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

Redis缓存值突然没了?迷失原因和应对办法聊聊

Redis缓存值突然没了?迷失原因和应对办法聊聊

你有没有遇到过这种情况:网站或者App用得好好的,突然一下子变得特别卡,加载个图片、看段文字都要转半天圈圈,一查问题,发现是Redis缓存里的数据没了,所有请求都直接砸向了数据库,数据库一下子扛不住,整个系统就慢下来了,这种“缓存突然消失”的现象,我们通常称之为缓存失效,但它背后可能的原因可不止一种,今天我们就来聊聊这些原因,以及怎么去应对。

最常见的一个原因就是缓存键(Key)过期了,Redis可以给每个缓存值设置一个生存时间,比如十分钟或者一小时,时间一到,Redis就会自动把这个键值对删除掉,给新数据腾地方,这本来是Redis清理旧数据、保持高效的好机制,但如果大量关键数据在同一时间点过期,就会出问题,想象一下,你给一万个商品数据都设置了凌晨两点准时过期,那么两点钟一过,所有用户来查询商品,都发现缓存没了,只能去查数据库,数据库的压力瞬间达到峰值,很可能就崩溃了,这种大量Key集中过期导致的问题,也叫“缓存雪崩”,应对这个问题的办法很简单,就是给缓存设置过期时间的时候,加个随机数,比如原本想都设置成一小时,现在可以设置成一小时加上一个零到五分钟的随机值,这样,这些缓存就不会在同一时刻集体失效,而是分散在一小段时间内陆续失效,数据库的压力就被平摊开了,避免了被“一波带走”。

一个容易被忽略的原因是Redis服务本身出了问题,服务器突然断电了,或者Redis进程因为某种原因崩溃了,如果你没有做任何持久化设置,那么内存里的所有数据就会全部丢失,重启Redis之后,它面对的就是一个空荡荡的数据库,为了解决这个问题,Redis提供了两种主要的持久化机制,可以理解为给内存数据拍快照,一种是RDB,它就像定时拍照,每隔一段时间把整个数据库的状态保存到一个文件里,优点是恢复起来快,缺点是如果刚拍完照数据就变了,到下次拍照之前的修改可能会丢失,另一种是AOF,它更像写日记,会把每一个写命令都记录下来,这样即使服务器宕机,重启后重新执行一遍这些命令,就能恢复到宕机前的状态,数据更安全,但恢复速度可能慢一些,日志文件也会更大,生产环境会结合使用这两种方式,在性能和可靠性之间找个平衡。

第三个原因,跟Redis的内存管理有关,当Redis占用的内存超过了它被设置的最大限制时,它就会启动内存淘汰机制,这个机制会根据你预设的策略,自动删除一些数据来腾出空间,策略有很多种,最近最少使用”的优先删除,或者“随机删除”等等,如果你的应用数据很重要,但内存又不够用,就可能发生重要的缓存数据被Redis自己给“踢”出去了,应对办法首先是合理设置内存大小和淘汰策略,你要根据业务重要性来选择,比如如果是缓存系统,可以选择淘汰最近不常用的数据;如果所有数据都重要,那可能就需要增加服务器内存了,要做好内存使用的监控,快满的时候能及时收到告警。

还有一种特殊情况是针对某一个热点数据的,叫做缓存击穿,就是指一个非常热门的Key,比如某个秒杀活动的商品信息,在它过期的瞬间,有海量的请求同时来读取这个数据,发现缓存失效后,这些请求又会同时去查询数据库,导致数据库瞬间压力巨大,应对这种情况,一个常见的办法是使用互斥锁,简单说就是,当第一个发现缓存失效的请求去数据库查询时,它先加上一把“锁”,告诉其他请求:“我正在查,你们等会儿”,等其他请求再来时,发现已经有“人”在查了,就原地等待一下,等第一个请求把数据从数据库取回来并重新设置到缓存后,大家就直接从缓存里拿了,这样就避免了所有人都去攻击数据库。

一些人为操作也可能导致数据丢失,比如运维同学不小心执行了flushallflushdb这样的命令,清空了整个Redis的数据,这就要求我们严格管理操作权限,并且谨慎对待生产环境的命令

Redis缓存数据突然没了,无外乎是“自动过期”、“服务挂了”、“内存满了被淘汰”或者“被热点请求击穿”这几种情况,应对的办法也围绕着这几方面展开:分散过期时间、配置持久化备份、设置合适的内存淘汰策略、对热点数据加锁保护,再加上规范的运维管理,理解了这些,下次再遇到缓存神秘消失的情况,你就能像个侦探一样,一步步找到原因并解决问题了。 参考和融合了知乎专栏“Redis缓存失效”相关讨论、博客园“深入理解Redis持久化”以及CSDN上关于缓存雪崩、击穿等概念的常见技术文章中的核心观点和解决方案)

Redis缓存值突然没了?迷失原因和应对办法聊聊