Redis缓存淘汰策略、缓存穿透、缓存击穿、缓存雪崩及Redis集群(主从复制,哨兵模式)

发布于:2022-11-09 ⋅ 阅读:(814) ⋅ 点赞:(0)

“临渊羡鱼,不如退而结网”
共勉

一,Redis缓存淘汰策略

Redis将数据保存在内存中, 内存的容量是有限的。如果Redis服务器的内存已经全满,现在还需要向Redis中保存新的数据,如何操作,就是缓存淘汰策略

noeviction:返回错误(默认)
如果我们不想让它发生错误,就可以设置它将满足某些条件的信息删除后,再将新的信息保存。

allkeys-random:所有数据中随机删除数据
volatile-random:有过期时间的数据中随机删除数据
volatile-ttl:删除剩余有效时间最少的数据
allkeys-lru:所有数据中删除上次使用时间距离现在最久的数据
volatile-lru:有过期时间的数据中删除上次使用时间距离现在最久的数据
allkeys-lfu:所有数据中删除使用频率最少的
volatile-lfu:有过期时间的数据中删除使用频率最少的

其中最常用的还是后面四个,如何选择需要结合工作需求!

二,缓存穿透

所谓缓存穿透,就是一个业务请求先查询redis,redis没有这个数据,那么就去查询数据库,但是数据库也没有的情况。
正常业务下,一个请求查询到数据后,我们可以将这个数据保存在Redis,之后的请求都可以直接从Redis查询,就不需要再连接数据库了,但是一旦发生上面的穿透现象,仍然需要连接数据库,一旦连接数据库,项目的整体效率就会被影响,如果有恶意的请求,高并发的访问数据库中不存在的数据,严重的,当前服务器可能出现宕机的情况。

解决方案:布隆过滤器

1.针对现有所有数据,生成布隆过滤器,保存在Redis中
2.在业务逻辑层,判断Redis之前先检查这个id是否在布隆过滤器中
3.如果布隆过滤器判断这个id不存在,直接返回
4.如果布隆过滤器判断id存在,在进行后面业务执行

三,缓存击穿

一个计划在Redis保存的数据,业务查询,查询到的数据Redis中没有,但是数据库中有。这种情况要从数据库中查询后再保存到Redis,这就是缓存击穿
但是这个情况也不是异常情况,因为我们大多数数据都需要设置过期时间,而过期时间到时,这个数据就会从Redis中移除,再有请求查询这个数据,就一定会从数据库中再次同步。

缓存击穿图
注意:缓存击穿并不是什么灾难性的问题,是允许发生的,也是很常见的,少量的击穿并不会影响性能,但是大量的击穿合起来就会变成缓存雪崩!!!

四,缓存雪崩

以上将的缓存击穿,如果更严重点就会演变为下图
缓存雪崩图
所谓缓存雪崩,指的就是Redis中保存的数据,短时间内有大量数据同时到期的情况;
如上图所示,本应该由Redis反馈的信息,由于雪崩都去访问了Mysql,mysql承担不了,非常可能导致异常,要想避免这种情况,就需要避免大量缓存同时失效,大量缓存同时失效的原因:通常是同时加载的数据设置了相同的有效期导致的。

解决办法:

我们可以通过在设置有效期时添加一个随机数,这样就能够防止大量数据同时失效了。

五,Redis集群

Redis最小状态是一台服务器,这个服务器的运行状态,直接决定Redis是否可用,
如果它离线了,整个项目就会无Redis可用,系统会面临崩溃,为了防止这种情况的发生,我们可以准备一台备用机。

主从复制

主从复制
也就是主机(master)工作时,安排一台备用机(slave)实时同步数据,万一主机宕机,我们可以切换到备机运行缺点,这样的方案,slave节点没有任何实质作用,只要master不宕机它就和没有一样,没有体现价值。

读写分离

读写分离
这样slave在master正常工作时也能分担Master的工作了。
但是如果master宕机,实际上主备机的切换,实际上还是需要人工介入的,这还是需要时间的,那么如果想实现发生故障时自动切换,一定是有配置好的固定策略的。

哨兵模式:故障自动切换

哨兵模式
哨兵节点每隔固定时间向所有节点发送请求,如果正常响应认为该节点正常,
如果没有响应,认为该节点出现问题,哨兵能自动切换主备机。
如果主机master下线,自动切换到备机运行。

如图,哨兵发送ping指令,如果服务器正常运行是有响应的
哨兵模式检查服务器是否正常运行

当然,哨兵模式也有误判的可能,比如服务器明明正常运行,哨兵却收不到回应
哨兵误判
为了减少误判的可能,我们可以使用

哨兵集群

哨兵集群
我们可以将哨兵节点做成集群,由多个哨兵投票决定是否下线某一个节点;
哨兵集群中,每个节点都会定时向master和slave发送ping请求;
如果ping请求有2个(集群的半数节点)以上的哨兵节点没有收到正常响应,会认为该节点下线。
当业务不断扩展,并发不断增高时

分片集群

只有一个节点支持写操作无法满足整体性能要求时,系统性能就会到达瓶颈;
这时我们就要部署多个支持写操作的节点,进行分片,来提高程序整体性能;
分片就是每个节点负责不同的区域。
Redis0~16383号槽,
例如:
MasterA负责0~5000;
MasterB负责5001~10000;
MasterC负责10001~16383;
一个key根据CRC16算法只能得到固定的结果,一定在指定的服务器上找到数据。
分片集群
有了这个集群结构,我们就能更加稳定和更加高效的处理业务请求了。
为了节省哨兵服务器的成本,有些公司在Redis集群中直接添加哨兵功能,即master/slave节点完成数据读写任务的同时也都互相检测它们的健康状态。

本文含有隐藏内容,请 开通VIP 后查看