redis主从复制
Redis主从结构
一主一从结构
一主一从结构是Redis最简单的渎职结构,用于主节点出现宕机是从节点提供故障转移支持。当应用写命令并发量较高且需要之九华是,可以只从节点开启AOF
避免了持久化对主节点的性能压力,也保证了数据的安全性
树状主从结构
树状结构(级联结构)可以使节点不但复制节点复制,同时还可以从其他的主节点接着复制,当主节点需要挂载多个节点是为了避免对主节点的性能干扰
主从复制原理
复制流程
-
保存主节点信息
-
主从建立socket连接
-
发送ping命令
-
权限验证
-
同步数据集
-
命令持续复制
复制类型
-
全量复制:用于初次复制的场景,把主节点全部数据一次性发送给从节点,,因为数据量较大,所以会对主节点和网络早成很大的开销
-
部分复制:用于处理在主从复制中因为一些原因导致的数据中断,主节点会补发丢失的数据给从节点。
复制偏移量
参与复制的主节点会把命令的字节长度做累加记录,统计信息在info replication 中的master_repl_offset指标中
从节点每秒中上报自身的复制偏移量给主节点,因此主节点会保存从节点复制偏移量,记录在自己的统计信息中
复制挤压缓冲区
是保存在主节点上的一个固定长度的队列,默认为1MB,当朱姐进行主从复制是,写命令不当会发送到从节点,还会写入复制挤压缓冲区
本质是一个先进先出的定长队列,可以实现保存最近已复制数据的功能
主节点运行ID
每个Redis节点启动后,都会动态分配一个运行id,从节点通过保存主节点的运行id,来判断先谁复制
Redis重启后运行id会随之改变
若不希望从节点对主节点进行全量复制,需要保持主节点id不变,重启后可以使用Redis-cli debug reload 命令来进行对配置文件的重新加载,但是此命令会对主节点造成阻塞
psync命令
- 命令格式:psync {runid(节点id)} {offset(复制偏移量)}
全量复制
-
对于数据量大的主节点,生成的rdb文件超过60G时,注意传输时间超过repl-timeout所配置的值,从节点会放弃接受RDB文件并清理已经下载好的临时文件
-
如果60秒内缓冲区消耗过大于64MB或者直接超过256MB,主节点会直接关闭复制客户端连接
部分复制
当全量复制失败后,从节点会向主节点的复制缓冲区要求补发丢失的命令数据。
心跳
主节点在建立复制后,会维护者长连接并彼此发送心跳命令
可以使用命令 client list 来查看
主节点连接转态:flags=M
从节点连接状态:flags=S
异步复制
主节点不但负责数据的读写,还负责写命令同步给从节点,也就是主节点处理完并写入命令后,不在搭理从节点复制是否完成
实验
21 master.redis.com redis master 6379
22 slave.redis.com redis slave 6379, slave 6380
wget http://download.redis.io/releases/redis-4.0.10.tar.gz
tar xf redis-4.0.10.tar.gz -C /usr/src
cd /usr/src/redis-4.0.10
make && make install
cd utils
./install_server.sh
#设置监听地址
[root@master ~]# sed -i '/^bind 127.0.0.1$/s/127.0.0.1/192.168.200.21/g' /etc/redis/6379.conf
#关闭redis的保护模式
[root@master ~]# sed -i '/protected-mode/s/yes/no/g' /etc/redis/6379.conf
#开启Redis的后台守护模式
[root@master ~]# sed -i '/daemonize/s/no/yes/g' /etc/redis/6379.conf
#设置密码123456
[root@master ~]# sed -i '/requirepass/s/foobared/123456/g' /etc/redis/6379.conf
#开启密码
[root@master ~]# sed -i '/requirepass 123456/s/^#//g' /etc/redis/6379.conf
[root@master ~]# /etc/init.d/redis_6379 restart
安装并配置slave
cd utils
./install_server.sh
#第一个6379直接回车
#第一个设置为6380,之后全都是6380
[root@slave utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379] 6380
Please select the redis config file name [/etc/redis/6380.conf]
Selected default - /etc/redis/6380.conf
Please select the redis log file name [/var/log/redis_6380.log]
Selected default - /var/log/redis_6380.log
Please select the data directory for this instance [/var/lib/redis/6380]
Selected default - /var/lib/redis/6380
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port : 6380
Config file : /etc/redis/6380.conf
Log file : /var/log/redis_6380.log
Data dir : /var/lib/redis/6380
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6380.conf => /etc/init.d/redis_6380
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
[root@slave utils]# sed -i '/^bind 127.0.0.1$/s/127.0.0.1/192.168.200.22/g' /etc/redis/6379.conf
[root@slave utils]# sed -i '/protected-mode/s/yes/no/g' /etc/redis/6379.conf
[root@slave utils]# sed -i '/daemonize/s/no/yes/g' /etc/redis/6379.conf
[root@slave utils]# sed -i '/requirepass/s/foobared/123456/g' /etc/redis/6379.conf
[root@slave utils]# sed -i '/requirepass 123456/s/^#//g' /etc/redis/6379.conf
[root@slave utils]# /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...
[root@slave utils]# sed -i '/^bind 127.0.0.1$/s/127.0.0.1/192.168.200.22/g' /etc/redis/6380.conf
[root@slave utils]# sed -i '/protected-mode/s/yes/no/g' /etc/redis/6380.conf
[root@slave utils]# sed -i '/daemonize/s/no/yes/g' /etc/redis/6380.conf
[root@slave utils]# sed -i '/requirepass/s/foobared/123456/g' /etc/redis/6380.conf
[root@slave utils]# sed -i '/requirepass 123456/s/^#//g' /etc/redis/6380.conf
[root@slave utils]# /etc/init.d/redis_6380 restart
Stopping ...
Redis stopped
Starting Redis server...
修改master配置文件
[root@master ~]# vim /etc/redis/6379.conf
451 min-slaves-to-write 2 #设置slave节点数量
452 min-slaves-max-lag 10 #超时时间
[root@slave utils]# /etc/init.d/redis_6379 restart
修改slave配置文件
[root@slave utils]# vim /etc/redis/6379.conf
282 slaveof 192.168.200.21 6379 #指定master的ip地址以及端口
289 masterauth 123456 #指定master的连接密码
[root@slave utils]# vim /etc/redis/6380.conf
282 slaveof 192.168.200.21 6379
289 masterauth 123456
[root@slave utils]# /etc/init.d/redis_6379 restart
[root@slave utils]# /etc/init.d/redis_6380 restart
测试
192.168.200.21:6379> info replication
# Replication
role:master
connected_slaves:2
min_slaves_good_slaves:2
slave0:ip=192.168.200.22,port=6380,state=online,offset=826,lag=0
slave1:ip=192.168.200.22,port=6379,state=online,offset=812,lag=0
master_replid:6b0329415c064d10796db380f492ea61a8eb0065
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:826
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:826
192.168.200.21:6379> set name whml
OK
[root@slave utils]# redis-cli -h 192.168.200.22 -a 123456 -p 6379
192.168.200.22:6379> key *
(error) ERR unknown command 'key'
192.168.200.22:6379> keys *
1) "name"
[root@slave utils]# redis-cli -h 192.168.200.22 -a 123456 -p 6380
192.168.200.22:6380> keys *
1) "name"