Redis 主从复制

观书散遗帙,探古穷至妙。这篇文章主要讲述Redis 主从复制相关的知识,希望能为你提供帮助。
Redis 主从复制

  • 虽然Redis可以实现单机的数据持久化,但无论是RDB也好或者AOF也好,都解决不了单点宕机问题,
    即一旦单台 redis服务器本身出现系统故障、硬件故障等问题后,就会直接造成数据的丢失
  • 此外,单机的性能也是有极限的,因此需要使用另外的技术来解决单点故障和性能扩展的问题。
2.1 Redis 主从复制
Redis 主从复制

文章图片

2.1.1 redis 主从复制架构
  • 主从模式(master/slave),可以实现Redis数据的跨主机备份。
  • 程序端连接到高可用负载的VIP,然后连接到负载服务器设置的Redis后端real server,此模式不需要在
    程序里面配 置Redis服务器的真实IP地址,当后期Redis服务器IP地址发生变更只需要更改redis 相应的
    后端real server即可, 可避免更改程序中的IP地址设置。
  • 主从复制特点
    • 一个master可以有多个slave
    • 一个slave只能有一个master
    • 数据流向是单向的,master到slave
2.1.2 redis主从复制实现
  • Redis Slave 也要开启持久化并设置和master同样的连接密码,因为后期slave会有提升为master的可
    能,Slave 端切换master同步后会丢失之前的所有数据,而通过持久化可以恢复数据一旦某个Slave成为一个master的slave,Redis Slave服务会清空当前redis服务器上的所有数据并将master的数据导入到自己的内存,但是如果只是断开同步关系后,则不会删除当前已经同步过的数据。
  • 当配置Redis复制功能时,强烈建议打开主服务器的持久化功能。否则的话,由于延迟等问题,部署的
    服务应该要避免自动启动。
  • 参考案例: 导致主从服务器数据全部丢失
1.假设节点A为主服务器,并且关闭了持久化。并且节点B和节点c从节点A复制数据 2.节点A崩溃,然后由自动拉起服务重启了节点A.由于节点A的持久化被关闭了,所以重启之后没有任何数据 3.节点B和节点c将从节点A复制数据,但是A的数据是空的,于是就把自身保存的数据副本删除。

  • 在关闭主服务器上的持久化,并同时开启自动拉起进程的情况下,即便使用Sentinel来实现Redis的高可
    用性,也是非常危险的。因为主服务器可能拉起得非常快,以至于Sentinel在配置的心跳时间间隔内没有检测到主服务器已被重启,然后还是会执行上面的数据丢失的流程。无论何时,数据安全都是极其重要的,所以应该禁止主服务器关闭持久化的同时自动启动。
2.1.2.1 命令行配置 2.1.2.1.1 启动主从同步
  • 默认redis 状态为master,需要转换为slave角色并指向master服务器的IP+PORT+Password
  • REPLICAOF MASTER_IP PORT 指令可以启用主从同步复制功能,早期版本使用 SLAVEOF 指令
127.0.0.1:6379> REPLICAOF MASTER_IP PORT 127.0.0.1:6379> CONFIG SET masterauth < masterpass>

