Kaito
2020-10-19
使用了 LFU 策略后,缓存还会被污染吗? 我觉得还是有被污染的可能性,被污染的概率取决于LFU的配置,也就是lfu-log-factor和lfu-decay-time参数。 1、根据LRU counter计数规则可以得出,counter递增的概率取决于2个因素: a) counter值越大,递增概率越低 b) lfu-log-factor设置越大,递增概率越低 所以当访问次数counter越来越大时,或者lfu-log-factor参数配置过大时,counter递增的概率都会越来越低,这种情况下可能会导致一些key虽然访问次数较高,但是counter值却递增困难,进而导致这些访问频次较高的key却优先被淘汰掉了。 另外由于counter在递增时,有随机数比较的逻辑,这也会存在一定概率导致访问频次低的key的counter反而大于访问频次高的key的counter情况出现。 2、如果lfu-decay-time配置过大,则counter衰减会变慢,也会导致数据淘汰发生推迟的情况。 3、另外,由于LRU的ldt字段只采用了16位存储,其精度是分钟级别的,在counter衰减时可能会产生同一分钟内,后访问的key比先访问的key的counter值优先衰减,进而先被淘汰掉的情况。 可见,Redis实现的LFU策略,也是近似的LFU算法。Redis在实现时,权衡了内存使用、性能开销、LFU的正确性,通过复用并拆分lru字段的方式,配合算法策略来实现近似的结果,虽然会有一定概率的偏差,但在内存数据库这种场景下,已经做得足够好了。
展开
共 20 条评论
215
甜宝仙女的专属饲养员
2020-10-19
又刷新了对lru和lfu的认知,这种突然打开知识盲区的天窗的感觉就如同一盆冷水,把我从地铁上这种迷迷糊糊的状态给满血复活
共 2 条评论
25
test
2020-10-19
1.选候选集:volatile前缀的是设置了过期时间的key,all前缀的是全部key; 2.算法:lru是最近最少使用,lfu是最近最不频繁使用,ttl是距离到期时间长短,ramdon是随机; 2.1 lru是自带了访问时间 2.2 lfu是带了访问次数,但是因为只有八位保存所以不是每访问一次就+1,而是每次原来访问次数乘以lfu_log_factor,加一再倒数,看是否大于随机值,大于则+1:double r = (double)rand()/RAND_MAX;double p = 1.0/(baseval*server.lfu_log_factor+1);if (r < p) counter++; 还有衰减机制,由lfu_decay_time控制,已过去n个lfu_decay_time,则将idle time加n。 3.淘汰规则:每次sample n个key,比如10个,放到pool里面,淘汰idle时间最长的key。再次淘汰的时候,继续抽样10个key,只把小于原pool中某个idle时间的key插入进去,即如果抽样出来的key比pool中所有key的idle时间都小,则不插入。然后淘汰pool中idle小的,保持pool在10个;
展开
14
xueyuan
2020-11-03
这篇文章就学到了很多,lfu的设计理念很有参考学习的意义。
11
yeek
2020-10-19
偏极端情况下,数据短期内被高频访问,且计数器达到了很大值,且计数器的衰减设置的很大,导致衰减很慢,此时该数据就可能在缓存中长期驻留。 从长期来看,我觉得应该是避免频繁执行数据淘汰,否则会影响redis的效率,较好的做法应该是监控redis服务器的内存情况,以及相应的报警机制,定期统计redis中的key分布情况,交由使用方check数据合理性,以检验程序中对redis数据设置的过期时间,访问失效等是否合理。
4
写点啥呢
2020-10-19
关于计数衰减想请问老师,它发生的时机是在缓存被访问到还是Redis会定时刷新所有缓存计数进行衰减呢?对这两种衰减时机感觉都有不足,再次访问时候衰减能维持较低的性能损耗但是对于短期热点数据如果不会被访问那么计数就不准确还会导致污染问题。如果是全量定时刷新那么又会带来很多性能损耗。
共 2 条评论
3
escray
2021-03-30
有缓存过期时间和缓存淘汰机制,为什么还会出现缓存污染? 这一讲算是补上了之前留下来的一个坑——前面讲过了 LRU 算法,但是对于 LFU 一直留到这里才讲。我之前望文生义的以为 LFU,就是按照访问频次来淘汰,但是没有考虑到如果次数相同,那么还是要看访问时间;另外就是巧妙的拆分了 RedisObject 里面的 lru 字段,用 ldt 和 counter 来实现算法。 能看懂计数器规则的公式,但是不理解为什么要这么计算。还有那个 衰减因子配置项 lfu_decay_time 的相关计算也比较有意思,但是不知所以然,此处必有蹊跷。 之前看 LRU 和 LFU 比较多,忽略了 volatile-ttl 策略,这次正好补上了。 使用了 LFU 策略之后,应该还是会有缓存污染的情况,但是被污染的比例,或者说造成的影响应该小很多。假设 Redis 每次收到的请求都是全量扫描或接近于,那么 LFU 是不是就会失效,或者说缓存污染就会比较严重?
2
bigben
2021-07-07
未达到触发淘汰机制的阈值之前,会被污染的;淘汰时也不是所有被污染key被淘汰,所以也还是被污染的;
1
而立斋
2021-04-17
这才是美妙的设计!!!那个随机数的作用也是神奇,能够有限的减缓计数器增长的速度,而且是数越大,越稳定
1
zenk
2020-11-30
缓存污染还有一个实时性问题吧 越小的时间范围内准确识别的难度越大,有时业务方都无法确保数据的时效性,更别说缺少业务信息的Redis 所以,不管什么策略,都无法避免绝对的没有污染
1