主从复制原理:
- 当建立了一个从服务器时,从服务器都将向主服务器发送一个SYNC命令。
- 接收到SYNC命令的主服务器会做两件事:
(1) 执行BGSAVE命令,即在后台保存数据到磁盘(rdb快照文件)
(2) 同时将新收到的写入和修改数据集的命令存入缓冲区(非查询类) - 当master在后台把数据保存到快照文件完成之后,master会把这个快照文件传送给slave,而slave则把内存清空后,加载该文件到内存中。
- 而master也会把此前收集到缓冲区中的命令,通过redis命令协议形式转发给slave,slave执行这些命令,实现和master的同步。
- master/slave此后会不断通过异步方式进行命令的同步,达到最终数据的一致
- 每一次重连都需要重新同步一遍,过于消耗资源。于是2.8版本后,出现类似断点重连的操作(也称 部分重同步)。
这里引用下大佬画的图,很清晰明了的流程:
部分重同步:
2.8版本以后,当master和slave连接断开后,他们之间可以采用持续复制处理方式代替采用全量同步。
master为复制流维护一个内存缓冲区in-memory backlog
,记录最近改善的复制命令;同时,master和slave之间都维护一个复制偏移量(replication offset)和当前master服务器ID,当网络断开后,slave尝试重连时:
(1) 如果masterID相同,并且从断开时到当前时刻的历史命令依然在master的内存缓冲区中存在,则master会将缺失的这段时间内的所有命令发送给slave执行,然后复制工件就可以继续执行了。
(2) 如果masterID对应上但replication offset都对应不上,那就需要全量复制操作。
部分重同步,可修改repl-backlog-size
的值进行调整,(redis负载压力相同的情况下)值越大允许网络断开的时间就越长,越小时间就越小。
推荐博文:https://blog.csdn.net/Stubborn_Cow/article/details/50442950
环境准备(搭建主从):
ip | hostname | service |
---|---|---|
192.168.20.3 | node2003 | redis-master |
192.168.20.4 | node2004 | redis-slave |
特点:
- 一个master可以有多个slave主机,支持链式复制
- master以非阻塞方式同步数据至slave主机
node2003
redis的安装这里就不演示和说明,我这里直接使用yum安装。
redis-master使用默认配置文件,只需要额外配置requirepass
认证密码。
~]# cat /etc/redis.conf | grep "^[^#]" //查看配置项,具体配置说明请查看之前博文
bind 192.168.20.3
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize systemd
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync Disk-backend
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
requirepass foo
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
...
~]# systemctl start redis //启动服务
~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 192.168.20.3:6379 *:*
...
node2004
从节点可以配置文件(持久)中配置主节点相关信息,也可直接在命令中设置(重启后丢失)。
~]# cat /etc/redis.conf | grep "^[^#]"
bind 192.168.20.4
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised systemd
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slaveof 192.168.20.3 6379 //配置主节点IP地址和端口
masterauth foo //配置master连接密码
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
也可在命令中配置,如下命令:
redis-cli> SLAVEOF <MASTER_IP> <MASTER_PORT>
redis-cli> CONFIG SET masterauth <PASSWORD>
~]# redis-cli -h 192.168.20.4 -p 6379
192.168.20.4:6379> SLAVEOF 192.168.20.3 6379
OK Already connected to specified master
192.168.20.4:6379> CONFIG SET masterauth foo
OK
测试主从效果:
node2003:
~]# redis-cli -h 192.168.20.3 -p 6379
192.168.20.3:6379> SET xue xi
(error) NOAUTH Authentication required.
192.168.20.3:6379> AUTH foo
OK
192.168.20.3:6379> set xue xi
OK
node2004:
~]# redis-cli -h 192.168.20.4 -p 6379
192.168.20.4:6379> get xue
"xi" //同步已经完成