Redis挂了,流量把数据库也打挂了,怎么办? (上)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis挂了,流量把数据库也打挂了,怎么办? (上)

image.png

他说他当时,一时间竟然找不到回答问题的角度,感觉自己没有回答到点子上。

我仔细想了一下,确实是感到这个问题有一丝丝的奇怪,有一种让人千言万语,又突然懵逼不知从何说起的神奇力量。

为什么这么说呢?

我们先读题啊,仔细的读一遍题,我给你翻译一下。

如果线上 Redis 挂了。然后所有请求打到数据库导致数据库也挂了。

这是啥?

Redis 挂了,不就是缓存都没了吗?

缓存都没了,不就是缓存雪崩了吗?

缓存雪崩了,不就导致数据库挂了吗?

一提到“缓存雪崩”这四个字,缓存穿透、缓存击穿这几兄弟,是不是就立马条件反射的出现在你的脑海里面了,还顺带着对应的几套解决方案。

然后就像背书似的,什么缓存全没了,什么缓存没有数据库中有,什么缓存和数据库中都没有...

image.png

张口就是几分钟不带停顿的。

另外关于缓存击穿和缓存穿透,很多同学都会搞混。

你换一个记法,缓存戳穿、缓存戳透。

穿,只是穿过了缓存。

透,是直接干到底。

你细品,应该就不会记混。

image.png

除了上面的“Redis 缓存三连击”这一套八股文之外,还隐藏着另外一个八股文:

Redis 挂了,为什么挂了?怎么就挂了?是不是有单点问题?

这不就是问你 Redis 服务的高可用吗?

说到 Redis 的高可用,脑子里面必须马上蹦出来主从、哨兵和集群吧?

想到这些了,张口又是几分钟不带停顿的。

但是这几分钟的千言万语,马上就被下面这个问题给干懵逼了?

这时该怎么进行恢复?

现在问你怎么恢复,就是事中的事儿了。

你得先说怎么恢复,再说怎么预防。

你要是上来就回答前面说的什么“缓存三连击”、“高可用架构”,还包括大多数同学能想到的多级缓存、限流措施、服务降级、熔断机制,这些都有点牵强。

因为毕竟这些手段都是事前的预防措施,上来就说这些背书痕迹比较明显。

答肯定是要答的,从事中恢复过度到事前预防方案,而且重点就是事前预防,那么我们怎么过度的自然一点呢?

先说事中怎么恢复,其实我觉得几句话就说完了。

服务挂了啊,老哥,还能怎么恢复,当然是重启服务啊。

站在运维人员的角度,当然优先考虑是先把 Redis 和数据库服务重新启动起来啦。

但是启动之前得先做个小操作,把流量摘掉,可以先把流量拦截在入口的地方,比如简单粗暴的通过 Nginx 的配置把请求都转到一个精心设计的错误页面,就是说这么一个意思。

这样做的目的是为了防止流量过大,直接把新启动的服务,启动一个打挂一个的情况出现。

要是启动起来又扛不住了,请在心里默念分布式系统三大利器:

image.png


不行就加钱,堆机器嘛。

要觉得堆机器没啥技术含量,你就再从缓存预热的角度答一个。

就是当 Redis 服务重新启动后,通过程序先放点已知的热点 key 进去后,系统再对外提供服务,防止缓存击穿的场景。

而且上面这一系列操作其实和开发人员的关系不大,主要是运维同学干的事儿。

开发同学最多就是在设计服务的时候做到服务无状态,以达到快速水平扩容的目的。

至于怎么去快速水平扩容,那是运维同学的事儿,暂时不要去抢别人的饭碗。

答到这,你就可以用“但是”来过度到事前预防,开始自己的表演了。

故作沉思的对面试官说“but”了:


image.png


我觉得从技术方案的角度来说,我们应该做到事前预防。

这一切的问题都是因为 Redis 崩了,也就是发生了缓存雪崩。

在高并发的情况下,除了缓存雪崩,我们还必须得考虑到缓存的击穿、穿透问题。

而且 Redis 为什么会崩了?是不是使用姿势不对?是不是没有保证高可用?

服务中是不是需要考虑限流或者熔断机制,最大程度的保护程序的运行?

或者我们是否应该建立多级缓存的机制,防止 Redis 挂掉之后,大批流量直接打到 MySQL 服务导致数据库的崩盘?

至此,“but”完成,答题的方向从事中恢复,转向了事前预防,进入了我们的强项,八股文专场,然后就可以开始“背诵”了。

我这里简单的聊一下缓存问题三连击和 Redis 的高可用。

至于多级缓存,可以看看我之前发的这篇文章:《这波舒服了,落地多级缓存!》


缓存击穿


先说一下缓存击穿的概念。

缓存击穿是指一个请求要访问的数据,缓存中没有,但数据库中有的情况。

image.png

这种情况一般来说就是缓存过期了。

但是这时由于并发访问这个缓存的用户特别多,这是一个热点 key,这么多用户的请求同时过来,在缓存里面没有取到数据,所以又同时去访问数据库取数据,引起数据库流量激增,压力瞬间增大,直接崩溃给你看。

