Redis内存优化の内存淘汰策略

  公司服务由于实时计算跨度过大,前文说过需要用redis来进行状态管理,暂未发现一种数据修改但是不改变expire时间的做法,所以记录的数据全部未设置过期时间,计划通过脚本和一个大key来每天凌晨对redis前一天的状态数据进行清理,但是在24小时运行过程中,可能会出现数据量过大,导致内存消耗过大的问题,考虑到业务只需要记录top 100的记录,可以理解为top 100就是所谓的热点数据,而对于非热点数据在内存不足的时候是可以选择进行释放的,查阅了Redis内存淘汰策略,具体淘汰策略如下:

1> Redis 4.0以前

  1. noeviction: 不进行数据淘汰,当内存达到上限无法申请足够内存时直接进行报错。
  2. volatile-lru: 从设置了过期时间的所有key中挑选最近最少使用的数据进行淘汰。
  3. volatile-ttl: 对于设置了过期时间的key,按照过期时间进行筛选,挑选即将要过期的数据进行淘汰。
  4. volatile-random: 从设置了过期时间的数据中进行随机淘汰。
  5. allkeys-lru: 从所有的key(无论是否设置过期时间)中,挑选最近最少使用的进行淘汰。
  6. allkeys-random: 从所有key中随机进行淘汰。

2> Redis 4.0以后新增

  1. allkeys-lfu: 和lru不同,lru使用的是最近最少使用的进行淘汰,但是有可能会导致某天某个时间段内不活跃(不活跃跨度超过清理间隔),从而可能导致某条其实整天来说数据量很大的数据,但是由于某个时间段内没有数据访问而导致之前的记录被清除,这样对结果影响会很不好,所以4.0以后加入的这个LFU就很好的弥补了这类需求,LFU可以理解为每条记录的访问频率,当然这个访问频率是随时间有关的,如果数据不变,随着时间递增这个频率值会递减,从而如果某个时间段内某条数据量访问极其频繁,而中途有段时间没有数据访问,但是它的访问频率其实还是很高的,所以即便在某个清理周期内没有任何访问记录,但是它也不一定会被清理,这样就很好的保障了top 100类业务的实现。
  2. volatile-lfu: 基于设置了过期时间的key使用LFU算法进行淘汰。

  这里对于top 100而言,这里可以理解为就是长期活跃的数据,而对于非top 100的数据基本属于所谓的最不常使用的数据,所以这里选择使用allkeys-lfu策略进行数据清理。设置方法如下:

redis-cli config set maxmemory-policy allkeys-lfu

  当然这里需要注意的一点是,以上所谓的LRU其实不是严格意义上的LRU算法实现,出于算法内存消耗的角度考量在选择淘汰样本时,不是将所有数据一次性进行筛选排序找到最优的淘汰样本,而是每次在整体数据集中进行小部分采样(采样个数控制参数:maxmemory-samples),然后在这个局部样本内部通过LRU选出需要淘汰的样本,然后如此循环采样来进行数据淘汰。所以和真正的LRU还是有些许区别的,但是到了3.0版本以后,Redis内部会维护一个淘汰样本池,即可以理解为会先挑选出一部分使用较少的数据组成一个样本池,然后在这个样本池中使用LRU进行样本淘汰,这样可以更好的提高样本淘汰的准确性。

补充点:

  关于LFU的两个参数lfu-log-factor个人理解为counter数值中每个1值涵盖的访问频率的范围大小,即lfu-log-factor越大说明counter每增加1的大小对应需要的频率越高,即counter中1的涵盖的频率密度相对较低(区间较低),例如lfu-log-factor=0时,counter每增加1值需要数据点击率新增10次;而lfu-log-factor=10时,counter每增加1值需要数据点击率新增1000次,所以lfu-log-factor=0,counter=10时,counter=10代表的点击频率为[n,n+10],而lfu-log-factor=0,counter=10时,counter=10代表的点击频率为[n,n+1000],所以这个lfu-log-factor就是权衡频率密度和所涵盖最大频率范围的一个控制参数,如果业务数据频率不高但是对密度范围有较高敏感度,例如要求能区分频率10次和20次的区别,那么就需要把lfu-log-factor设置的低一些,这样才能使得10次和20次的频率数据的counter值不一样,不然如果lfu-log-factor设置过大,10次和20次的两条数据最终得到的counter值其实就是一样的,无法对其进行区分;当然如果频率范围较大,例如最高频率达到了100M次,如果想支持0-100M次的频率范围,那么就需要调大lfu-log-factor参数,否则lfu-log-factor如果过小时会导致1M次的频率的记录和100M次的记录最终的counter值是一样的。当然,通常情况下,采用系统默认的lfu-log-factor=10值就能够满足大部分我们的需求了。

