聊聊memcached1.4的LRU算法

Memcached 是完全基于内存,而内存总会被用完的,如果在 set 操作的时候发现内存不足了,它会怎么办?它采用 Least Recently Used (LRU) 算法,理解 LRU 算法对于使用 memcached 非常关键。

从 memcached1.5 开始,为了进一步优化内存使用和提高性能,memcached 采取了新的 LRU 算法,我会分三篇文章说说新旧版本的 LRU 算法,今天描述 memcached1.4 以前版本的 LRU 算法的原理,相对简单一点。

在 memcached1.4 以前的版本中,如果一个 item 过期了,memcached 并不会主动回收内存空间;也没有异步的线程在后台回收。它的内存回收策略完全是同步的,对于一个 set 操作来说,如果 memcacheed 发现内存不够了,它会采用一种算法进行内存操作,从而为新的 item 腾出空间。

它采取的不是 FIFO 这种先进先出的内存淘汰算法,它采用的是更高级的内存淘汰算法,这就是 LRU,如果一个 item 长时间没有使用且已经过期了,会优先清空它们的内存空间,当然这个算法也不是那么智能,假设两个 item 的过期时间一样,在清理的时候,不会优先清理相对较大的 item。

甚至不同的 Slab-class 其 LRU 淘汰策略也是完全独立的,互不影响。

在 set 的时候,如果没有过期的 item 被淘汰,那怎么办?这个时候 memcached 只好根据 LRU 算法淘汰尚未过期的 item,这个操作也叫做 evict

memcached 本质上是缓存软件,如果你存储的数据不能丢失(非缓存),那需要好好进行内存容量规划,避免数据被 evict。想想看,假设 session 数据使用 memcached 存储,如果一个正常用户对应的 session 被 evict 了,那么这个用户就 logout 了,影响可大可小。

那么 memcached 内部是如何实现 LRU 算法的呢?我没有看源代码,完全通过 wiki 和官方博客学习,如果描述有问题或模棱两可,还请见谅。

在 memcached 中,每个 item 对象被创建的时候,它维护一个计数器,item 对象计数器的值就是 unix 当前时间戳,当一个 item 被 FETCHED 的时候(get、set、replace),这个计数器的值就会更新为当前时间(表示被使用了)。

如果 memcached 在遇到 set 操作的时候,发现内存不够,就会淘汰计数器值最小的 item(过期的优先淘汰),本质上就是这么简单:如果某个 item 没被使用就优先淘汰。

听上去是不是很简单?我们再稍微深入一点,每个 Slab-class 的 LRU 由一个双向链表维护,如下图:

当一个新 item 被 set 的时候,它会进入链表的 head,如果发生 evict,那么在链表 tail 尾的 item 会从内存中释放。

当 get 一个 item,它会从链表中 unlink,然后重新 link 到链表的 head,这个过程叫做 bump

由于 bump 会有锁(mutex locks and mutations),频繁发生对性能有非常大的影响,所以 memcached 做了一个优化,在 60 秒内同一个 item 只会产生一次 bump。

活跃的 item 即使没有频繁产生 bump,但如果 get 操作非常多,也会产生很多的锁竞争,导致某些 get 延时不一致,甚至导致 cpu 负载在某个时间过高,也就是多线程的扩展性受制于 memcached 的 LRU lock。什么意思呢?对于老的 URL 实现来说,memcached 开启的工作线程建议不要超过 8 个。

为了进一步提升 LRU 的效率和减少内存的使用,后续我会描述最新的 memcached LRU 算法。

再补充一点,一个 item 什么时候会释放内存呢?通常下面几个步骤会释放:

  • 主动 del 操作。
  • set 覆盖操作。
  • 一个过期 item 进行 get,add,replace 操作的时候。
  • evict 操作发生的时候,优先回收 tail 尾部过期的 item。

观察 evict 和内存回收情况对于评估 memcached 非常实用,可以通过 stats 和 stats items 命令了解详细的情况。相关参数解释如下:

1:reclaimed:表示有多少过过期的 item 被回收了。

2:evicted:查看有多少个 item 在过期前发生了 evict

3:evicted_nonzero:查看有多少个明确设置了过期时间的 item 在过期前。相对来说明确设置过期时间的 item 被 evict,那么可能会影响业务。

4:evicted_time:上一次运行 evict 到现在的时间。

5:expired_unfetched:查看有多少 item 被 set 后,从来没访问过,然后因为过期被回收的数量。

6:evicted_unfetched:查看有多少 item 被 set 后,从来没访问过,然后被 evict 的数量。

7:evicted_active:查看有多少 item 被 set 后,最近被访问过(但没来得及达到 LRU head),然后被 evict 的数量。

memcached 相关文章:


欢迎大家关注我的公众号(ID:yudadanwx,虞大胆的叽叽喳喳),所有文章都是原创,主要来源于平时工作中遇到的问题和学习中的一些想法。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容