主从复制
https://redis.io/docs/management/replication/
master以写为主,slave以读为主。当master数据变化时,自动将新的数据异步同步到其它slave数据库
- 功能:读写分离;容灾恢复;数据备份;水平扩容支撑高并发
- 缺点:复制延时,信号衰减;master挂了不会在slave节点自动重选master
搭建一主(6379)二从(6380,6381)
三个Redis的服务器网络相互ping通,防火墙的配置正确
配置文件修改
- 开启daemonize yes
- 注释掉bind 127.0.0.1 - : :1
- 关闭保护模式 protected-mode no
- 指定端口 port 6379
- 指定当前工作目录 dir /myredis
- 修改pid文件名称 pidfile /var/run/redis_6379.pid
- 修改log文件名字 logfile “/myredis/6379.log”
- 设置密码 requirepass 123456
- 修改dump.rdb名称 dbfilename dump6379.rdb
- 持久化aof配置(可选):
- 开启aof appendonly yes
- appendfilename “appendonly.aof”
- appenddirname “appendonlydir”
- 配置从机访问主机的密码(主机无密码不需配置,主从复制只需要配从机,但为了下一步哨兵master也必须配) masterauth “123456”
- 从机配置连接主机的信息(主机不能配) replicaof 192.168.10.20 6379
查看主从复制情况
先master后两个slave启动
-
查看日志
- 主机日志vim 6379.log
Synchronization with replica 192.168.10.20:6380 succeeded
Synchronization with replica 192.168.10.20:6381 succeeded - 从机日志tail -f 6380.log
Connecting to MASTER 192.168.10.20:6379
…
Successful partial resynchronization with master
- 主机日志vim 6379.log
-
在每个服务上使用命令 info replication
注意事项
- 从机不能执行写命令,只能读
- slave不管是从头开始复制还是半路跟着复制,都会复制master全部的数据;从机down后再次启动,也会把落下的复制数据同步上
- 主机shutdown后,从机原地待命,从机数据可以正常使用,等待主机归来
- 主机shutdown,重启后主从关系还在,从机还可以正常复制
- 上一个slave可以是下一个slave的master,slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻主master的写压力
- 可以使用命令临时改变主从关系,即使所有服务都是master启动,改变之前的数据会被清除,重新拷贝数据;但重启服务后配置会失效
主从复制内部流程
- slave启动,同步初请
slave启动成功连接到master后会发送一个sync命令
slave首次全新连接master,一次完全同步(全量复制)将被自动执行,slave自身原有数据会被master数据覆盖清除 - 首次连接,全量复制
master节点收到sync命令后会开始在后台保存快照(即RDB持久化,主从复制时会触发RDB),
而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中,从而完成复制初始化同时收集所有接收到的用于修改数据集命令缓存起来,master节点执行RDB持久化完后,master将rdb快照文件和所有缓存的命令发送到所有slave,以完成一次完全同步 - 心跳持续,保持通信
master发出PING包的周期,默认是10秒 repl-ping-replica-period 10 - 进入平稳,增量复制
Master继续将新的所有收集到的修改命令自动依次传给slave,完成同步 - 从机下线,重连续传
master会检查backlog里面的offset,master和slave都会保存一个复制的offset还有一个masterId,offset是保存在backlog中的。Master只会把已经复制的offset后面的数据复制给Slave,类似断点续传
哨兵sentinel
https://redis.io/docs/manual/sentinel/
吹哨人巡查监控后台master主机是否故障,如果故障了根据投票数自动将某一个从库转换为新主库,继续对外服务
- 功能
- 主从监控:监控主从redis库运行是否正常
- 消息通知:哨兵可以将故障转移的结果发送给客户端
- 故障转移:如果Master异常,则会进行主从切换,将其中一个Slave作为新Master
- 配置中心:客户端通过连接哨兵来获得当前Redis服务的主节点地址
- 使用建议
- 哨兵节点的数量应为多个,哨兵本身应该集群,保证高可用
- 哨兵节点的数量应该是奇数
- 各个哨兵节点的配置应一致
- 如果哨兵节点部署在Docker等容器里面,尤其要注意端口的正确映射
- 哨兵集群+主从复制,并不能保证数据零丢失(考虑使用集群)
- 一组哨兵可以同时监控多个master,配置多行sentinel monitor 即可
运行流程
- 三个哨兵监控一主二从服务
- SDown主观下线(Subjectively Down)
单个Sentinel实例对服务做出的下线判断,即单个sentinel认为某个服务下线(有可能是接收不到订阅,之间的网络不通等等原因)。如果服务在[sentinel down-after-milliseconds]给定的毫秒数之内没有回应PING命令或者返回一个错误消息, 那这个Sentinel会主观的(单方面的)认为这个master不可用
sentinel down-after-milliseconds <masterName> <timeout>
- ODown客观下线(Objectively Down)
masterName是对某个master+slave组合的一个区分标识(一套sentinel可以监听多组master+slave这样的组合)
quorum这个参数是进行客观下线的一个依据,法定人数/法定票数,至少有quorum个sentinel认为这个master有故障才会对master进行下线以及故障转移。因为有时,某个sentinel节点可能因为自身网络原因导致无法连接master,而此时master并没有出现故障,所以就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,保证了公平性和高可用。
sentinel monitor <master-name> <ip> <redis-port> <quorum>
- 选举出领导者哨兵(哨兵中选出兵王)
当主节点被判断客观下线以后,各个哨兵节点会进行协商,先选举出一个领导者哨兵节点(兵王)并由该领导者节点,也即被选举出的兵王进行failover(故障迁移)
监视该主节点的所有哨兵都有可能被选为领导者,选举使用的算法是Raft算法;Raft算法的基本思路是先到先得:即在一轮选举中,哨兵A向B发送成为领导者的申请,如果B没有同意过其他哨兵,则会同意A成为领导者 - 兵王开始推动故障切换流程并选出一个新master
- 选新的master
规则:redis.conf文件中,优先级slave-priority或者replica-priority最高的从节点(数字越小优先级越高 );复制偏移位置offset最大的从节点;最小Run ID的从节点(字典顺序,ASCII码) - 配置slave
Sentinel leader会对选举出的新master执行slaveof no one操作,将其提升为master节点;Sentinel leader向其它slave发送命令,让剩余的slave成为新的master节点的slave - 配置原master改完slave
Sentinel leader会让原来的master降级为slave,当重新上线后会成为新master的从节点 - failover操作均由sentinel自己独自完成,并已将配置信息持久化到配置文件,完全无需人工干预
- 选新的master
搭建三个哨兵(26379、26380、26381)监控一主(6379)二从(6380,6381)
3个哨兵:自动监控和维护集群,不存放数据,只是吹哨人
1主2从:用于数据读取和存放
配置文件
- bind 服务监听地址,用于客户端连接,默认本机地址
- daemon 是否以后台daemon方式运行
- protected-mode 安全保护模式
- port 端口
- logfile 日志文件路径
- pidfile pid文件路径
- dir 工作目录
- sentinel monitor masterName ip port quorum : masterName是对某个master+slave组合的一个区分标识(一套sentinel可以监听多组master+slave这样的组合),quorum:确认客观下线的最少的哨兵数量
- sentinel auth-pass masterName password 连接master的密码
- sentinel down-after-milliseconds :指定多少毫秒之后,主节点没有应答哨兵,此时哨兵主观上认为主节点下线
- sentinel parallel-syncs master-name nums :表示允许并行同步的slave个数,当Master挂了后,哨兵会选出新的Master,此时,剩余的slave会向新的master发起同步数据
- sentinel failover-timeout master-name milliseconds :故障转移的超时时间,进行故障转移时,如果超过设置的毫秒,表示故障转移失败
- sentinel notification-script master-name script-path :配置当某一事件发生时所需要执行的脚本
- sentinel client-reconfig-script master-name script-path:客户端重新配置主节点参数脚本
bind 0.0.0.0
daemonize yes
protected-mode no
port 26379
logfile "/myredis/sentinel26379.log"
pidfile /var/run/redis-sentinel26379.pid
dir /myredis
sentinel monitor mymaster 192.168.10.20 6379 2
sentinel auth-pass mymaster 123456
bind 0.0.0.0
daemonize yes
protected-mode no
port 26380
logfile "/myredis/sentinel26380.log"
pidfile /var/run/redis-sentinel26380.pid
dir "/myredis"
sentinel monitor mymaster 192.168.10.20 6379 2
sentinel auth-pass mymaster 123456
bind 0.0.0.0
daemonize yes
protected-mode no
port 26381
logfile "/myredis/sentinel26381.log"
pidfile /var/run/redis-sentinel26381.pid
dir "/myredis"
sentinel monitor mymaster 192.168.10.20 6379 2
sentinel auth-pass mymaster 123456
启动
redis-sentinel sentinel26379.conf --sentinel
redis-sentinel sentinel26380.conf --sentinel
redis-sentinel sentinel26381.conf --sentinel
查看sentinel26379.log、sentinel26380.log、sentinel26381.log 查看故障转移过程
文件的内容,在运行期间会被sentinel动态进行更改
Master-Slave切换后,主从机的redis.conf和所有哨兵的sentinel.conf的内容都会发生改变