延伸知识点のLFU获取热点key

  依据LFU算法,每次在对key进行读写访问时,会更新24 bits域代表的访问时间和counter,所以通过counter代表的访问频率 就可以知道哪些key是热点key了,redis本身就提供了对应的访问方法:

./redis-cli --hotkeys
# Scanning the entire keyspace to find hot keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).

[00.00%] Hot key '394cee9e41b3639e2b474e20625f6824f9575ad5_status' found so far with counter 5
[00.01%] Hot key '9f93b1c5694c5ebf880a12f56970d96997c562a4' found so far with counter 7
[00.01%] Hot key '5365aa52d43d3c53a023bc8bfdf2f1fa8f4c3abb' found so far with counter 5
[00.01%] Hot key '522e2c1fe2320956a02223bc9decac32c55942e9_status' found so far with counter 5
[00.01%] Hot key '9f00824926d424d1fc9cf7b492927b6e0087fa8c_status' found so far with counter 5
...
[04.51%] Hot key 'd7fb6b1a965a32b507dd9deeb46aca9dda1fe09e' found so far with counter 9
[05.21%] Hot key '2b99cb7c2eab96a9051ef4b4b717fc91f4f10ef1' found so far with counter 9
[10.49%] Hot key 'd8ae3b65d53539011563ddb53be307550b9761db' found so far with counter 9
[11.09%] Hot key 'c81ebe273b1bf947579bcae3034929442e512b57' found so far with counter 9
[31.41%] Hot key 'openfreetystvip.migu.cn4_' found so far with counter 14
[46.57%] Hot key 'cache.ott.ystenvod.itv.cmvideo.cn4_' found so far with counter 14
[49.35%] Hot key 'live.hcs.cmvideo.cn4_' found so far with counter 17
[62.08%] Hot key '3dbbe9a97c499839a3c2c7a21343a694b1324870' found so far with counter 10
[65.15%] Hot key '0d6199ba69f89f91cc6a19a7e7473ac79e28e34e' found so far with counter 10
[67.50%] Hot key 'all_join_url_domains' found so far with counter 255
[69.84%] Hot key 'wlanwm.12530.com4_' found so far with counter 10
[73.89%] Hot key 'freevod.nf.migu.cn4_' found so far with counter 14
[97.20%] Hot key 'ggv.cmvideo.cn4_' found so far with counter 18

-------- summary -------

Sampled 147878 keys in the keyspace!
hot key found with counter: 255 keyname: all_join_url_domains
hot key found with counter: 18  keyname: ggv.cmvideo.cn4_
hot key found with counter: 17  keyname: live.hcs.cmvideo.cn4_
hot key found with counter: 14  keyname: openfreetystvip.migu.cn4_
hot key found with counter: 14  keyname: cache.ott.ystenvod.itv.cmvideo.cn4_
hot key found with counter: 14  keyname: freevod.nf.migu.cn4_
hot key found with counter: 10  keyname: 3dbbe9a97c499839a3c2c7a21343a694b1324870
hot key found with counter: 10  keyname: 0d6199ba69f89f91cc6a19a7e7473ac79e28e34e
hot key found with counter: 10  keyname: wlanwm.12530.com4_
hot key found with counter: 9   keyname: 3cc24eceaaa143a8f8e264159226cd5f8b47504e
hot key found with counter: 9   keyname: a83149516404bb5a3357703bdb852d294fe2b177
hot key found with counter: 9   keyname: 14e41d6c72a0bc696c8a1d71b7f01b6e33e4e593
hot key found with counter: 9   keyname: 9cb88cee017fe11826a7745aaf1c26e8cac65047
hot key found with counter: 9   keyname: b1d0ae060c0c1041b1463835bf356ec7473d3b0f
hot key found with counter: 9   keyname: 92ef5bf31db3c5f4b61339aa8b0d8cd3dbc491ec

  当然要提前把内存数据清理机制设置为allkeys-lfu或是volatile-lfu,因为只有基于lfu才能这样获取到对应key的访问频率。

参考:

https://redis.io/topics/lru-cache

https://yq.aliyun.com/articles/278922

https://yq.aliyun.com/articles/257459?spm=a2c4e.11153940.blogcont278922.8.5b914914Pnf5A5

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值