Redis缓存雪崩(主从复制、哨兵模式(脑裂)、分片集群)

2024-06-23 01:20

本文主要是介绍Redis缓存雪崩(主从复制、哨兵模式(脑裂)、分片集群),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

缓存雪崩:

在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。

方法一:

给不同key的TTL添加随机值,以此避免同一时间大量key失效。(用于解决同一时间大量key过期,后面的方法用于解决redis宕机)

方法二:

使用Redis集群提高服务可用性(哨兵模式、分片集群)

主从复制(解决高并发读):

在讲哨兵模式之前,我们需要先了解一下主从复制

单节点处理并发的能力有限,我们需要提供搭建集群来提高应对并发的能力。

主节点命名为master、子节点命名为(slave/replica)。由于redis基本上都是在执行读操作,所以我们只需要安排主节点负责写操作、子节点负责读操作就可以有效的提高应对并发的能力。不过这里就有一个问题,主节点执行了写操作后,怎么和子节点进行数据同步呢?

全量同步:

流程:

(以下是第一次同步的流程)

  1. 子节点执行replicaof命令建立连接。

    这里大家可能会有疑问,子节点什么时侯要建立连接呢?

    其实这个命令是在搭建集群的时候执行的,在搭建集群时我们会执行如下命令。

    # 服务器 B 执行这条命令以设置服务器A为自己的主节点
    replicaof <服务器 A 的 IP 地址> <服务器 A 的 Redis 端口号>

    执行完命令后,我们就建立好主从节点之间的连接了。

  1. 子节点请求数据同步(这里有两个很重要的参数:replid、offest)

  2. 主节点判断是否是第一次同步。就是通过replid来判断,一个数据集不论增删改查它的replid不变,所以如果子节点的replid和主节点不同,代表一定是第一次同步)

  3. 是第一次则返回数据版本信息(replid、offest)

  4. 子节点保存版本信息(这里子节点的replid就和主节点相同了)

  5. 主节点执行bgsave,生成RDB

  6. 主节点发送RDB

  7. 子节点清空数据并加载RDB(根据RDB生成数据)

  8. 主节点记录RDB期间所有的命令(有一步的原因:在子节点清空并生成数据的过程中,主节点可能会接收到写操作,但是发送的RDB里面数据是接收到写操作之前的数据,所以需要一个repl_baklog来记录生成RDB后接收的操作)

  9. 主节点发送repl_baklog中的命令(再次进行同步,确保数据相同)

  10. 子节点执行接受到的命令

(以下是非第一次同步的流程)

  1. 主节点发送repl_baklog中的命令(这里就用到刚刚说的重要的变量offest,在第一次同步时,步骤4发送了第一次offest,此后步骤10只需要根据offest,就可以判断需要发送哪些数据,比如说第一次步骤4发送的offest为5,而在子节点生成数据期间,repl_baklog记录的数据为7条,此时主节点的offest就变成了 5+7=12,那么主节点就会发送 12-5=7 条最新的命令给子节点以完成同步)

  2. 子节点执行接受到的命令

增量同步:

实际上和全量同步的非第一次同步流程很像,但是增量同步主要应对slave重启

流程:

  1. 子节点重启

  2. 子节点请求数据同步(这里同样会发送两个参数:replid、offest)

  3. 主节点判断是否是第一次(replid是否一致,不过这里我们建立过链接,只是因为slave重启了要重新同步数据)

  4. 不是第一次,主节点发送continue

  5. 主节点根据slave传入的offest(步骤2)来判断要发送那些repl_baklog中的命令

  6. 主节点发送repl_baklog中的命令

  7. 子节点执行命令

哨兵模式(解决高可用):

主从复制存在一个问题,如果主节点挂了,那么整个集群就不可用了(只有主节点执行写操作),为了应对这种情况,redis提供了哨兵机制。

监控:

用于判断节点是否可用

自动故障恢复:

当master节点被判断下线,哨兵就会进行选举

选举逻辑:

  1. 根据断开时间排除部分节点

  2. 判断slave-priority中的优先级,最小的被选举为主节点

  3. 如果slave-priority相同,就根据offest判断,offest越大代表数据越全面

  4. 最后是根据slave节点的运行id,每个slave节点在运行时都有一个id,越小优先级越高

脑裂问题:

