日期:2014-05-17  浏览次数:20632 次

memcache如何定期删除不常用的数据
如题,如何防止memcache里的数据无限制增长,如何实现定期删除长时间不用或使用频率低的数据。在线等!

------解决方案--------------------
我就知道memcache可以像session或cookie那样设个过期时间
------解决方案--------------------
定制规则;有能力可以修改memcache实现
------解决方案--------------------
memcache是在slab内存池的基础上, 每个slab内维护LRU链表, 每个NODE具有生命期, 所有Cache的NODE组成Hash表。

memcache采用懒惰删除机制, 其内存请求步骤大致是这样一个请求链: 根据node的size定位到slab ---> 从该slab的LRU尾部向前寻找过期且reference==1的NODE, 如果找到, 则从hash表与LRU中unlink此NODE, 并将此NODE插入到LRU头部并且reference置1, 将输入存入node尾部, 重新插入到哈希表中. 如果没找到, 那么会直接向slab申请新的内存来存储NODE, 这也就是内存池的功能了, 如果申请失败, 那么接下来的策略是重新扫描LRU, 找出那些虽然没有过期, 但reference==1的NODE, 直接回收使用, 这是不得已的策略. 如果这个策略都失败了, 我印象中还有一个策略, 是对于那些生命期已经失效3天并且当前refercence != 1的结点强制回收, 我记得注释里说那是一个小BUG, 这样处理是OK的, 大概意思是:somewhere refer to this node, becuase nowhere refers to it, 不知道这个BUG发生在哪里,我当初是没研究出来, 因为get/remove都是配对出现在memcache的各个函数里的, 真不知道引用计数怎么会失效3天还不为0.

所以,你看懂了没... 也就是尽可能的把内存分配向外推, 程序一开始就分配了很大的malloc内存充当内存池由slab管理, 而内存的重用是由LRU链表完成的, 不是一个线程定期扫描, 而是有需求才检测的方法, 达到了异步的效果.
------解决方案--------------------
探讨
memcache是在slab内存池的基础上, 每个slab内维护LRU链表, 每个NODE具有生命期, 所有Cache的NODE组成Hash表。

memcache采用懒惰删除机制, 其内存请求步骤大致是这样一个请求链: 根据node的size定位到slab ---> 从该slab的LRU尾部向前寻找过期且reference==1的NODE, 如果找到, 则从hash表与LRU中unlink此……

------解决方案--------------------
LS已经解释的很详细了...

一句话总结的话....
你只要在启动memcached的时候,用-m参数设定memcached所能占用的最大内存数,剩下的事情都是memcached自己搞定了,不需要你操心,它会把最没用的数据自己扔掉
------解决方案--------------------
定期flush
------解决方案--------------------
记得java是有memcache的flush方法,php应该会有的
至于定期的事情,你可以在一个php文件中写入flush,在linux中crontab 定时请求,例如
*/10 */23 * * * wget -q --spider http://www.xxxx.com/statbyday/stat1.php > /dev/null 2>&1