#在mater上设置key1 [root@centos8 ~]#redis-cli 127.0.0.1:6379> AUTH 123456 OK 127.0.0.1:6379> INFO replication # Replication role:master connected_slaves:0 master_replid:a3504cab4d33e9723a7bc988ff8e022f6d9325bf master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6379> SET key1 v1-master OK 127.0.0.1:6379> KEYS * 1) "key1" 127.0.0.1:6379> GET key1 "v1-master" 127.0.0.1:6379> #以下都在slave上执行,登录 [root@centos8 ~]#redis-cli 127.0.0.1:6379> info NOAUTH Authentication required. 127.0.0.1:6379> AUTH 123456 OK 127.0.0.1:6379> INFO replication #查看当前角色默认为master # Replication role:master connected_slaves:0 master_replid:a3504cab4d33e9723a7bc988ff8e022f6d9325bf master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6379> SET key1 v1-slave-18 OK 127.0.0.1:6379> KEYS * 1) "key1" 127.0.0.1:6379> GET key1 "v1-slave-18" 127.0.0.1:6379> #在第二个slave,也设置相同的key1,但值不同 127.0.0.1:6379> KEYS * 1) "key1" 127.0.0.1:6379> GET key1 "v1-slave-28" 127.0.0.1:6379> 127.0.0.1:6379> INFO replication # Replication role:master connected_slaves:0 master_replid:a3504cab4d33e9723a7bc988ff8e022f6d9325bf master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6379> #在slave上设置master的IP和端口,4.0版之前的指令为slaveof 127.0.0.1:6379> REPLICAOF 10.0.0.8 6379 #仍可使用SLAVEOF MasterIP Port OK #在slave上设置master的密码,才可以同步 127.0.0.1:6379> CONFIG SET masterauth 123456 OK 127.0.0.1:6379> INFO replication # Replication #角色变为slave role:slave master_host:10.0.0.8 #指向master master_port:6379 master_link_status:up master_last_io_seconds_ago:8 master_sync_in_progress:0 slave_repl_offset:42 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:b69908f23236fb20b810d198f7f4539f795e0ee5 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:42 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:42 #查看已经同步成功 127.0.0.1:6379> GET key1 "v1-master"#在master上可以看到所有slave信息 127.0.0.1:6379> INFO replication # Replication role:master connected_slaves:2 slave0:ip=10.0.0.18,port=6379,state=online,offset=112,lag=1 #slave信息 slave1:ip=10.0.0.28,port=6379,state=online,offset=112,lag=1 master_replid:dc30f86c2d3c9029b6d07831ae3f27f8dbacac62 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:112 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:112 127.0.0.1:6379>

2.1.2.1.2 删除主从同步
  • REPLIATOF NO ONE 指令可以取消主从复制
#取消复制,在slave上执行REPLIATOF NO ONE,会断开和master的连接不再主从复制, 但不会清除slave 上已有的数据 127.0.0.1:6379> REPLICAOF no one

2.1.2.2 同步日志 2.1.2.2.1 在master 观看日志
[root@centos8 ~]#tail /var/log/redis/redis.log 24402:M 06 Oct 2020 09:09:16.448 * Replica 10.0.0.18:6379 asks for synchronization 24402:M 06 Oct 2020 09:09:16.448 * Full resync requested by replica 10.0.0.18:6379 24402:M 06 Oct 2020 09:09:16.448 * Starting BGSAVE for SYNC with target: disk 24402:M 06 Oct 2020 09:09:16.453 * Background saving started by pid 24507 24507:C 06 Oct 2020 09:09:16.454 * DB saved on disk 24507:C 06 Oct 2020 09:09:16.455 * RDB: 2 MB of memory used by copy-on-write 24402:M 06 Oct 2020 09:09:16.489 * Background saving terminated with success 24402:M 06 Oct 2020 09:09:16.490 * Synchronization with replica 10.0.0.18:6379 succeeded

2.1.2.2.1 在slave 观看日志
[root@centos8 ~]#tail -f /var/log/redis/redis.log 24395:S 06 Oct 2020 09:09:16.411 * Connecting to MASTER 10.0.0.8:6379 24395:S 06 Oct 2020 09:09:16.412 * MASTER < -> REPLICA sync started 24395:S 06 Oct 2020 09:09:16.412 * Non blocking connect for SYNC fired the event. 24395:S 06 Oct 2020 09:09:16.412 * Master replied to PING, replication can continue... 24395:S 06 Oct 2020 09:09:16.414 * Partial resynchronization not possible (no cached master) 24395:S 06 Oct 2020 09:09:16.419 * Full resync from master: 20ec2450b850782b6eeaed4a29a61a25b9a7f4da:0 24395:S 06 Oct 2020 09:09:16.456 * MASTER < -> REPLICA sync: receiving 196 bytes from master 24395:S 06 Oct 2020 09:09:16.456 * MASTER < -> REPLICA sync: Flushing old data 24395:S 06 Oct 2020 09:09:16.456 * MASTER < -> REPLICA sync: Loading DB in memory 24395:S 06 Oct 2020 09:09:16.457 * MASTER < -> REPLICA sync: Finished with success

2.1.2.3 修改slave配置文件
[root@centos8 ~]#vim /etc/redis.conf ....... # replicaof < masterip> < masterport> replicaof 10.0.0.8 6379 #指定master的IP和端口号 # If the master is password protected (using the "requirepass" configuration # directive below) it is possible to tell the replica to authenticate before # starting the replication synchronization process, otherwise the master will # refuse the replica request. # masterauth < master-password> masterauth 123456 #如果密码需要设置 ....... [root@centos8 ~]#systemctl restart redis

