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

Redis旧缓存怎么自动清理,性能和体验能不能更顺畅点?

关于Redis旧缓存自动清理以及如何让性能和体验更顺畅,这确实是使用Redis时一个非常核心且实际的问题,我们不需要太复杂的理论,就直接说怎么干和为什么这么干。

Redis旧缓存是如何自动清理的?

Redis本身就像一个内存里的临时仓库,空间总是有限的,当新东西要进来,但仓库又满了的时候,就得扔掉一些旧东西腾地方,这个“扔东西”的策略,就是Redis的内存淘汰策略,你可以在Redis的配置文件(redis.conf)里用 maxmemory-policy 这个指令来设定它。

这些策略主要分两大类:

  1. 针对设置了过期时间的键(key):

    • volatile-lru:从那些设置了过期时间的键中,挑最近最少使用的(最久没被碰过的)淘汰,这是最常用的策略之一。
    • volatile-ttl:从那些设置了过期时间的键中,挑剩余寿命最短的(马上要过期的)淘汰。
    • volatile-random:从设置了过期时间的键中,随机挑一个淘汰。
    • volatile-lfu:从设置了过期时间的键中,挑最不经常使用的(访问频率最低的)淘汰。(这个是从Redis 4.0版本开始有的)
  2. 针对所有键(不管有没有设过期时间):

    • allkeys-lru:从所有键中,挑最近最少使用的淘汰,如果你的应用有些关键数据是永久有效的,用这个要小心。
    • allkeys-random:从所有键中,随机挑一个淘汰。
    • allkeys-lfu:从所有键中,挑最不经常使用的淘汰。(Redis 4.0+)
    • noeviction不淘汰任何键,当内存不够时,新写入的操作会报错,这适用于你绝对不允许丢失任何数据的场景,但通常生产环境不会这么设。

怎么选? 根据Antirez(Redis创始人)在博客和讨论中的建议,以及社区的普遍实践(信息来源:Redis官方文档及社区最佳实践讨论):

  • 如果你的应用里,大部分数据都设置了合理的过期时间,那么用 volatile-lru 通常是个安全又高效的选择。
  • 如果你无法准确预测哪些数据应该永久保存,希望系统自己能智能管理,allkeys-lru 更省心。
  • volatile-ttl 在你希望缓存能像定时刷新一样工作时比较有用。
  • 强烈不建议使用 noeviction,除非你知道后果。

自动清理的核心就是为你Redis实例设置一个合适的内存上限(maxmemory),并配置一个符合你业务逻辑的淘汰策略。

Redis旧缓存怎么自动清理,性能和体验能不能更顺畅点?

怎么让性能和体验更顺畅点?

光有自动清理还不够,目标是既快又稳,用户体验好,以下几点很关键:

  1. 给缓存设置一个合理的过期时间(TTL),并且尽量分散开。 这是最重要的一条,不要把所有缓存的过期时间都设成一样的,比如都设1小时,想象一下,每小时整点,大量缓存同时失效,这时所有请求都直接打到后端数据库上,数据库瞬间压力巨大,可能导致服务卡顿甚至崩溃,这就是“缓存雪崩”。 怎么办? 在设置过期时间时,加一个随机数,基础过期时间是1小时,那么实际TTL可以设为 3600 + random(0, 300) 秒,这样过期时间就分散在1小时到1小时5分钟之间,压力就平摊开了。(信息来源:广泛存在于各类技术博客和架构经验分享,如大型互联网公司的技术实践总结)

  2. 避免使用耗时长的命令,特别是KEYS命令。 KEYS * 这个命令会遍历整个Redis的所有键,如果键非常多,这个命令会直接阻塞住Redis,导致其他所有请求都卡住,体验极差。 怎么办? 如果你需要查找键,使用 SCAN 命令来代替。SCAN 是分批次的、非阻塞的,虽然慢一点,但不会影响正常服务。

    Redis旧缓存怎么自动清理,性能和体验能不能更顺畅点?

  3. 利用Redis的持久化机制保证数据安全,但要平衡性能。 Redis可以把内存数据写到硬盘上(持久化),防止重启后数据全丢,主要有两种方式:

    • RDB:在特定时间点给内存拍个快照,恢复数据快,但可能会丢失最后一次快照之后的数据。
    • AOF:记录每一次写操作命令,数据安全度高,最多丢一秒的数据(可配置),但文件会越来越大,恢复速度慢。 怎么更顺畅? 通常建议同时开启RDB和AOF,用RDB做定期冷备,用AOF保证数据安全,可以调整AOF的重写条件(auto-aof-rewrite-percentageauto-aof-rewrite-min-size),避免在业务高峰时段触发AOF重写(一个消耗资源的操作)。
  4. 使用连接池。 频繁地创建和关闭连接到Redis是很耗时的,使用连接池,预先建立好一些连接放在那里,需要用的时候直接拿,用完了放回去,能极大提升效率,降低延迟。

  5. 考虑使用更高效的数据结构。 Redis不只是简单的Key-Value存储,如果你要存一个用户的个人信息,不要用多个独立的Key(user:1001:name, user:1001:age),而是用一个Hash结构(key是 user:1001,field是name, age等),这样网络传输次数更少,更节省内存,也更快。

  6. 监控和预警。 你不能等到服务出问题了才发现,要用监控工具(比如Redis自带的INFO命令,或者Grafana+Prometheus等)持续监控Redis的关键指标:内存使用率连接数命中率keyspace_hits / (keyspace_hits + keyspace_misses))、延迟等,设置预警阈值,比如内存使用超过80%就发告警,让你有机会在问题发生前主动干预。

让Redis性能和体验更顺畅,是一个系统工程,它需要:

  • 正确的配置:设好内存上限和淘汰策略。
  • 良好的编码习惯:设置分散的过期时间、使用高效命令和数据结构、使用连接池。
  • 完善的运维保障:配置合理的持久化策略、建立监控预警。

把这些点都做到位,你的Redis缓存服务就能在自动清理旧数据的同时,保持高效、稳定、顺滑的运行状态,为用户提供流畅的体验。