1. 画图理解
启动 memcached 的时候,可查看到 page 和 chunk 的信息
- 命令:
./bin/memcached -m 64 -p 11211 -u root -vvv
2. 内存分配
- 启动 memcached 时,-m 指定内存大小,将信息保存到缓存中后才开始分配和保留物理内存。
- 通过 slab allocation 机制对内存进行管理。
- 最大内存默认 64,通过 -m 调整。
- 内存空间由 slab classes 构成,内存以 slab page 为单位去申请,分配到对应的 slab class。
- slab page:最大 1 兆,由 1 个或多个 chunk 组成。
- chunk:实际存储数据的单元。
3. memcached 缓存策略 - LRU
- 在 1.4.x 及更早版本中,memcached 中的 LRU 是标准的双向链表:有头部和尾部。将新物品插入头部,从尾部弹出驱逐物。如果访问某个项目,则将其从其位置取消链接,然后重新链接到头部(此处称为“碰撞”),返回到 LRU 的顶部。
- 下面这些情况,带有超时时间的记录会被删除
- 被认为删除。
- 被 set 覆盖。
- 被动删除:过期后,被 get、add 等命令访问。
- 主动清楚:LRU 机制。
问题点:碰撞几率过高,对同一个链表的修改导致大量的互斥锁争抢(修改节点位置的时候),导致 CPU 使用率高或者响应变慢。
4. memcached 缓存策略 - 分段LRU
- 每个 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
- LRU 爬虫是一个单独的后台线程。
- 专门用来处理失效的数据。
- 检查每个 slab class 中每个子 LRU 链表。