@
目录一、主从复制的概念
为什么需要主从复制,因为单机Redis会存在以下问题: ①机器故障,那么原本机器中的业务数据会损害造成不可挽回的损失;②容量瓶颈,单继Redis的内存有限,硬件条件拉跨无法存储巨额数据;为了避免这些问题保证数据的安全性和服务器的高可用性出现了主从复制。
主从复制是指,主机数据更新后根据配置和策略,自动同步到备机的master/slaver 机制,Master以写为主,Slave 以读为主。
二、主从复制基础用法
简介:
2.1 工作流程(1)建立连接
- 首先由 slave(从服务器)向 master(主服务器) 发送
slaveof ip port
指令申明称为 master的从机。紧接着slave 会保存master的地址(masterhost
)和端口(masterport
)以保存master的信息,然后根据保存的信息建立起与主机间的socket
连接。为了保证连接的不中断同时slave会不断发送ping
命令来测试连接是否联通。如果主机设置了密码,此时还需要从机进行身份验证auth password
来向主机核验自己的身份,如果验证授权通过从机才可以发送指令replconf listening-port <port-number>
来向master发送自己的端口信息。最终主从连接成功。 - 最终的状态是master保存了slave的端口信息;slave保存了master的地址和端口;总体二者之间建立了socket连接。
建立连接的方法:
-
启动方式1、客户端发送命令:
slaveof <masterip> <masterport>
-
启动方式2、启动服务器参数:
redis-server xxxxx.conf --slaveof host port
-
启动方式3、服务器配置:
slaveof <masterip> <masterport>
-
授权访问需要从机提供主机设置好的密码:
2.2 工作流程(2)数据同步
Redis数据同步可以分为全量复制和增量复制(部分复制)。
全量复制: 由slave发起 psyhc2指令给master,master会执行 bgsave
(rdb方式的手动持久化)来生成当前的rdb数据文件。但是在rdb持久化过程中新增的数据也需要记录,因此在第一个slave连接的时候master就创建了一个复制缓冲区来记录这一过程新增的指令。等到master持久化完成就会通过socket将rdb数据文件发送给slave,slave接收到RDB然后清空数据执行RDB文件恢复数据。
增量复制: 恢复完成后slave发送命令告知master已经恢复完成,master在这一阶段会发送复制缓冲区中的指令给slave,slave接收到这些指令执行 bgrewriteaof
来恢复数据(这是以aof的方式,因为复制缓冲区中存储的是指令而不是rdb文件类型的数据)。
需要注意的问题:
- master方面:
- 如果master数据量巨大,数据同步阶段应当避开流量高峰阶段,避免造成master阻塞,影响业务的正常进行;
- 复制缓冲区的大小必须设置合理,否则会导致数据溢出。比如全量复制时间太久,进行部分复制时发现数据已经存在丢失的情况,必须进行二次全量复制,可能导致slave陷入死循环。
可以通过修改repl-backlog-size
来修改复制缓冲区大小,默认是1MB - master单机内存占用主内存的比例不应太大,建议使用 50%~70%的内存,留下30%-50%的内存用于执行bgsave命令和创建复制缓冲区。
- slave方面:
- 为避免slave进行全量复制、部分复制时服务器响应阻塞或者数据不同步,建议关闭对外服务。
slave-serve-stale-data yes|no
- 数据同步阶段,master会向slave发送ping命令来测试连接。
- 多个salve向master请求数据同步,master发送的RDB文件过多,会对带宽造成巨大冲击,造成master的带宽不足。因此数据同步需要错峰进行。
- slave过多时建议调整拓扑结构,由一主多从调整为树状结构,中间的结点既是master,也是上一层的slave。但是需要注意树状结构的深度,如果深度过深,深度高的master和底层的slave之间数据同步延迟较大,数据一致性不高。
总结: 全量复制获取的是获取从发指令那一刻开始之前的所有数据;增量复制是获取rdb过程中的所有数据;
最终的状态为:slave持有master的全部数据,包含RDB过程中接收的数据;master持有slave当前数据同步的位置。
2.3 工作流程(3)命令传播
命令传播阶段就是对全量复制和增量复制的不断重复进行保证数据的实时一致性。
- 服务器的运行 id
- 复制缓冲区
工作原理: 当一条命令进来后master会将该命令拆解为单个字节值,复制缓冲区包括偏移量和字节值两部分,被拆解的字节值会分别存储到复制缓冲区中同时标记上偏移量。由于不同的slave之间存在数据传播的差异,因此master和slave都需要记录这个偏移量。
-
复制偏移量
-
数据同步与命令传播阶段工作流程:
- 全量复制详解:
首先slave发送psync2 <runid> <offset>
指令给master(此时slave还不知道master的服务器运行id,因此runid初始为?,offset初始为-1),接着master进行rdb持久化并协同+FULLRESYNC runid offset
一起发送给slave。在这期间master可能会接受客户端命令,offset进行移动变化。slave接收到了+FULLRESYNC
会保存master的runid和offset参数,同时清空全部数据恢复RDB 数据。 - 增量复制详解:
当slave再次发送psync2 runid offset
指令给master时,master会核对 runid和offset参数是否匹配。如果runid不满足或者offset溢出就执行全量复制;如果runid满足但是offset不相同(比方说slave突然掉线,而master端仍有命令进入,会造成master端的offset不断增长而slave端不变),master则会发送+CONTINUE offset
和复制缓冲区中相差的那段指令数据给slave。 slave接收到+CONTINUE
指令后保存新的 offset 然后执行bgrewriteaof
恢复数据。
- 全量复制详解:
-
心跳机制:
心跳机制是为了保证master和slave之间的连接能够不中断,方便数据稳定传输的。(注意它并没有包含在数据同步阶段中,而是在命令传播阶段)
slave 会发送 replconf ack offset
命令给master 来检测offset是否合理,接下来的操作和数据同步阶段相同。
为了保证命令传播阶段数据的高一致性,slave会不断发送 replconf ack offset
命令给master,同时master也会不断发送 ping
命令给slave来保证连接。
三、主从复制实例
实例:
复制三份配置文件,分别占用6379、6380、6381三个端口。
命令:
info replication :查询当前机器的身份状态
slaveof 主机ip 主机端口port :成为某台机器的从机
-
一主二仆:
·info replication:查看当前机器的角色·
* 如果主机宕机后,从机的身份不会改变,依旧原地待命。
* 如果主机回来后,主机依旧为主机,从机依旧为从机。
* 如果从机宕机后回来,从机的身份就变为了master,每次与master断开后,都需要重新连接,除非配置进redis.conf 文件
* 只有主机可以进行写,从机只能进行读
-
薪火相传(slave与master是相对的概念)
-
反客为主
slaveof no one :使当前数据库停止与其它数据库的同步,转换为主数据库
-
复制原理:
-
哨兵模式:
能够后台监控主机是否故障,如果故障了根据投票数自动将从库转化为主库。简单地说反客为主的自动版。- 如何配置:首先创建一个
sentinel.conf
文件,在该文件里面进行主机宕机后的配置sentinel monitor 被监控的主机数据库名字(自己起) 127.0.0.1 6379 1
。最后的一个1表示主机宕机后从机谁的票数多谁就成为主机。 - 哨兵启动:
redis-sentinel xxx.sentinel.conf
- 此时如果主机宕机回来后,就自动变为了从机。
- 一组sentinel能够同时监控多个Master
- 如何配置:首先创建一个
四、主从复制常见问题
- 频繁的全量复制(1)
- 频繁的全量复制(2)
- 频繁的网络中断(1)
- 频繁的网络中断(2)
- 数据不一致
五、主从复制的作用
- 读写分离: master写,slave读,提高服务器的读写负载能力;
- 负载均衡: 基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数量,通过多个从节点分担数据读取负载,大大提高Redis服务器并发量与吞吐量;
- 故障恢复:当master出现问题时,由slave来提供服务实现快速的故障恢复;
- 数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式;
- 高可用基石:基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案;