前言
redis提供了一个简单易用的主从(master-replica)复制: 它允许 Redis 副本实例成为主实例的精确副本。每次链接中断时,slave都会自动重新连接到master,并且不管master发生什么情况,都会尝试成为它的一个精确副本。运作机制
该系统通过三种主要机制运作:
- 当一个master和一个slave实例连接正常时,master通过向副本发送一系列命令来保持slave副本更新,以便在master中复制由客户的写入、键过期、移除或任何其他操作改变master而对数据集产生的影响。(数据同步)
- 由于网络问题,或者由于master与slave副本连接超时,导致master与slave之间的链接中断时,slave副本将重新连接并尝试进行部分重新同步: 这意味着它将尝试获取在断开连接期间错过的命令流的一部分。(故障重连、数据校正)
- 当部分重新同步不可能时,slave副本将要求完全重新同步。这将涉及一个更复杂的过程,其中master需要创建所有数据的快照,将其发送到slave,然后随着数据集的更改继续发送命令流。(数据重建)
主从复制特点
以下是关于 Redis 主从复制的一些非常重要的特点:
- Redis 使用异步复制,slave异步处理确认自己每次复制的数据量。
- 一个主机master可以有多个副本slave。
- slave可以接受来自其他slave的连接。除了将许多slave连接到同一个master之外,slave还可以连接到级联结构中的其他slave。
- Redis 主从复制在master是非阻塞的。这意味着当一个或多个slave执行初始同步或部分重新同步时,master将继续处理查询。
- slave 在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了
- 主从复制既可用于可伸缩性,以便有多个slave用于只读查询,也可用于提高数据安全性和高可用性。
安全性问题
master关闭持久化给主从复制带来安全性问题
在使用 Redis 复制的设置中,强烈建议在master和slave中打开持久性。
故障演示
- 假设我们有一个设置,节点 a 充当master,关闭持久性,节点 b 和 c 作为slave。
- master节点a因为意外崩溃,但是它有一些自动重启系统,可以重新启动进程。但是,由于持久性被关闭,master将以一个空数据集重新启动。
- 节点 b 和 c 将从空的节点 a 进行复制,复制得到是一个空数据集。
redis主从复制原理
每个 Redis master都有一个Replication ID: 它是一个大的伪随机字符串,标记数据集的给定参数。每个maseter还接受一个offset偏移量,每生成一个复制流的每个字节都增加一个偏移量,这个偏移量将被发送到slave,以便通过修改数据集的新更改更新slave的状态。即使没有slave实际连接,复制偏移量也会递增,所以基本上每一对:Replication ID, offset是标识master数据集的精确版本。
当slave连接到master时,它们使用 PSYNC 命令来发送旧的master Replication ID和到目前为止处理的offset。这样master就可以发送所需的增量部分。但是,如果master的缓冲区中没有足够的积压工作,或者副本引用的是不再知道的历史记录(Replication ID) ,那么就会发生完全重新同步: 在这种情况下,slave将从头开始获得数据集的完整副本。
下面是完全同步在更多细节中的工作原理:
master启动后台保存进程,以生成 RDB 文件。同时,它开始缓冲从客户机接收的所有新的写命令。当后台保存完成后,master将数据库文件传输到slave,slave将其保存在磁盘上,然后将其加载到内存中。然后,master将向slave发送所有缓冲命令。这是以命令流的形式完成的,与 Redis 协议本身的格式相同。
相关配置(基于redis5)
配置基本 Redis 主从同步非常简单: 只需在slave配置文件中添加以下代码行:
replicaof <IP> <Port>
在运行状态中的slave上也可以在redis命令行中直接执行这个命令
如果master通过 requirepass 获得了密码,那么将slave需要配置相同的密码
运行中的slave们可以在命令行中使用以下命令
config set masterauth <password>
永久生效可以在配置文件中如下配置
masterauth <password>
主从复制状态可以使用以下命令查看
info replication
异常情况
1、master宕机
此情况下,slave会保持对外只读服务,查看其replication状态,可以看到master已经down,该节点可读不可写
但是因为master无法工作,整个redis 无法写入。
此时有两种操作:
a、尽快恢复master服务。(注意,如果master没有进行持久化配置,服务恢复后,其为空数据,可能回到着链接着他的slave数据被同步为空)
b、 将slave切换为master
如果故障的master短时间内无法恢复,则考虑将slave上位成为master
关闭slave上的主从关系
replicaof no one
此时查看从的replication信息可以看到,原有数据不受影响,角色变为master
同样的其他slave设置为归属于新的master即可。
2 slave宕机
除了宕机的slave,对整个redis主从没有影响。
题外话
之前版本的redis中,一直都是用slaveof命令而不是replicaof,归根结底还是“zzzq”,呵呵