当前位置:首页 > 问答 > 正文

Redis淘汰策略怎么调才更顺手性能好,实际用起来那些设置真管用

想让Redis用起来顺手又性能好,关键在于理解它的“内存淘汰策略”并正确设置,你可以把Redis的内存想象成一个仓库,数据就是仓库里的货物,仓库容量有限,当新货物要进来但空间不足时,你就得决定把哪些旧货物扔出去,这个“扔东西的规则”就是淘汰策略,调得好,仓库周转高效,常用物品随手就能拿到;调不好,要么仓库早早塞满瘫痪,要么找个东西得翻半天。

你得知道有哪些策略可选。

Redis提供了8种主要的策略(来源:Redis官方文档),但不用被数字吓到,它们可以归为几类,我们挑最常用、最管用的来说:

  1. 不淘汰(noeviction):这是默认策略,当内存不够时,新写入的操作会直接报错,所有读取和删除操作正常,这适合你非常确定数据量绝不会超过内存,或者你宁愿让系统报错也不愿丢失任何数据的场景,但对大多数需要持续服务的应用来说,这不太“顺手”,因为会让服务中断。

  2. “全体随机”淘汰(allkeys-lru / allkeys-random)

    • allkeys-lru:从所有key中,淘汰最近最少使用的那个,LRU是“最近最少使用”的缩写,它认为,最近没怎么被访问的数据,以后用到的可能性也小,优先淘汰它们。这是最常用、最泛用、效果通常也最好的策略之一。
    • allkeys-random:从所有key中,随机挑一个淘汰,这个策略简单粗暴,开销小,但很可能把热点数据(经常被访问的)给误删了,导致缓存命中率下降,除非你的数据访问模式完全是随机的,否则不推荐作为首选。
  3. “有过期时间”的淘汰(volatile-lru / volatile-ttl / volatile-random)

    • 这类策略只针对那些设置了过期时间(TTL)的key进行淘汰,没设置过期时间的key会被永久保留(直到内存爆掉,如果同时用了noeviction就可能报错)。
    • volatile-lru:从设了过期时间的key中,淘汰最近最少使用的。
    • volatile-ttl:从设了过期时间的key中,淘汰剩余寿命最短的(TTL最小的),这个策略很直观,快过期的先扔。
    • volatile-random:从设了过期时间的key中,随机淘汰一个。

实际用起来,哪些设置真管用?怎么调才顺手?

第一招:首选 allkeys-lru,把它作为你的“默认备选”

Redis淘汰策略怎么调才更顺手性能好,实际用起来那些设置真管用

如果你不确定该用哪个,或者你的业务数据访问有热点(比如某些商品、新闻被频繁查看),allkeys-lru 十有八九是你的最佳选择,它能自动把冷数据清理掉,把宝贵的内存空间留给热数据,从而保证较高的缓存命中率,比如一个电商网站,新上架的商品和热门促销商品会被频繁访问,而三个月前的旧商品页面几乎没人看,allkeys-lru 就会自动把旧商品信息淘汰掉。

怎么设置? 在Redis的配置文件 redis.conf 里找到这一行: # maxmemory-policy noeviction 把开头的 注释去掉,并把 noeviction 改成 allkeys-lrumaxmemory-policy allkeys-lru 然后重启Redis或者通过命令重载配置。

第二招:明确区分缓存和数据字典,用对策略

这是让Redis性能好的一个关键心法,你要想清楚,存在Redis里的数据,哪些是纯粹的“缓存”(丢了可以从数据库再查),哪些是充当“持久数据字典”的(丢了就真没了)。

  • 对于纯缓存场景:比如用来缓存数据库查询结果、会话(Session)等,这些数据丢了没关系,可以从源数据恢复,这时,强烈建议使用 allkeys-lru,因为你希望内存尽可能多地容纳热点缓存,所有key都应该参与淘汰。
  • 对于数据字典场景:比如你用来存储用户基础信息、城市列表等很少变化但查询极频繁的数据,这些数据你希望永远留在内存里,不能因为内存不足被淘汰,这时,你应该不给这些key设置过期时间,然后选择 volatile-lruvolatile-ttl 策略,确保你的总内存大小足够容纳这些“永久数据”加上其他缓存数据,这样,Redis只会淘汰那些设置了过期时间的缓存key,而你的重要数据字典安然无恙。

第三招:利用 volatile-ttl 处理有时效性的数据

Redis淘汰策略怎么调才更顺手性能好,实际用起来那些设置真管用

如果你的缓存数据有非常明确的生命周期,并且过期后必须及时清理,volatile-ttl 就特别管用,比如限时优惠券、手机验证码、临时授权令牌等,这些数据不仅希望到期自动删除,在内存紧张时,也希望能优先清理那些马上就要过期的,给还有更长时间才过期的数据留出空间。volatile-ttl 策略正好满足这个需求。

第四招:核心是设置好 maxmemory,否则策略白费

无论你选了多牛的策略,都必须设置 maxmemory 这个参数,它决定了Redis内存使用的“天花板”,如果你不设置,Redis会一直吃内存,直到被操作系统强制杀死,那所有策略都成了空谈。

怎么设置?redis.conf 中,根据你的服务器内存来定,要留出余量给操作系统和其他进程,比如你的服务器有4G内存,可以设置: maxmemory 3gb 这样当Redis内存使用达到3GB时,淘汰策略就开始工作了。

最后的小贴士:

  • 监控是关键:用了淘汰策略后,一定要监控evicted_keys这个指标(通过info stats命令查看),如果这个数字持续快速增长,说明你的内存压力很大,淘汰很频繁,可能需要考虑扩容内存,或者检查业务代码是否有内存泄漏(比如忘了设置过期时间)。
  • 避免频繁淘汰:理想状态是淘汰平稳发生,而不是瞬间爆发,频繁淘汰意味着缓存命中率低,性能会受损。
  • 混合使用:在复杂业务中,你可以通过给不同key设置或不设置TTL,结合 volatile-xxx 策略,实现更精细的内存控制。

调顺手的核心就是:理解业务数据特性 -> 选对策略(无脑选allkeys-lru通常不会错)-> 设好内存上限 -> 做好监控,没有一成不变的银弹,最好的设置是贴合你实际业务场景的设置。