2.1.2.4 master和slave查看状态
#在master上查看状态 127.0.0.1:6379> info replication # Replication role:master connected_slaves:1 slave0:ip=10.0.0.18,port=6379,state=online,offset=1104403,lag=0 master_replid:b2517cd6cb3ad1508c516a38caed5b9d2d9a3e73 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1104403 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:55828 repl_backlog_histlen:1048576 127.0.0.1:6379> #在slave上查看状态 127.0.0.1:6379> get key1 #同步成功后,slave上的key信息丢失,从master复制过来新的值 "v1-master" 127.0.0.1:6379> INFO replication # Replication role:slave master_host:10.0.0.8 master_port:6379 master_link_status:up master_last_io_seconds_ago:6 master_sync_in_progress:0 slave_repl_offset:1104431 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:b2517cd6cb3ad1508c516a38caed5b9d2d9a3e73 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1104431 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:55856 repl_backlog_histlen:1048576 127.0.0.1:6379> #停止master的redis服务:systemctl stop redis,在slave上可以观察到以下现象 127.0.0.1:6379> INFO replication # Replication role:slave master_host:10.0.0.8 master_port:6379 master_link_status:down #显示down,表示无法连接master master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:1104529 master_link_down_since_seconds:4 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:b2517cd6cb3ad1508c516a38caed5b9d2d9a3e73 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1104529 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:55954 repl_backlog_histlen:1048576 127.0.0.1:6379>

2.1.2.5 slave 日志
[root@centos8 ~]#tail -f /var/log/redis/redis.log 24592:S 20 Feb 2020 12:03:58.792 * Connecting to MASTER 10.0.0.8:6379 24592:S 20 Feb 2020 12:03:58.792 * MASTER < -> REPLICA sync started 24592:S 20 Feb 2020 12:03:58.797 * Non blocking connect for SYNC fired the event. 24592:S 20 Feb 2020 12:03:58.797 * Master replied to PING, replication can continue... 24592:S 20 Feb 2020 12:03:58.798 * Partial resynchronization not possible (no cached master) 24592:S 20 Feb 2020 12:03:58.801 * Full resync from master: b69908f23236fb20b810d198f7f4539f795e0ee5:2440 24592:S 20 Feb 2020 12:03:58.863 * MASTER < -> REPLICA sync: receiving 213 bytes from master 24592:S 20 Feb 2020 12:03:58.863 * MASTER < -> REPLICA sync: Flushing old data 24592:S 20 Feb 2020 12:03:58.863 * MASTER < -> REPLICA sync: Loading DB in memory 24592:S 20 Feb 2020 12:03:58.863 * MASTER < -> REPLICA sync: Finished with success

2.1.2.6 master日志
[root@centos8 ~]#tail /var/log/redis/redis.log 11846:M 20 Feb 2020 12:11:35.171 * DB loaded from disk: 0.000 seconds 11846:M 20 Feb 2020 12:11:35.171 * Ready to accept connections 11846:M 20 Feb 2020 12:11:36.086 * Replica 10.0.0.18:6379 asks for synchronization 11846:M 20 Feb 2020 12:11:36.086 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for \'b69908f23236fb20b810d198f7f4539f795e0ee5\', my replication IDs are \'4bff970970c073c1f3d8e8ad20b1c1f126a5f31c\' and \'0000000000000000000000000000000000000000\') 11846:M 20 Feb 2020 12:11:36.086 * Starting BGSAVE for SYNC with target: disk 11846:M 20 Feb 2020 12:11:36.095 * Background saving started by pid 11850 11850:C 20 Feb 2020 12:11:36.121 * DB saved on disk 11850:C 20 Feb 2020 12:11:36.121 * RDB: 4 MB of memory used by copy-on-write 11846:M 20 Feb 2020 12:11:36.180 * Background saving terminated with success 11846:M 20 Feb 2020 12:11:36.180 * Synchronization with replica 10.0.0.18:6379 succeeded

2.1.2.7 slave 状态只读无法写入数据
127.0.0.1:6379> set key1 v1-slave (error) READONLY You can\'t write against a read only replica.

2.1.3 主从复制故障恢复 2.1.3.1 主从复制故障恢复过程介绍 2.1.3.1.1 slave 节点故障和恢复
  • Client指向另一个从节点即可,并及时修复故障从节点
