Redis使用的是master-slave主从复制模式,从2.8版本开始,这个过程是异步的。
1. 工作原理
当一个slave首次或重新连接到master的时候,会向master发送一个PSYNC命令(2.8版本之前是SYNC命令)要求同步数据。
1.1 全量同步 Full resynchronization
当master接收到slave的同步命令之后会执行BGSAVE启动一个background进程创建.rdb持久化文件,同时会将所有新执行的写入命令都保存到一个缓冲区里面。当.rdb保存完毕之后,master会把.rdb文件传送给slave,然后slave会把保存的.rdb文件load到内存里面,最后master会将缓冲区里面的所有写命令发送给slave。如果master接收到多个slave的同步请求,master只会执行一次BGSAVE命令,然后把保存的.rdb文件同时传送给所有的slave(占用较多的资源和带宽)。当master-slave的连接由于某种原因断开时,slave会自动重新连接。在2.8版本之前,断线后的重新连接是会执行全量同步,在2.8版本开始,slave是可以根据master的情况来自动选择执行全量同步还是增量同步(partial resynchronization)。
1.2 增量同步 Partial resynchronization
从2.8版本开始,Redis在master端创建了一个复制流的内存缓冲区,master和所有slave都标记一个复制的偏移量和master runid,用于当master-slave连接短暂断开然后重新连接的时候,master和slave可以执行增量同步,也就是从之前断开的部分开始同步,而不需要执行全量同步。前提条件是master runid和之前是相同的,并且标记的复制偏移量仍然在复制流的内存缓冲区里面,否则的话会执行全量同步。这种新的增量同步特性会使用PSYNC命令,而2.8版本之前会使用SYNC命令。值得注意的是,如果slave是2.8或以上的版本能够检测master是否支持PSYNC命令,如果不支持会自动使用SYNC命令。
2. 无盘复制 Diskless replication
从2.8.18版本开始支持无盘复制,master以流的方式直接传送数据给slave,不需要创建.rdb文件,slave接收数据后仍然会保存.rdb文件然后load到内存里面。这种选项的优点就是避免master的磁盘读写慢导致的性能问题。
3. Replication的配置
Redis的复制有3种配置方式:
3.1 在slave的配置文件redis.conf里面添加slaveof <masterip> <masterport>,masterip是master的ip,masterport是master的端口
3.2 在使用redis-server启动slave的时候,直接添加--slaveof <masterip> <masterport>参数(非配置文件启动方式)
3.3 使用redis-cli连接slave,然后执行slaveof <masterip> <masterport>命令
4. slave端的相关配置
slave-read-only yes #从2.6版本开始支持只读的slave,默认是yes的
masterauth <master-password> #如果master配置了requirepass设置密码,slave需要配置连接master的密码
slave-serve-stale-data yes #当slave与master断开或者复制正在进行的时候是否继续提供服务,默认是yes继续服务,可以配置为no返回错误提示“SYNC with master in progress”(除了INFO和SLAVEOF命令)
repl-ping-slave-period 10 #slave发送心跳的间隔时间,默认是10秒
5. master端的相关配置
repl-diskless-sync no #是否使用无盘复制 Diskless replication,默认是no
repl-diskless-sync-delay 5 #无盘复制延时开始秒数,默认是5秒,意思是当PSYNC触发的时候,master延时多少秒开始向master传送数据流,以便等待更多的slave连接可以同时传送数据流,因为一旦PSYNC开始后,如果有新的slave连接master,只能等待下次PSYNC。可以配置为0取消等待,立即开始
repl-backlog-size 1mb #复制流的内存缓冲区大小,用于增量同步,当master-slave断开的时候,master保存在复制流内存缓冲区的数据大小限制,默认是1mb。如果至少有1个slave连接的话,就会释放
repl-backlog-ttl 3600 #复制流的内存缓冲区过时时间,默认3600秒,就是说无论保存在复制流内存缓冲区的数据大小是否超过限制,当master-slave断开超过上述时间就会释放
min-slaves-to-write 3 #从2.8版本开始,可以配置与master连接的slave的最少数量,默认是0没有限制,如果配置>0,需要结合下面的选项一起使用,只有同时满足这2个选项,master才能接收写操作
1. 工作原理
当一个slave首次或重新连接到master的时候,会向master发送一个PSYNC命令(2.8版本之前是SYNC命令)要求同步数据。
1.1 全量同步 Full resynchronization
当master接收到slave的同步命令之后会执行BGSAVE启动一个background进程创建.rdb持久化文件,同时会将所有新执行的写入命令都保存到一个缓冲区里面。当.rdb保存完毕之后,master会把.rdb文件传送给slave,然后slave会把保存的.rdb文件load到内存里面,最后master会将缓冲区里面的所有写命令发送给slave。如果master接收到多个slave的同步请求,master只会执行一次BGSAVE命令,然后把保存的.rdb文件同时传送给所有的slave(占用较多的资源和带宽)。当master-slave的连接由于某种原因断开时,slave会自动重新连接。在2.8版本之前,断线后的重新连接是会执行全量同步,在2.8版本开始,slave是可以根据master的情况来自动选择执行全量同步还是增量同步(partial resynchronization)。
1.2 增量同步 Partial resynchronization
从2.8版本开始,Redis在master端创建了一个复制流的内存缓冲区,master和所有slave都标记一个复制的偏移量和master runid,用于当master-slave连接短暂断开然后重新连接的时候,master和slave可以执行增量同步,也就是从之前断开的部分开始同步,而不需要执行全量同步。前提条件是master runid和之前是相同的,并且标记的复制偏移量仍然在复制流的内存缓冲区里面,否则的话会执行全量同步。这种新的增量同步特性会使用PSYNC命令,而2.8版本之前会使用SYNC命令。值得注意的是,如果slave是2.8或以上的版本能够检测master是否支持PSYNC命令,如果不支持会自动使用SYNC命令。
2. 无盘复制 Diskless replication
从2.8.18版本开始支持无盘复制,master以流的方式直接传送数据给slave,不需要创建.rdb文件,slave接收数据后仍然会保存.rdb文件然后load到内存里面。这种选项的优点就是避免master的磁盘读写慢导致的性能问题。
3. Replication的配置
Redis的复制有3种配置方式:
3.1 在slave的配置文件redis.conf里面添加slaveof <masterip> <masterport>,masterip是master的ip,masterport是master的端口
3.2 在使用redis-server启动slave的时候,直接添加--slaveof <masterip> <masterport>参数(非配置文件启动方式)
3.3 使用redis-cli连接slave,然后执行slaveof <masterip> <masterport>命令
4. slave端的相关配置
slave-read-only yes #从2.6版本开始支持只读的slave,默认是yes的
masterauth <master-password> #如果master配置了requirepass设置密码,slave需要配置连接master的密码
slave-serve-stale-data yes #当slave与master断开或者复制正在进行的时候是否继续提供服务,默认是yes继续服务,可以配置为no返回错误提示“SYNC with master in progress”(除了INFO和SLAVEOF命令)
repl-ping-slave-period 10 #slave发送心跳的间隔时间,默认是10秒
5. master端的相关配置
repl-diskless-sync no #是否使用无盘复制 Diskless replication,默认是no
repl-diskless-sync-delay 5 #无盘复制延时开始秒数,默认是5秒,意思是当PSYNC触发的时候,master延时多少秒开始向master传送数据流,以便等待更多的slave连接可以同时传送数据流,因为一旦PSYNC开始后,如果有新的slave连接master,只能等待下次PSYNC。可以配置为0取消等待,立即开始
repl-backlog-size 1mb #复制流的内存缓冲区大小,用于增量同步,当master-slave断开的时候,master保存在复制流内存缓冲区的数据大小限制,默认是1mb。如果至少有1个slave连接的话,就会释放
repl-backlog-ttl 3600 #复制流的内存缓冲区过时时间,默认3600秒,就是说无论保存在复制流内存缓冲区的数据大小是否超过限制,当master-slave断开超过上述时间就会释放
min-slaves-to-write 3 #从2.8版本开始,可以配置与master连接的slave的最少数量,默认是0没有限制,如果配置>0,需要结合下面的选项一起使用,只有同时满足这2个选项,master才能接收写操作
min-slaves-max-lag 10 #允许master-slave的心跳最大间隔,默认是10秒,需要结合min-slaves-to-write选项一起使用
6. 复制+持久化的数据完整性考虑
如果master配置了slave,那么强烈建议master启用持久化。因为当master重启的时候,如果没有启用持久化,数据会全部丢失,而且当slave重新连接master的时候,slave原有的数据也会被清空。如果真的要配置不启用持久化,最好不要设置自动启动master,除非数据全部丢失对你来说不重要。