redis的过期策略和内存淘汰

之前经常将将 Redis 的过期策略和内存淘汰策略搞混淆,查阅了一些资料后做个总结。

过期策略

Redis 所有的 key 都可以设置过期时间,时间一到就回自动删除。

如何设置过期时间

常用的方式有:

  • EXPIRE key seconds
  • EXPIREAT key timestamp

字符串独有的方式:

  • SET key value [expiration EX seconds|PX milliseconds][nx|xx]
  • SETEX key seconds value

Redis 采用的过期策略

  • 惰性删除

    • 在进行 get 或 setnx 等操作时,先检查 key 是否过期,
    • 若过期,删除 key,然后执行相应操作;
    • 若没过期,直接执行相应操作
  • 定期删除
    依次遍历每个数据库,默认每秒进行十次过期扫描

    1. 检查当前库中的随机 20 个 key
    2. 删除这 20 个 key 中已经过期的 key;
    3. 如果过期的 key 比率超过 1/4,那就重复步骤 1

    为了保证过期扫描不会出现循环过度,导致线程卡死现象,会判断定期删除操作是否已经达到指定时长(默认不会超过 25ms),若已经达到,直接退出定期删除。

如果某一个时间段,缓存集中过期失效,对于数据库而言,就会产生周期性的压力波峰造成缓存雪崩。如果有大批量的 key 过期,要给过期时间设置一个随机范围,而不宜全部在同一时间过期,分散过期处理的压力。

内存淘汰机制

用于缓存的内存不足时,Redis 提供了几种可选策略 (maxmemory-policy) 来让用户自己决定该如 大专栏  redis的过期策略和内存淘汰何腾出新的空间以继续提供读写服务。

  • noeviction 不会继续服务写请求 (DEL 请求可以继续服务),读请求可以继续进行。这样可以保证不会丢失数据,但是会让线上的业务不能持续进行。这是默认的淘汰策略。

  • volatile-lru 尝试淘汰设置了过期时间的 key,最少使用的 key 优先被淘汰。没有设置过期时间的 key 不会被淘汰,这样可以保证需要持久化的数据不会突然丢失。

    扫描二维码关注公众号,回复: 9508256 查看本文章
  • volatile-ttl 跟上面一样,除了淘汰的策略不是 LRU,而是 key 的剩余寿命 ttl 的值,ttl 越小越优先被淘汰。

  • volatile-random 跟上面一样,不过淘汰的 key 是过期 key 集合中随机的 key。

  • allkeys-lru 区别于 volatile-lru,这个策略要淘汰的 key 对象是全体的 key 集合,而不只是过期的 key 集合。这意味着没有设置过期时间的 key 也会被淘汰。

  • allkeys-random 跟上面一样,不过淘汰的策略是随机的 key。

如果你只是拿 Redis 做缓存,那应该使用 allkeys-xxx,客户端写缓存时不必携带过期时间。
如果你还想同时使用 Redis 的持久化功能,那就使用 volatile-xxx 策略,这样可以保留没有设置过期时间的 key,它们是永久的 key 不会被 LRU 算法淘汰。

小结

Redis 采用惰性删除定期删除,处理过期的缓存数据。
Redis 的内存淘汰策略的选取并不会影响过期的 key 的处理,用于处理内存不足时的需要申请额外空间的数据。

参考文档

Expires
Redis as an LRU cache

猜你喜欢

转载自www.cnblogs.com/lijianming180/p/12389553.html