Redis 持久化 & 主从 & 哨兵 & 集群
2023-02-05 21:06:51 31 举报
Redis 持久化 & 主从 & 哨兵 & 集群
作者其他创作
大纲/内容
通信端口:服务端口+ 10000
网络抖动
slave
client
主从复制风暴(多个从节点同时复制主节点导致主节点压力过大)
1、链接断开
1、slave 发现自己的master 变为 FAIL
master
5、send buffer
将命令打包发送,redis必须在处理完所有命令前先缓存起所有命令结果,前面失败不影响后面执行,不能保证原子性
槽位定位算法HASH_SLOT = CRC16(key) mod 16384
集群脑裂数据丢失问题
跳转重定位:当客户端向一个错误的节点发出了指令,该节点会发现指令的 key 所在的槽位并不归自己管理,这时它会向客 户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。客户端收到指 令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有 key 将使用新的槽 位映射表。
搭建使用见博客: xxx
1、psync命令同步数据,发送命令之前会跟master建立socket长链接
sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。 哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过 sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis 主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)sentinel集群都启动完毕后,会将哨兵集群的元数据信息写入所有sentinel的配置文件里去(追加在文件的 最下面)当redis主节点如果挂了,哨兵集群会重新选举出新的redis主节点,同时会修改所有sentinel节点配置文件 的集群元数据信息.同时还会修改sentinel文件里之前配置的mymaster对应的端口当挂掉的redis实例再次启动时,哨兵集群根据集群元数据信息就可以将6379端口的redis节点作为从节点 加入集群代码应用见博客:xxxxxxxx //TODO 待补充
2.1、收到psync命令执行 bgsave生成最新rdb快照数据
3、send rdb 数据
Redis Cluster
重写时老数据用 RDB 二进制新数据 AOF 记录
Redis4.0 混合持久化
Redis集群对批量操作命令的支持
AOF 重写 -> bgrewriteaof 手动触发# auto-aof-rewrite-min-size 64mb //aof至少达到64M才会重写# auto-aof-rewrite-percentage 100 //aof文件自上次重写后,文件大小增长了100%(128M)则再次触发重写
Redis集群选举原理分析
工作原理:如果你为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个PSYNC 命令给master请求复制数据。 master收到PSYNC命令后,会在后台进行数据持久化通过bgsave生成最新的rdb快照文件,持久化期 间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完 毕以后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后 再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。 当master与slave之间的连接由于某些原因而断开时,slave能够自动重连Master,如果master收到了多 个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送 给多个并发连接的slave。
管道(Pipeline)
JedisCluster
高可用集群模式
*3$3 set $5zhuge$3666这是一种resp协议格式数据,星号后面的数字代表命令有多少个参数,$号后面的数字代表这个参数有几 个字符。注意,如果执行带过期时间的set命令,aof文件里记录的是并不是执行的原始命令,而是记录key过期的 时间戳
2、 master最近数据的缓存其实就是一些写命令
master25461~10922
7、master通过socket长链接持续把写命令发送给从结点,保证主从数据一致性
在 Lua 脚本中,可以使用redis.call()函数来执行Redis命令。注意,不要在Lua脚本中出现死循环和耗时的运算,否则redis会阻塞,将不接受其他的命令, 所以使用 时要注意不能出现死循环、耗时的运算。redis是单进程、单线程执行脚本。管道不会阻塞redis。
哨兵集群
sentinel
3、重新连接到master建立的是socket 长链接
Redis 哨兵高可用架构
lua脚本(Pipeline)
缺点
2.2、 master开始做rdb之后新数据的缓存其实就是一些写命令
4、psync(offset)
5、slave的offset 如果在 repl backlog buffer 中,则 master 会将缓存中从slave offset 之后的数据一次性同步给slave结点,否则会全量同步
gossip
rdb数据
redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis集群不需 要sentinel哨兵∙也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中 心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过1000个节点)。redis集群的 性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单
对于类似mset,mget这样的多个key的原生批量操作命令,redis集群只支持所有key落在同一slot的情况,如 果有多个key一定要用mset命令在redis集群上操作,则可以在key的前面加上{XX},这样参数数据分片hash计 算的只会是大括号里的值,这样能确保不同的key能落到同一slot里去,示例如下:mset {user1}:1:name zhuge {user1}:1:age 18假设name和age计算的hash slot值不一样,但是这条命令在集群下执行,redis只会用大括号里的 user1 做 hash slot计算,所以算出来的slot值肯定相同,最后都能落在同一slot。
# save 60 1000 //“ 60 秒内有至少有 1000 个键被改动时,自动保存数据集dump.rdb 文件save 同步命令 / bgsave 异步命令(默认, Copy-On-Write 写时复制)二进制文件存储
Redis 持久化
redis集群没有过半机制会有脑裂问题,网络分区导致脑裂后多个主节点对外提供写服务,一旦网络分区恢复, 会将其中一个主节点变为从节点,这时会有大量数据丢失。规避方法可以在redis配置里加上参数(这种方法不可能百分百避免数据丢失,参考集群leader选举机制): min-replicas-to-write 1 //写数据成功最少同步的slave数量,这个数量可以模仿大于半数机制配置,比如总共有三个结点可以配置1, 加上leader就是2,超过了半数注意:这个配置在一定程度上会影响集群的可用性,比如slave要是少于1个,这个集群就算leader正常也不能 提供服务了,需要具体场景权衡选择。
Redis集群节点间的通信机制redis cluster节点间采取gossip协议进行通信维护集群的元数据(集群节点信息,主从角色,节点数量,各节点共享的数据等)有两种方式:集中式和gossip集中式: 优点在于元数据的更新和读取,时效性非常好,一旦元数据出现变更立即就会更新到集中式的存储中,其他节 点读取的时候立即就可以立即感知到;不足在于所有的元数据的更新压力全部集中在一个地方,可能导致元数 据的存储压力。 很多中间件都会借助zookeeper集中式存储元数据。gossip:gossip协议包含多种消息,包括ping,pong,meet,fail等等。 meet:某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通 信; ping:每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过 ping交换元数据(类似自己感知到的集群节点增加和移除,hash slot信息等); pong: 对ping和meet消息的返回,包含自己的状态和其他信息,也可以用于信息广播和更新; fail: 某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了。
Redis 主从架构
RDB 快照(snapshot)备份数据
6、执行buffer里的命令写到内存
Redis集群为什么至少需要三个master节点,并且推荐节点数为奇数?
开启混合持久化# aof-use-rdb-preamble yesappendonly.aof
master10~5460
1. 写crontab定时调度脚本,每小时都copy一份rdb或aof的备份到一个目录中去,仅仅保留最近48 小时的备份 2. 每天都保留一份当日的数据备份到一个目录中去,可以保留最近1个月的备份 3. 每次copy备份的时候,都把太旧的备份给删了 4. 每天晚上将当前机器上的备份复制一份到其他机器上,以防机器损坏
5、slave收到超过半数master的ack后变成新的Master(集群最少需要3个结点的原因)
主从复制(全量复制) 流程图
repl backlogbuffer
当一个master服务器被某sentinel视为下线状态后,该sentinel会与其他sentinel协商选出sentinel的leader进 行故障转移工作。每个发现master服务器进入下线的sentinel都可以要求其他sentinel选自己为sentinel的 leader,选举是先到先得。同时每个sentinel每次选举都会自增配置纪元(选举周期),每个纪元中只会选择一 个sentinel的leader。如果所有超过一半的sentinel选举某sentinel作为leader。之后该sentinel进行故障转移 操作,从存活的slave中选举出新的master,这个选举过程跟集群的master选举很类似。 哨兵集群只有一个哨兵节点,redis的主从也能正常运行以及选举master,如果master挂了,那唯一的那个哨 兵节点就是哨兵leader了,可以正常选举新master。 不过为了高可用一般都推荐至少部署三个哨兵节点。为什么推荐奇数个哨兵节点原理跟集群奇数个master节点 类似。
1、减少网络开销2、原子操作3、替代redis 事务功能
问题:访问瞬断内存限制数据恢复同步效率
AOF 持久化(append-only file)记录修改指令
哨兵leader选举流程
必须先开启aof
2、将自己记录的集群 currentEpoch 加1, 并广播 FAILOVER_AUTH_REQUEST 信息
从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,一定的延迟确保我们等待 FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票延迟计算公式 DELAY = 500ms + random(0 ~ 500 ms) + SLAVE_RANK * 1000msSLAVE_RANK 表示此slave已经从master复制数据的总量的rank. Rank 越小代表已复制的数据越新,理论上会让持有最新数据的slave 首先发起选举。
Redis集群
当redis.conf的配置cluster-require-full-coverage为no时,表示当负责一个插槽的主库下线且没有相应的从 库进行故障恢复时,集群仍然可用,如果为yes则集群不可用。
因为新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,当其中 一个挂了,是达不到选举新master的条件的。 奇数个master节点可以在满足选举该条件的基础上节省一个节点,比如三个master节点和四个master节点的 集群相比,大家如果都挂了一个master节点都能选举新master节点,如果都挂了两个master节点都没法选举 新master节点了,所以奇数的master节点更多的是从节省机器资源角度出发说的。
Redis 集群原理
repl buffer
gossip协议的优点在于元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续,打到所有节点上 去更新,有一定的延时,降低了压力;缺点在于元数据更新有延时可能导致集群的一些操作会有一些滞后。
集群是否完整才能对外提供服务
4、尝试failover 的slave 收集master 返回的 FAILOVER_AUTH_ACK
6、slave 广播 Pong 消息通知其他集群节点
4、清空旧数据并加载主节点的rdb
划分槽位(slots)16384
#超出指定时间长度才认为失联cluster-node-timeout 5000
6、master 通过socket长链接持续把写命令发送给从结点,保证主从数据一致性
master310922~16384
0 条评论
下一页