哨兵模式会出现的一个问题,如果说由于某些原因(可能是网络原因),哨兵(sentinel)和master断开了连接(图一),但是master和Clinet的连接并没有中断,由于哨兵模式特有的自动故障修复功能,哨兵会在slave中重新选举出新的master节点(要注意,原本的master节点并没有下线,所有的数据操作仍然是在Client和原本的master之间进行),过了一段时间后,哨兵(sentinel)连接上了原本的主节点,但是由于哨兵认可的是新选举的master节点,所以原本的master节点会被降级为slave节点(图二),然后被降级的salve节点就会清空自己的数据重新申请新master节点的数据,这样会导致脑裂过程中Client和原本的master之间交换的数据全部丢失。

                                                                        图一

                                                                        图二

解决方法:

  1. 设置master节点 min-replicas-to-write 1(表示master节点最少要有一个slave节点,不然不进行数据操作)

  2. 设置master节点 min-replicas-max-lag 5(表示master节点与slave节点最久5s要通信一次,不然不进行数据操作)

分片集群:

主从复制解决了高并发读的问题,但是因为只有一个master在写,所以无法解决高并发写的问题,如果我们有多个master,是不是就可以解决高并发写的问题了?

  • 多个master解决高并发写的问题

  • 每个master有多个slave解决高并发读的问题(每个slave都可以读)

  • master通过ping检测彼此状态(sentinel相同功能,如果发现客观下线就在slave中新选举一个master,解决高可用问题)

  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点(要理解这个就要看下面的内容)

简单来说,不管是传进来什么样的数据,都会通过哈希函数计算出哈希值然后存放在对应区间的插槽中(这里要注意,如果key前面有大括号,就将大括号中的数据用于计算,如果没有大括号,就将key本身用于计算)

方法三:

给缓存业务添加降级限流策略(比如说nginx限流,sentinel降级)

方法四:

给业务添加多级缓存(充分利用请求处理的每个环节,分别添加缓存)

这篇关于Redis缓存雪崩(主从复制、哨兵模式(脑裂)、分片集群)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1085931

相关文章

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

Springboot整合Redis主从实践

《Springboot整合Redis主从实践》:本文主要介绍Springboot整合Redis主从的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言原配置现配置测试LettuceConnectionFactory.setShareNativeConnect

Redis过期删除机制与内存淘汰策略的解析指南

《Redis过期删除机制与内存淘汰策略的解析指南》在使用Redis构建缓存系统时,很多开发者只设置了EXPIRE但却忽略了背后Redis的过期删除机制与内存淘汰策略,下面小编就来和大家详细介绍一下... 目录1、简述2、Redis http://www.chinasem.cn的过期删除策略(Key Expir

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R

Redis指南及6.2.x版本安装过程

《Redis指南及6.2.x版本安装过程》Redis是完全开源免费的,遵守BSD协议,是一个高性能(NOSQL)的key-value数据库,Redis是一个开源的使用ANSIC语言编写、支持网络、... 目录概述Redis特点Redis应用场景缓存缓存分布式会话分布式锁社交网络最新列表Redis各版本介绍旧

Java如何从Redis中批量读取数据

《Java如何从Redis中批量读取数据》:本文主要介绍Java如何从Redis中批量读取数据的情况,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一.背景概述二.分析与实现三.发现问题与屡次改进3.1.QPS过高而且波动很大3.2.程序中断,抛异常3.3.内存消

Redis中的Lettuce使用详解

《Redis中的Lettuce使用详解》Lettuce是一个高级的、线程安全的Redis客户端,用于与Redis数据库交互,Lettuce是一个功能强大、使用方便的Redis客户端,适用于各种规模的J... 目录简介特点连接池连接池特点连接池管理连接池优势连接池配置参数监控常用监控工具通过JMX监控通过Pr

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe

如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)

《如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)》:本文主要介绍如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)问题,具有很好的参考价值,希望对大家有所帮助,如有... 目录先在你打算存放的地方建四个文件夹更改这四个路径就可以修改默认虚拟内存分页js文件的位置接下来从高级-

PyCharm如何更改缓存位置

《PyCharm如何更改缓存位置》:本文主要介绍PyCharm如何更改缓存位置的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录PyCharm更改缓存位置1.打开PyCharm的安装编程目录2.将config、sjsystem、plugins和log的路径