尽管memcached使用的场景非常多,解决了不少性能问题,但是如果用的不当,会造成意想不到的问题。
不同slab之间不能LRU就是一个不小的坑。
比如前一版本存的都是1000字节,内存使用已达上限;
现在升级版本,不重启memcached,变成500字节,就会出现缓存异常。
下面的测试,先用1000、4000字节的内容塞满memcached,超时时间180秒,
然后继续用500字节的写入12万次,记住最前面的10000个key,
Put完后,获取这10000个key,就出现无法读取的现象了。
有几个结论:
1、 memcached按value的长度将内存分成不同的slab;
2、 内存达到上限,put时,相同slab中,会释放最老的数据,不同slab之间不会超时释放,即使内存不足了;
3、 Memcache不会主动释放已占用的内存,不管是否超时,只有在get时,才会超时删除。
听说twiter的twemcache 可以自动调整,测试后发现,当出现上述情况时,有约20%-50%的错误率,并且会持续失败。
如果使用memcached1.4.21的 -o slab_reassign,slab_automove可以解决部分问题,
但是当发生上述问题时,有一个很长的切换时间,切换时会有80%以上的错误率。
stats slabs
STAT 9:chunk_size 600 -- 500字节的占用情况,已经申请不到更多内存了,老的1000、4000的也不释放
STAT9:chunks_per_page 1747
STAT 9:total_pages 11
STAT 9:total_chunks19217
STAT 9:used_chunks19217
STAT 9:free_chunks 0
STAT9:free_chunks_end 0
STAT 9:mem_requested11318813
STAT 9:get_hits 0
STAT 9:cmd_set 240000
STAT 9:delete_hits 0
STAT 9:incr_hits 0
STAT 9:decr_hits 0
STAT 9:cas_hits 0
STAT 9:cas_badval 0
STAT 9:touch_hits 0
STAT 12:chunk_size1184 --- 1000字节的占用情况
STAT12:chunks_per_page 885
STAT 12:total_pages786
STAT 12:total_chunks695610
STAT 12:used_chunks694875
STAT 12:free_chunks735
STAT12:free_chunks_end 0
STAT 12:mem_requested757413750
STAT 12:get_hits39647
STAT 12:cmd_set695228
STAT 12:delete_hits 0
STAT 12:incr_hits 0
STAT 12:decr_hits 0
STAT 12:cas_hits 0
STAT 12:cas_badval 0
STAT 12:touch_hits 0
STAT 18:chunk_size4544 ---- 4000字节的占用情况
STAT18:chunks_per_page 230
STAT 18:total_pages228
STAT 18:total_chunks52440
STAT 18:used_chunks52400
STAT 18:free_chunks40
STAT18:free_chunks_end 0
STAT 18:mem_requested214316000
STAT 18:get_hits 0
STAT 18:cmd_set104291
STAT 18:delete_hits 0
STAT 18:incr_hits 0
STAT 18:decr_hits 0
STAT 18:cas_hits 0
STAT 18:cas_badval 0
STAT 18:touch_hits 0
STAT active_slabs 3
STAT total_malloced1073419800
END