2.1.3.1.2 master节点故障和恢复
  • 需要提升slave为新的master
  • master故障后,只能手动提升一个slave为新master,不支持自动切换。Master的切换会导致master_replid发生变化,slave之前的master_replid就和当前master不一致从而会引发所有 slave的全量同步。
2.1.3.2 主从复制故障恢复实现
  • 假设当前主节点10.0.0.8故障,提升10.0.0.18为新的master
#查看当前10.0.0.18节点的状态为slave,master指向10.0.0.8 127.0.0.1:6379> INFO replication # Replication role:slave master_host:10.0.0.8 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:3794 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:8e8279e461fdf0f1a3464ef768675149ad4b54a3 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:3794 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:3781 repl_backlog_histlen:14 127.0.0.1:6379>

停止slave同步并提升为新的master
#提升为master角色 127.0.0.1:6379> REPLICAOF NO ONE #旧版使用SLAVEOF no one OK (5.04s) 127.0.0.1:6379> info replication # Replication role:master connected_slaves:0 master_replid:94901d6b8ff812ec4a4b3ac6bb33faa11e55c274 master_replid2:0083e5a9c96aa4f2196934e10b910937d82b4e19 master_repl_offset:3514 second_repl_offset:3515 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:3431 repl_backlog_histlen:84 127.0.0.1:6379>

测试能否写入数据:
127.0.0.1:6379> set keytest1 vtest1 OK

修改所有slave 指向新的master节点
#修改10.0.0.28节点指向新的master节点10.0.0.18 127.0.0.1:6379> SLAVEOF 10.0.0.8 6379 OK 127.0.0.1:6379> set key100 v100 (error) READONLY You can\'t write against a read only replica. #查看日志 [root@centos8 ~]#tail -f /var/log/redis/redis.log 1762:S 20 Feb 2020 13:28:21.943 # Connection with master lost. 1762:S 20 Feb 2020 13:28:21.943 * Caching the disconnected master state. 1762:S 20 Feb 2020 13:28:21.943 * REPLICAOF 10.0.0.18:6379 enabled (user request from \'id=5 addr=127.0.0.1:59668 fd=9 name= age=149 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=41 qbuf-free=32727 obl=0 oll=0 omem=0 events=r cmd=slaveof\') 1762:S 20 Feb 2020 13:28:21.966 * Connecting to MASTER 10.0.0.18:6379 1762:S 20 Feb 2020 13:28:21.966 * MASTER < -> REPLICA sync started 1762:S 20 Feb 2020 13:28:21.967 * Non blocking connect for SYNC fired the event. 1762:S 20 Feb 2020 13:28:21.968 * Master replied to PING, replication can continue... 1762:S 20 Feb 2020 13:28:21.968 * Trying a partial resynchronization (request 8e8279e461fdf0f1a3464ef768675149ad4b54a3:3991). 1762:S 20 Feb 2020 13:28:21.969 * Successful partial resynchronization with master. 1762:S 20 Feb 2020 13:28:21.969 * MASTER < -> REPLICA sync: Master accepted a Partial Resynchronization.

在新master可看到slave
#在新master节点10.0.0.18上查看状态 127.0.0.1:6379> INFO replication # Replication role:master connected_slaves:1 slave0:ip=10.0.0.28,port=6379,state=online,offset=4606,lag=0 master_replid:8e8279e461fdf0f1a3464ef768675149ad4b54a3 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:4606 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:4606 127.0.0.1:6379>

2.1.4 redis 级联复制即实现基于Slave节点的Slave
master和slave1节点无需修改,只需要修改slave2及slave3指向slave1做为mater即可
#在slave2和slave3上执行下面指令 127.0.0.1:6379> REPLICAOF 10.0.0.18 6379 OK 127.0.0.1:6379> CONFIG SET masterauth 123456

在 master 设置key,观察是否同步
#在master新建key 127.0.0.1:6379> set key2 v2 OK 127.0.0.1:6379> get key2 "v2" #在slave1和slave2验证key 127.0.0.1:6379> get key2 "v2" #在slave1和slave2都无法新建key 127.0.0.1:6379> set key3 v3 (error) READONLY You can\'t write against a read only replica.

