Redis
原理
Redis的主从复制:
1、同一个Master可以同步多个Slaves。
2、Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。
3、Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。
4、Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据。
5、在Slave启动并连接到Master之后,它将主动发送一个SYNC命令。此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。而Slave服务器在接收到数据库文件数据之后将其存盘并加载到内存中。即连上之后,先进行一次全量同步。
6、此后,Master继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。后面进行增量同步。
7、 如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。
发现故障
主观下线(subjectively down,SDOWN):当前 Sentinel 实例认为某个 redis 服务为”不可用”状态。Sentinel 向 redis master 数据节点发送消息后 30s(down-after-milliseconds) 内没有收到有效回复(+PONG、-LOADING 或者 -MASTERDOWN),Sentinel 会将 master 标记为下线
**客观下线(objectively down,ODOWN):**多个 Sentinel 实例都认为 master 处于 SDOWN 状态,那么此时 master 将处于 ODOWN, ODOWN可以简单理解为master已经被集群确定为”不可用”,将会开启故障转移机制。向其他 sentinel 节点发送 sentinel is-master-down-by-addr
消息询问数据节点情况,得知达到 quorum 数量的 sentinel 节点认为数据节点已经下线
故障处理–选举
就是选举出新的Leader-Sentinel,选举过程如下:
1、发现主库客观下线的哨兵节点(这里称为A)向每个哨兵节点发送命令要求对方选举自己为领头哨兵(leader);
2、如果目标哨兵没有选举过其他人,则同意将A选举为领头哨兵;
3、如果A发现有超过半数且超过quorum参数值的哨兵节点同意选自己成为领头哨兵,则A哨兵成功选举为领头哨兵。
4、当有多个哨兵节点同时参与领头哨兵选举时,出现没有任何节点当选可能,此时每个参选节点等待一个随机时间进行下一轮选举,直到选出领头哨兵。
故障处理–转移(切换 Redis master 数据节点)
- sentinel master 选择合适的 redis slave 成为 master
slave 选择标准:健康的节点:在线的、最近成功通信过的(5s 内回复过PING
命令)、数据比较新的(与 master 失联时间不超过 10*down-after-milliseconds)、slave-priority(slave节点优先级)最高的slave节点(越小越高,master节点的优先级为0,因此如果设置为0的话永远不会被选为主)、复制偏移量最大的 slave 节点(复制的最完整)、选择 runId 最小的 slave 节点(启动最早的节点) - 执行
SLAVEOF no one
(不会删除已有数据,只是不再接受主节点新的数据变化) 命令让其成为新的 master 节点。每秒 Sentinel 向其发送一次INFO
命令,直到成功变为 master - 向剩余的 slave 节点发送
SLAVEOF 新master
命令,让他们成为新 master 节点的 slave 节点 - 让剩余的 slave 复制新 master 的数据,通过配置
sentinel parallel-syncs
(sentinel.conf) 规定了每次向新的主节点发起复制操作的从节点个数,parallel-syncs 取值越大,slave 完成复制的时间越快,但是对主节点的网络负载、硬盘负载造成的压力也越大 - 更新原来master 节点配置为 slave 节点,并保持对其进行关注,一旦这个节点重新恢复正常后,会命令它去复制新的master节点信息
- 全部故障转移工作完成后,Leader Sentinel 就会推送 +switch-master 消息,同时重置 master,重置操作会释放掉原来 master 全部的 slave 对象和监听该 master 的其他 Sentinel 对象,然后创建出新的 slave 对象。故障迁移过程中 slave 能否返回数据给客户端取决于
slave-serve-stale-data
(redis.conf) - 持续关注旧的 master,并在他重新上线后将它设置为新 master 的 slave
在 sentinel 中执行 sentinel failover master
可以强制该 sentinel 节点执行故障转移,不与其他节点进行选举(跳过leader的选举过程),因为最先使用优先级进行选择新master,那么可以使用以下命令来配置redis的slave优先级
## 默认是100,这里配置成50
config set slave-priority 50
## 其他可配置项目可以通过以下命令查看
config get *
## 配置的信息如果想要保存到配置文件中,可以使用以下命令,进行redis主备转移的时候会默认执行一次这个
config rewrite
配置
redis.conf配置内容如下:
# 开启后台启动,默认为no
daemonize yes
# 新增密码
requirepass "password"
# 允许从节点进行写功能
slave-read-only no
# 设置了密码,主节点需要进行密码认证
masterauth "password"
# 如果是Slave则需要配置Master的地址
# slaveof 10.10.10.238 6379
sentinel.conf配置内容如下:
# 检查主redis节点的地址和端口信息,1代表至少1个sentinel节点认为主节点宕机才算宕机,根据实际情况进行配置
sentinel monitor mymaster 10.10.10.44 6379 1
# 主节点失联X秒后,认为主节点不可达,默认30s
sentinel down-after-milliseconds mymaster 5000
# 主节点的密码,如有的话
sentinel auth-pass mymaster password
# sentinel后台运行
daemonize yes
# 解决哨兵之间不能通信,不能进行主结节客观下线的判断,以及failover
protected-mode no
测试
redis.conf配置文件(关键内容)如下:
# 237
daemonize yes
requirepass zhkjredis@002396
slave-read-only no
masterauth zhkjredis@002396
# 238
daemonize yes
requirepass zhkjredis@002396
slave-read-only no
masterauth zhkjredis@002396
slaveof peerServer 6379
# 104
daemonize yes
requirepass zhkjredis@002396
slave-read-only no
masterauth zhkjredis@002396
slaveof server237 6379
sentinel.conf配置文件(关键内容)如下:
# 237
sentinel monitor mymaster localServer 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel auth-pass mymaster password
daemonize yes
protected-mode no
# 238
sentinel monitor mymaster peerServer 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel auth-pass mymaster password
daemonize yes
protected-mode no
# 104
sentinel monitor mymaster server237 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel auth-pass mymaster password
daemonize yes
protected-mode no
先启动237的redis和sentinel,然后启动238和104的组件。
通过INFO命令可以看到237为master,下面有两个slave,一个是238一个是104
# 237-Replication
role:master
connected_slaves:2
slave0:ip=10.10.10.238,port=6379,state=online,offset=17686,lag=1
slave1:ip=10.10.10.104,port=6379,state=online,offset=17408,lag=1
# 238-Replication
role:slave
master_host:peerServer
master_port:6379
master_link_status:up
# 104-Replication
role:slave
master_host:peerServer
master_port:6379
master_link_status:up
在237插入<test, test>,分别在238和104进行查询,能够查询成功,说明238和104对237同步成功。
在238插入<test238, test>,分别在237和104查询,查询失败,说明237和104并没有同步238数据,且slave能够进行数据的插入。
关闭237,此时经过选举之后,238和104中其中一个将会成为新的master,讲238重新上线,238将会成为新master的slave。
将237重新变为master,此时想指定让104成为master,需要进行以下操作:
## 先保证238和104的优先级为100,然后设置237的优先级为50
redis-cli -h 10.10.10.104 -a zhkjredis@002396 config set slave-priority 100
redis-cli -h 10.10.10.104 -a zhkjredis@002396 config rewrite
redis-cli -h 10.10.10.238 -a zhkjredis@002396 config set slave-priority 100
redis-cli -h 10.10.10.238 -a zhkjredis@002396 config rewrite
redis-cli -h 10.10.10.237 -a zhkjredis@002396 config set slave-priority 50
## 进行sentinel故障转移
redis-cli -h 10.10.10.237 -a zhkjredis@002396 -p 26379 sentinel failover mymaster
## 等待104成为master之后,讲104的优先级改回100
redis-cli -h 10.10.10.237 -a zhkjredis@002396 config set slave-priority 100
redis-cli -h 10.10.10.237 -a zhkjredis@002396 config rewrite
主动主备切换
保证除了指定成为新master的redis的优先级变成100,然后讲该redis的优先级设置为50,然后通过sentinel的命令进行故障转移,待转移完成之后,讲该redis的优先级改回100。
例如目前237为master,要使得104成为主,只需要保证237和238的slave优先级为100,并讲104的优先级设置为50,然后进行故障转移,等待转移完成之后将104的优先级改回100.
被动主备切换
当发生故障转移时,sentinel会选举出leader-sentinel,然后由该sentinel选择适合的redis成为新的master,原master重新上线时候,会被sentinel转换成当前master的slave。