LRU实现太复杂,一般用LFU近似。
LFU的关键是统计访问频次。
可以看参考资料: https://redis.io/topics/lru-cache
里面提到为了节省空间,用8位来统计1000次访问或更多。
直接存肯定不行,因为8位=>256,最多存256次。
所以8位肯定只能存分级,256个等级。
比如1000次hit才增加一次等级。
那么怎么知道有1000次hit了呢?
可以用概率算法,rand()一个数,如果小于1/1000,则加1。
类似的概率算法还有:count min sketch
算法,用一大堆布隆过滤器记录每个key的访问频次,
由于肯定会有碰撞,因此这个估计值是虚高的。
取的时候,从这些布隆里取一个最小的频次作为估计值即可。
主要思想如此,类似的还有HyperLogLog
,但是实际代码有很多边界修正。
比如谷歌的HLL++算法,保证平均、最坏情况下的精度损失不会太大。