在中间那个slave查看状态
127.0.0.1:6379> INFO replication # Replication role:slave master_host:10.0.0.8 master_port:6379 master_link_status:up master_last_io_seconds_ago:8 #最近一次与master通信已经过去多少秒。 master_sync_in_progress:0 #是否正在与master通信。 slave_repl_offset:4312 #当前同步的偏移量 slave_priority:100 #slave优先级,master故障后值越小越优先同步。 slave_read_only:1 connected_slaves:1 slave0:ip=10.0.0.28,port=6379,state=online,offset=4312,lag=0 #slave的slave节点 master_replid:8e8279e461fdf0f1a3464ef768675149ad4b54a3 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:4312 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:4312

2.1.5 redis 主从复制优化 2.1.5.1 主从复制过程Redis主从复制分为全量同步和增量同步
2.1.5.1.1 全量复制过程
Redis 主从复制

文章图片

  • 同步是全量同步,主从同步可以让从服务器从主服务器同步数据,而且从服务器还可再有其它的从
    服务器,即另外一台redis服务器可以从一台从服务器进行数据同步,redis 的主从同步是非阻塞的,
    master收到从服务器的psync(2.8版本之前是SYNC)命令,会fork一个子进程在后台执行bgsave命令,并
    将新写入的数据写入到一个缓冲区中,bgsave执行完成之后,将生成的RDB文件发送给slave,然后
    master再将缓冲区的内容以redis协议格式再全部发送给slave,slave 先删除旧数据,slave将收到后的
    RDB文件载入自己的内存,再加载所有收到缓冲区的内容 从而这样一次完整的数据同步
  • Redis全量复制一般发生在Slave首次初始化阶段,这时Slave需要将Master上的所有数据都复制一份。
2.1.5.1.2 增量复制过程
Redis 主从复制

文章图片

  • 全量同步之后再次需要同步时,从服务器只要发送当前的offset位置(等同于mysql的binlog的位置)给主
    服务器,然后主服务器根据相应的位置将之后的数据(包括写在缓冲区的积压数据)发送给从服务器,再次
    其保存到其内存即可。
2.1.5.1.3 主从同步完整过程具体主从同步过程如下:
1)从服务器连接主服务器,发送PSYNC命令 2)主服务器接收到PSYNC命令后,开始执行BGSAVE命令生成RDB快照文件并使用缓冲区记录此后执行的所有 写命令 3)主服务器BGSAVE执行完后,向所有从服务器发送RDB快照文件,并在发送期间继续记录被执行的写命令 4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照至内存 5)主服务器快照发送完毕后,开始向从服务器发送缓冲区中的写命令 6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令 7)后期同步会先发送自己slave_repl_offset位置,只同步新增加的数据,不再全量同步

【Redis 主从复制】
Redis 主从复制

文章图片

Redis 主从复制

文章图片

  • 复制缓冲区(环形队列)配置参数
#复制缓冲区大小,建议要设置足够大 repl-backlog-size 1mb#Redis同时也提供了当没有slave需要同步的时候,多久可以释放环形队列: repl-backlog-ttl 3600

2.1.5.1.4 避免全量复制
  • 第一次全量复制不可避免,后续的全量复制可以利用小主节点(内存小),业务低峰时进行全量
  • 节点运行ID不匹配:主节点重启会导致RUNID变化,可能会触发全量复制,可以利用故障转移,例如哨
    兵或集群,而从节点重启动,不会导致全量复制
  • 复制积压缓冲区不足: 当主节点生成的新数据大于缓冲区大小,从节点恢复和主节点连接后,会导致
    全量复制.解决方法将repl-backlog-size 调大
2.1.5.1.5避免复制风暴
  • 单主节点复制风暴
  • 当主节点重启,多从节点复制
  • 解决方法:更换复制拓扑
Redis 主从复制

文章图片

  • 单机器复制风暴
    • 机器宕机后,大量全量复制
  • 解决方法:主节点分散多机器
Redis 主从复制

文章图片

2.1.5.2 主从同步优化配置Redis在2.8版本之前没有提供增量部分复制的功能,当网络闪断或者slave Redis重启之后会导致主从之
间的全量同 步,即从2.8版本开始增加了部分复制的功能。
  • 性能相关配置
