Redis 内存淘汰与过期策略
引言Redis 作为内存数据库内存资源有限必须妥善处理内存占用问题。本文梳理两种核心机制淘汰策略决定内存达到上限时如何移除数据涵盖 noeviction、LRU、LFU 等多种算法及其实现细节过期策略惰性删除 定期删除负责及时清理已过期的键并说明如何避免读到过期数据。掌握这些机制有助于合理配置 Redis 实例平衡内存效率与数据可用性。Redis淘汰策略当 Redis 的内存使用量达到配置maxmemory的上限时如何决定哪些数据应该被删除以释放内存。淘汰策略是在全局范围内应用的它适用于 Redis 实例中的所有键。noeviction一旦缓存被写满了再有写请求来时Redis 不再提供服务而是直接返回错误。volatile-ttl会针对设置了过期时间的键值对根据过期时间的先后进行删除越早过期的越先被删除。volatile-random在设置了过期时间的键值对中进行随机删除。volatile-lru会使用 LRU 算法筛选设置了过期时间的键值对默认策略。volatile-lfu会使用 LFU 算法选择设置了过期时间的键值对。allkeys-random从所有键值对中随机选择并删除数据。allkeys-lru使用 LRU 算法在所有数据中进行筛选。allkeys-lfu使用 LFU 算法在所有数据中进行筛选。LRU算法实现最近最少使用算法。比较访问时间淘汰最近一次访问时间小的数据。Redis的LRU实现RedisObject的lru字段记录数据最近一次访问时间。第一次淘汰数据时根据配置maxmemory-samples选择出来N个数据作为候选集合把lru字段值最小的数据淘汰。再次淘汰数据时能进入候选集合的数据的 lru 字段值必须小于候选集合中最小的 lru 值当候选数据集中的数据个数达到了配置值时把候选数据集中 lru 字段值最小的数据淘汰出去。LFU算法实现最不经常使用算法。先比较访问次数再比较访问时间。相对LRU可以减少全表扫描造成的缓存污染需要淘汰的数据无法被淘汰。淘汰时先根据数据 lru 字段的后 8bit 选择访问次数最少的数据进行淘汰。当访问次数相同时再根据 lru 字段的前 16bit 值大小选择访问时间最久远的数据进行淘汰。Redis的LFU实现RedisObject中lru字段拆成两部分第一部分前16bit 存储访问时间第二部分后8bit最大255 存储访问次数。当前的访问次数 * lfu_log_factor建议设置为10 1再取倒数将此数值与01随机数比较如果大于随机数则访问次数加1。衰减策略如果lfu_decay_time为1N分钟内没有被访问访问次数 - N如果lfu_decay_time为2N分钟内没有被访问访问次数 - N/2。第一次淘汰数据时根据配置maxmemory-samples选择出来N个数据作为候选集合把lru字段值最小的数据淘汰。再次淘汰数据时能进入候选集合的数据的 lru 字段值必须小于候选集合中最小的 lru 值当候选数据集中的数据个数达到了配置值时把候选数据集中 lru 字段值最小的数据淘汰出去。Redis过期策略当Redis中的键在设定的过期时间到达后如何自动删除。惰性删除当一个数据的过期时间到了以后并不会立即删除数据而是等到再有请求来读写这个数据时对数据进行检查如果发现数据已经过期了再删除这个数据。定期删除Redis 每隔一段时间默认 100ms就会随机选出一定数量的数据检查它们是否过期并把其中过期的数据删除这样就可以及时释放一些内存。主动淘汰删除通过淘汰策略内存达到 maxmemory 限制时根据淘汰策略进行删除。如何避免读到过期数据Redis 3.2 之前的版本从库在服务读请求时并不会判断数据是否过期而是会返回过期数据。在 3.2 版本后Redis 做了改进如果读取的数据已经过期了从库虽然不会删除但是会返回空值这就避免了客户端读到过期数据。使用EXPIRE设置key存活时间为多少秒 和 PEXPIRE设置key存活时间为多少毫秒命令设置过期时间时主从库之间的同步延迟会导致主从库的过期时间不一样通过从库读取时会读到过期数据。建议使用EXPIREAT和PEXPIREAT命令指定过期时间。感谢您的阅读如果文章中有任何问题或不足之处欢迎及时指出您的反馈将帮助我不断改进与完善。期待与您共同探讨技术共同进步
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2480257.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!