1. 画图理解


image.png

启动 memcached 的时候,可查看到 page 和 chunk 的信息

  • 命令:./bin/memcached -m 64 -p 11211 -u root -vvv

image.png

2. 内存分配


  • 启动 memcached 时,-m 指定内存大小,将信息保存到缓存中后才开始分配和保留物理内存。
  • 通过 slab allocation 机制对内存进行管理。

image.png

  • 最大内存默认 64,通过 -m 调整。
  • 内存空间由 slab classes 构成,内存以 slab page 为单位去申请,分配到对应的 slab class。
  • slab page:最大 1 兆,由 1 个或多个 chunk 组成。
  • chunk:实际存储数据的单元。

    3. memcached 缓存策略 - LRU


  • 在 1.4.x 及更早版本中,memcached 中的 LRU 是标准的双向链表:有头部和尾部。将新物品插入头部,从尾部弹出驱逐物。如果访问某个项目,则将其从其位置取消链接,然后重新链接到头部(此处称为“碰撞”),返回到 LRU 的顶部。

image.png

  • 下面这些情况,带有超时时间的记录会被删除
    • 被认为删除。
    • 被 set 覆盖。
    • 被动删除:过期后,被 get、add 等命令访问。
    • 主动清楚:LRU 机制。

问题点:碰撞几率过高,对同一个链表的修改导致大量的互斥锁争抢(修改节点位置的时候),导致 CPU 使用率高或者响应变慢。

4. memcached 缓存策略 - 分段LRU


image.png

  • 每个 slab-class 安排一个 LRU,每个 LRU 拆分为四个子 LRU 类型。
  • 每个存储的数据都有两个标志位:FETCHED、ACTIVE
    • FETCHED:该数据曾经被请求过。
    • ACTIVE:该数据有两次或以上被请求,当数据被移动时移除。
  • TEMP:该队列中的 item TTL 通常只有几秒,不会被挪动。具体时间可配置 stats settings temporary_ttl 选项。
  • HOT:试用队列,数据不会长久存在该链表,一旦数据到达队列的尾部,则开始移动。如果物品处于活动状态,他会被移动到 WARM,非活动状态,它会被移动到 COLD。
  • WARM:访问量不大的数据。如果物品处于活跃状态,它将被移动到 WARM 头部,非活跃状态,它将被移动到 COLD。
  • COLD:最不活跃的数据。回收时如果处于 ACTIVE 状态,则移动到 WARM,否则删除。

总结:碰撞率变小了,提高了性能。

5. memcached 缓存策略 - LRU Crawler


image.png

  • LRU 爬虫是一个单独的后台线程。
  • 专门用来处理失效的数据。
  • 检查每个 slab class 中每个子 LRU 链表。