repl-diskless-sync no # 是否使用无盘同步RDB文件,默认为no,no为不使用无盘,需要将RDB文件 保存到磁盘后再发送给slave,yes为支持无盘,支持无盘就是RDB文件不需要保存至本地磁盘,而且直接通 过socket文件发送给slave repl-diskless-sync-delay 5 #diskless时复制的服务器等待的延迟时间 repl-ping-slave-period 10 #slave端向server端发送ping的时间间隔,默认为10秒 repl-timeout 60 #设置主从ping连接超时时间,超过此值无法连接,master_link_status显示为 down,并记录错误日志 repl-disable-tcp-nodelay no #是否启用TCP_NODELAY,如设置成yes,则redis会合并小的TCP包 从而节省带宽, 但会增加同步延迟(40ms),造成master与slave数据不一致,假如设置成no,则redis master会立即发送同步数据,没有延迟,yes关注性能,no关注redis服务中的数据一致性 repl-backlog-size 1mb #master的写入数据缓冲区,用于记录自上一次同步后到下一次同步过程中间 的写入命令,计算公式:repl-backlog-size = 允许从节点最大中断时长 * 主实例offset每秒写入 量,比如master每秒最大写入64mb,最大允许60秒,那么就要设置为64mb*60秒=3840MB(3.8G),建议此 值是设置的足够大 repl-backlog-ttl 3600 #如果一段时间后没有slave连接到master,则backlog size的内存将会被 释放。如果值为0则 表示永远不释放这部份内存。 slave-priority 100 #slave端的优先级设置,值是一个整数,数字越小表示优先级越高。当master故 障时将会按照优先级来选择slave端进行恢复,如果值设置为0,则表示该slave永远不会被选择。 min-replicas-to-write 1 #设置一个master的可用slave不能少于多少个,否则master无法执行写 min-slaves-max-lag 20 #设置至少有上面数量的slave延迟时间都大于多少秒时,master不接收写操 作(拒绝写入)

2.1.6 常见主从复制故障汇总 2.1.6.1 master 密码不对
  • 即配置的master密码不对,导致验证不通过而无法建立主从同步关系。
[root@centos8 ~]#tail -f /var/log/redis/redis.log 24930:S 20 Feb 2020 13:53:57.029 * Connecting to MASTER 10.0.0.8:6379 24930:S 20 Feb 2020 13:53:57.030 * MASTER < -> REPLICA sync started 24930:S 20 Feb 2020 13:53:57.030 * Non blocking connect for SYNC fired the event. 24930:S 20 Feb 2020 13:53:57.030 * Master replied to PING, replication can continue... 24930:S 20 Feb 2020 13:53:57.031 # Unable to AUTH to MASTER: -ERR invalid password

2.1.6.2 Redis版本不一致
  • 不同的redis 大版本之间存在兼容性问题,比如:3和4,4和5之间,因此各master和slave之间必须保
    持版本一致
Redis 主从复制

文章图片
Redis 主从复制

文章图片

2.1.6.3 无法远程连接在开启了安全模式情况下,没有设置bind地址或者密码
[root@centos8 ~]#vim /etc/redis.conf #bind 127.0.0.1 #将此行注释 [root@centos8 ~]#systemctl restart redis [root@centos8 ~]#ss -ntl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 100 127.0.0.1:25 0.0.0.0:* LISTEN 0 128 0.0.0.0:6379 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* LISTEN 0 100 [::1]:25 [::]:* LISTEN 0 128 [::]:6379 [::]:* [root@centos8 ~]#redis-cli -h 10.0.0.8 10.0.0.8:6379> KEYS * (error) DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command \'CONFIG SET protected-mode no\' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to \'no\', and then restarting the server. 3) If you started the server manually just for testing, restart it with the \'--protected-mode no\' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside. 10.0.0.38:6379> exit #可以本机登录 [root@centos8 ~]#redis-cli 127.0.0.1:6379> KEYS * (empty list or set)

2.1.6.4 配置不一致
  • 节点的maxmemory不一致,主节点内存大于从节点内存,主从复制可能丢失数据
  • rename-command 命令不一致,如在主节点定义了lfushall,flushdb,从节点没定义,结果执行flushdb,不
    同步
#master有一个rename-command flushdb "magedu",而slave没有这个配置,则同步时从节点可以看到 以下同步错误 3181:S 21 Oct 2020 17:34:50.581 # == CRITICAL == This replica is sending an error to its master: \'unknown command `magedu`, with args beginning with: \' after processing the command \'< unknown> \'


    推荐阅读