所以一个数据有缓存,每次请求都从缓存中快速的返回了数据,但是某个时间点缓存失效了,某个请求在缓存中没有请求到数据,这时候我们就说这个请求就"击穿"了缓存。

针对这个场景,对应的解决方案一般来说有三种。

  • 第一个就是只放行一个请求到数据库,然后做构建缓存的操作。

多个请求只放行一个,怎么做?

就借助 Redis setNX 命令设置一个标志位就行。设置成功的放行,设置失败的就轮询等待。

  • 第二个解决方案就是后台续命。

这个方案的思想就是,后台开一个定时任务,专门主动更新即将过期的数据。

比如程序中设置 why 这个热点 key 的时候,同时设置了过期时间为 10 分钟,那后台程序在第 8 分钟的时候,会去数据库查询数据并重新放到缓存中,同时再次设置缓存为 10 分钟。

怎么样,是不是有点 Redisson 分布式锁看门狗的味道?

我觉得思想是一脉相承的。

只是方案落地的时候,从代码编写的角度来说稍微麻烦了一点。

我曾经也借助这个思想开发过一个流水号系统。

大概是这样的。

流水号系统,属于非常关键的系统,为了降低数据库异常对服务带来的冲击,所以服务启动后会就会为每种业务系统都预先在缓存中缓存 5000 个流水号。

然后后台 Job 定时检查缓存中还剩下多少流水号,如果小于 1000 个,则再预先生成新的流水号,补充到缓存中,让缓存中的流水号再次回到 5000 个。

这样做的好处就是数据库异常后,我至少保证还有 5000 个缓存可以保证上游业务,我有一定的时间去恢复数据库。

这也算是一种后台续命的思想。

  • 第三个方法就简单了:永不过期。

缓存为什么会被击穿,是不是因为设置了超时时间,然后被回收了?

那我不设置超时时间不就行了?

如果结合实际场景你用脚趾头都能想到这个 key 一定会是个热点 key,会有大量的请求来访问这个数据。而且这个 key 对应的 value 不会发生变化。

对于这样的数据你还设置过期时间干什么?

直接放进去,永不过期。

其实上面的后台续命思想的最终体现是也是永不过期。

只是后台续命的思想,会主动更新缓存,适用于缓存会变的场景。会出现缓存不一致的情况,取决于你的业务场景能接受多长时间的缓存不一致。

总之,具体情况,具体分析。

但是思路要清晰,最终方案都是常规方案的组合或者变种。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
3月前
|
canal 缓存 NoSQL
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
根据对一致性的要求程度,提出多种解决方案:同步删除、同步删除+可靠消息、延时双删、异步监听+可靠消息、多重保障方案
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
|
3月前
|
Oracle NoSQL 关系型数据库
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
644 2
|
4月前
|
SQL 存储 NoSQL
Redis6入门到实战------ 一、NoSQL数据库简介
这篇文章是关于NoSQL数据库的简介,讨论了技术发展、NoSQL数据库的概念、适用场景、不适用场景,以及常见的非关系型数据库。文章还提到了Web1.0到Web2.0时代的技术演进,以及解决CPU、内存和IO压力的方法,并对比了行式存储和列式存储数据库的特点。
Redis6入门到实战------ 一、NoSQL数据库简介
|
4月前
|
存储 缓存 NoSQL
Redis内存管理揭秘:掌握淘汰策略,让你的数据库在高并发下也能游刃有余,守护业务稳定运行!
【8月更文挑战第22天】Redis的内存淘汰策略管理内存使用,防止溢出。主要包括:noeviction(拒绝新写入)、LRU/LFU(淘汰最少使用/最不常用数据)、RANDOM(随机淘汰)及TTL(淘汰接近过期数据)。策略选择需依据应用场景、数据特性和性能需求。可通过Redis命令行工具或配置文件进行设置。
103 2
|
4月前
|
JSON NoSQL Redis
Redis 作为向量数据库快速入门指南
Redis 作为向量数据库快速入门指南
223 1
|
4月前
|
网络协议 NoSQL 网络安全
【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下)
【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下)
|
4月前
|
存储 缓存 NoSQL
基于SpringBoot+Redis解决缓存与数据库一致性、缓存穿透、缓存雪崩、缓存击穿问题
这篇文章讨论了在使用SpringBoot和Redis时如何解决缓存与数据库一致性问题、缓存穿透、缓存雪崩和缓存击穿问题,并提供了相应的解决策略和示例代码。
85 0
|
存储 缓存 负载均衡
学会这15点,让你分分钟拿下Redis数据库
介绍Redis技术入门的一些基础知识点
学会这15点,让你分分钟拿下Redis数据库
|
存储 NoSQL 数据库
学会这15点,让你分分钟拿下Redis数据库
原文:学会这15点,让你分分钟拿下Redis数据库 1、Redis简介 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。
1180 0
|
5天前
|
存储 缓存 NoSQL
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
118 85