1、配置reids主从:
主备模式,可以实现Redis数据的跨主机备份,程序端连接到高可用负载的VIP,然后连接到负载服务器设置的Redis后端real server,此模式不需要在程序里面配置Redis服务器的真实IP地址,当后期Redis服务器IP地址发生变更只需要更改redis相应的后端real server即可,可避免更改程序中的IP地址设置。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hZkH9jU4-1618479908804)(F:\typora相关笔记\redis\images\主从架构.png)]
2、Slave主要配置:
Redis Slave也要开启持久化并设置和master同样的连接密码,因为后期slave会有提升为master的可能,Slave端切换master同步后会丢失之前的所有数据。
一旦某个Slave成为一个master的slave,Redis Slave服务会清空当前redis服务器上的所有数据并将master的数据导入到自己的内存,但是断开同步关系后不会删除当前已经同步过的数据。
3、主从主机信息
节点 | IP |
---|---|
主节点 | 192.168.21.131 |
从节点 | 192.168.21.139 |
4、修改的配置文件
4.1、修改主服务器131配置文件
vim /usr/local/src/redis/etc/redis.conf
69 bind 0.0.0.0 # 如果不想让其他服务从终端能访问到直接写成本机即可,127.0.0.1
136 daemonize yes # 设置成允许后台启动
500 requirepass 123456 # 设置master连接密码
注意: 本配置只针对集群,对于其他的redis配置请参考redis基础(一)中的配置文件修改,修改之后重启服务
4.2、修改从服务器配置文件
vim /usr/local/src/redis/etc/redis.conf
69 bind 0.0.0.0 # 如果不想让其他服务从终端能访问到直接写成本机即可,127.0.0.1
136 daemonize yes # 设置成允许后台启动
290 masterauth 123456 # 设置slave连接master密码
282 slaveof 192.168.21.131 6379 # 添加master的IP和端口
修改之后重启服务
5、查看master的状态
127.0.0.1:6379> info
......
# Replication
role:master # 当前节点角色
connected_slaves:1 # 当前连接的slave数量
slave0:ip=192.168.21.139,port=6379,state=online,offset=1680,lag=0 # 连接的slave IP、端口、状态信息
master_replid:b3b33c2e6427989053ded619ceb9a1460b64df0f # master ID
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1680
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1680
......
6、查看slave的状态
127.0.0.1:6379> info
......
# Replication
role:slave # 当前节点角色
master_host:192.168.21.131 # master IP
master_port:6379 # master端口
master_link_status:up # master的状态
master_last_io_seconds_ago:8 # 和master在多少秒进行的检查
master_sync_in_progress:0
slave_repl_offset:1750
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:b3b33c2e6427989053ded619ceb9a1460b64df0f # master ID
master_replid2:0000000000000000000000000000000000000000 # 如果其他slave被切换成master,这里上边的ID会放到这里
master_repl_offset:1750
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1750
......
7、查看slave日志
[root@host221 logs]# tail -f redis.log
44053:S 15 Apr 16:59:38.420 * Master replied to PING, replication can continue...
44053:S 15 Apr 16:59:38.421 * Trying a partial resynchronization (request 885b6566c310c38f89f2de1a3677d32fd011d069:113).
44053:S 15 Apr 16:59:38.421 * Full resync from master: b3b33c2e6427989053ded619ceb9a1460b64df0f:0
44053:S 15 Apr 16:59:38.421 * Discarding previously cached master state.
44053:S 15 Apr 16:59:38.512 * MASTER <-> SLAVE sync: receiving 176 bytes from master
44053:S 15 Apr 16:59:38.512 * MASTER <-> SLAVE sync: Flushing old data # 清空当前内存数据
44053:S 15 Apr 16:59:38.512 * MASTER <-> SLAVE sync: Loading DB in memory # 加载DB到内存
44053:S 15 Apr 16:59:38.512 * MASTER <-> SLAVE sync: Finished with success # 完成同步
8、测试同步数据
8.1、查看master 数据
查看master默认库数据
127.0.0.1:6379> keys *
(empty list or set)
8.2、查看master 数据
127.0.0.1:6379> keys *
(empty list or set)
8.3、创建master数据
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> keys *
1) "name"
8.4、查看slave同步情况
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get name
"zhangsan"
数据同步完成!
9、主从同步过程
Redis支持主从复制分为全量同步和增量同步,首次同步是全量同步,主从同步可以让从服务器从主服务器备份数据,而且从服务器还可与有从服务器,即另外一台redis服务器可以从一台从服务器进行数据同步,redis的主从同步是非阻塞的,master收到从服务器的sync(2.8版本之前是PSYNC)命令会fork一个子进程在后台执行bgsave命令,并将新写入的数据写入到一个缓冲区里面,bgsave执行完成之后并生成的将RDB文件发送给客户端,客户端将收到后的RDB文件载入自己的内存,然后redis master再将缓冲区的内容在全部发送给redis slave,之后的同步slave服务器会发送一个offset的位置(等同于MysQL的binlog的位置给主服务器,主服务器检查后位置没有错误将此位置之后的数据包括写在缓冲区的挤压数据发送给redis从服务器,从服务器将主服务器发送的挤压数据写入内存,这样一次完整的数据同步,再之后再同步的时候从服务器只要发送当前的offset位置给主服务器,然后主服务器根据相应的位置将之后的数据发送给从服务器保存到其内存即可。
Redis全量复制一般发生在Slave首次初始化阶段,这时Slave需要将Master上的所有效据都复制一份,具体主从同步如下:
1)从服务器连接主服务器,发送SYNC令;
2)主服务器接收到SYNC命名后,开始执行BGSAVE含命生成RDB快照文件并使用重冲区记录此后执行的所有写命令;
3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
7)后期向步会先发送自己slave-repl_offset位置,只同步新增加的数据,不再全量同步。
10、主从同步优化
Redis在2.8版本之前没有提供增量部分复制的功能,当网络闪断或者slave Redis重启之后会导致主从之间的全量同步,即从2.8版本开始增加了部分复制的功能。
- repl-diskless-sync no # 是否使用无盘同步RDB文件,默认为no,no为不使用无盘,需要将RDB文件保存到磁盘后再发送给slave,yes为支持无盘,支持无盘就是RDB文件不需要保存至本地磁盘,而且直接通过socket文件发送给slave。这个参数取决于磁盘IO,如果磁盘很快就设置成no,如果网络很快可以设置成yes。
- repl-diskless-sync-delay 5 # Master准备好RDB文件后等待传输时间。
- repl-ping-slave-period 10 # slave端向server端发送ping的时间区间设置,默认为10秒
repl-timeout 60#设置超时时间 - repl-disable-tcp-nodelay no # 是否启用TCP-NODELAY,如设置成yes,则redis会合并小的TCP包从而节省带宽,但会增加同步延迟(40ms),造成master与slave数据不一致,假如设置成no,则redis master会立即发送同步数据,没有延迟,前者关注性能,后者关注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-slaves-to-write 1#设置一个master端的可用slave少于多少个
#min-slaves-max-lag 20#设置所有slave延迟时间都大于多少秒时,master不接收写操作(拒绝写入)
11、slave服务还可以有slave
11.1、配置
只需要配置slave的slave的redis配置文件即可,也就是140的配置文件。配置方法是配置
vim /usr/local/src/redis/etc/redis.conf
290 masterauth 123456 # 设置slave连接master密码
282 slaveof 192.168.21.131 6379 # 添加master的IP和端口
现在slave140的master是139,但是139的info中显示的角色还是slave,因为它首先是131的slave,其次是140的master。
11.2、更换140的master
slave140的master是139,想把slave140的master更换成131
# 设置140的节点不属于任何主从的slave
127.0.0.1:6379>slaveof no one
# 修改配置文件
vim /usr/local/src/redis/etc/redis.conf
290 masterauth 123456 # 设置slave连接master密码
282 slaveof 192.168.21.131 6379 # 添加master的IP和端口
12、切换master
当master宕机后需要手动切换slave为master
12.1、停掉master的redis服务
/usr/local/src/redis/bin/redis-cli shutdown
12.2、查看状态
在从服务器上查看master状态
127.0.0.1:6379> info
......
# Replication
role:slave
master_host:192.168.1.138
master_port:6379
master_link_status:down # master已经宕掉了
master_last_io_seconds_ago:-1
......
12.3、查看slave当前数据
# 查看从库当前数据
127.0.0.1:6379> keys *
1) "class1"
2) "list1"
3) "zset3"
4) "list2"
5) "zset1"
6) "set1"
7) "set2"
8) "num"
9) "hash1"
10) "hash2"
11) "name"
12) "age"
13) "paihangbang"
14) "zset2"
15) "key"
16) "zset5"
12.4、测试slave数据写入
127.0.0.1:6379[1]> set paihangbang zhanlang
(error) READONLY You can't write against a read only slave. # 写入失败,提示是slave,只能用来读数据
12.5、剔除slave的master
127.0.0.1:6379[1]> slaveof no one
OK
再次查看slave当前数据,发现数据还在
127.0.0.1:6379[1]> keys *
1) "class1"
2) "list1"
3) "zset3"
4) "list2"
5) "zset1"
6) "set1"
7) "set2"
8) "num"
9) "hash1"
10) "hash2"
11) "name"
12) "age"
13) "paihangbang"
14) "zset2"
15) "key"
16) "zset5"
12.6、测试当前节点的写入数据
127.0.0.1:6379[1]> set paihangbang zhanlang
OK
发现已经可以正常写入数据了,但是注意一点,master和slave的redis的版本必须一致,如果版本不一致会导致数据无法进行同步。当master和slave版本不一致时,从slave日志看当master和slave进行连接后,salve开始清空自己的数据,当数据清理完成后发现无法导入master的RDB数据。
注意: 这种结构已经很少有公司在用,主要弊端太明显,不具备故障转义的功能,当master宕机之后业务会终端写入,需人工切换master才行。