Redis的主从复制架构
Posted y_zilong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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在配置的心跳时间间隔内没有检测到主服务器已被重启,然
后还是会执行上面的数据丢失的流程。无论何时,数据安全都是极其重要的,所以应该禁止主服务器关
闭持久化的同时自动启动。
1、命令行配置
启用主从同步
默认redis状态为master,需要转换为slave角色并指向master服务器的IP+PORT+PASSWORD
PRELICAOF MASTER_IP PORT 指令可以启用主从同步复制功能
#在master上设置key1
[root@cent8_yzl_10 ~]# redis-cli -a 123456
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:6a7a3fbbc7c3e272d405898cabbb2eb532d69568
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> get key1
"v1-master"
127.0.0.1:6379>
#以下都在slave上执行,登录
[root@cent8_yzl_20 ~]# redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:e290abfe9ae9f79c69ff745d057dc612736c5899
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-20
OK
127.0.0.1:6379> get key1
"v1-slave-20"
127.0.0.1:6379>
#slave-30
[root@cent8_yzl_30 ~]# redis-cli -a 123456
127.0.0.1:6379> set key1 v2-slave-30
OK
127.0.0.1:6379> get key1
"v2-slave-30"
127.0.0.1:6379>
#在slave上设置master的IP和PORT
127.0.0.1:6379> replicaof 10.0.0.10 6379
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.10 #指向master
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:14
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:1f522fbcc6c181aa14717057a22f9fe532b50751
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
#查看已经同步成功
127.0.0.1:6379> get key1
"v1-master"
127.0.0.1:6379>
#在master上可以看到所有slave
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.0.0.20,port=6379,state=online,offset=322,lag=1 #slave信息
slave1:ip=10.0.0.30,port=6379,state=online,offset=322,lag=1
master_failover_state:no-failover
master_replid:1f522fbcc6c181aa14717057a22f9fe532b50751
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:322
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:322
127.0.0.1:6379>
删除主从同步
REPLICAOF NO ONE指令可以取消主从复制
#取消复制,在slave上执行replicaof no one,会断开和master的连接不再主从复制,但不会清除slave上已有的数据
127.0.0.1:6379> replicaof no one
OK
127.0.0.1:6379> get key1
"v1-master"
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:1c68ff8bd04f3b2ef87a6140e38e65172646a62c
master_replid2:1f522fbcc6c181aa14717057a22f9fe532b50751
master_repl_offset:672
second_repl_offset:673
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:672
127.0.0.1:6379>
2、配置文件修改redis主从复制
主节点:
[root@cent8_yzl_10 ~]# vim /apps/redis/etc/redis.conf
bind 0.0.0.0
masterauth 123456
requirepass 123456
从节点:
[root@cent8_yzl_20 ~]#vim /apps/redis/etc/redis.conf
bind 0.0.0.0
masterauth 123456
requirepass 123456
replicaof 10.0.0.10 6379
#或者非交互执行
[root@cent8_yzl_20 ~]# sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /apps/redis/etc/redis.conf
#只在slave节点上执行这一句
[root@cent8_yzl_20 ~]# echo "replicaof 10.0.0.10 6379" >> /apps/redis/etc/redis.conf
3、实现redis的级联复制
master和slave1节点无需修改,只需要修改slave2指向slave1做为mater即可
127.0.0.1:6379> replicaof 10.0.0.20 6379 #把slave1指向master指向10.0.0.20
OK
127.0.0.1:6379> config set masterauth 123456
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.20
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:364
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:a9574022a359f05c706fbbb1af6aa5f819b906de
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:364
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:364
127.0.0.1:6379>
#在slave1上无法创建key,因为必须和第一个master数据相同
#在master 10上
127.0.0.1:6379> set key3 k3
OK
127.0.0.1:6379> get key3
"k3"
127.0.0.1:6379>
#slave30上查看
127.0.0.1:6379> get key3
"k3"
127.0.0.1:6379>
在中间那个slave查看状态
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10 #最近一次与master通信已经过去多少秒
master_sync_in_progress:0 #是否正在与master通信
slave_repl_offset:796 #当前同步的偏移量
slave_priority:100 #slave优先级,master故障后值越小越优先同步
slave_read_only:1
replica_announced:1
connected_slaves:1
slave0:ip=10.0.0.30,port=6379,state=online,offset=796,lag=1
master_failover_state:no-failover
master_replid:a9574022a359f05c706fbbb1af6aa5f819b906de
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:796
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:796
127.0.0.1:6379>
4、主从复制的优化
具体主从同步过程如下:
1、从服务器连接主服务器,发送psync命令
2、主服务器接收到psync命令后,开始执行bgsave命令生成rdb快照文件并使用缓冲区记录此后执行的所有写命令
3、主服务器bgsave执行完后,向所有从服务器发送rdb快照文件,并在发送期间继续记录被执行的写命令
4、从服务器收到快照文件后丢弃所有旧数据,载入收到的快照至内存
5、主服务器快照发送完毕后,开始向从服务器发送缓冲区中的写命令
6、从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令
7、后期同步会先发送主机slave_repl_offset位置,只同步新增加的数据,不再全量同步
#复制缓冲区(环形队列)配置参数:
#复制缓冲区大小,建议要设置足够大
repl-backlog-size 100m #master的写入数据缓冲区,用于记录自上一次同步后到下一次同步过程中间的写入命令,计算公式:repl-backlog-size = 允许从节点最大中断时长 * 主实例offset每秒写入量,比如master每秒最大写入64mb,最大允许60秒,那么就要设置为64mb*60秒=3840MB(3.8G),建议此值是设置的足够大#redis同时也提供了当没有slave需要同步的时候,多久可以释放环形队列:
repl-backlog-ttl 3600 #如果一段时间后没有slave连接到master,则backlog size的内存将会被释放。如果值为0则 表示永远不释放这部份内存
以上是关于Redis的主从复制架构的主要内容,如果未能解决你的问题,请参考以下文章
NoSQL初探之人人都爱Redis:Redis主从复制架构初步探索