redis主从架构

redis高可用与集群

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

redis主从架构

主备模式,可以实现Redis数据的跨主机备份。

程序端连接到高可用负载的VIP,然后连接到负载服务器设置的Redis后端realserver,此模式不需要在程序里面配置Redis服务器的真实IP地址,当后期Redis服务器IP地址发生变更只需要更改redis 相应的后端real server即可,可避免更改程序中的IP地址设置。
在这里插入图片描述

Slave主要配置

Redis Slave 也要开启持久化并设置和master同样的连接密码,因为后期slave会有提升为master的可能,Slave端切换master同步后会丢失之前的所有数据。

一旦某个Slave成为一个master的slave,Redis Slave服务会清空当前redis服务器上的所有数据并将master的数据
导入到自己的内存,但是断开同步关系后不会删除当前已经同步过的数据

基于命令行配置主从,临时生效,重启后主从状态失效

当前状态的master,需要转化为slave角色并指向master服务器的IP+PORT+Password

172.222.2.127-slave:6379> REPLICAOF 172.222.2.107 6379 #主master_ip_port,redis5.0后可使用
OK
172.222.2.127:6379> CONFIG SET masterauth 123456
OK
172.222.2.127:6379> SLAVEOF 172.222.2.107 6379 #redis5.0以前
OK
172.222.2.127:6379> CONFIG SET MASTERAUTH 123456
OK

基于配置文件设置主从

171 logfile "/apps/redis/logs/redis.log"
286 replicaof 172.222.2.107 6379
293 masterauth 123456 #master如果密码需要设置

当前slave状态

172.222.2.127:6379>INFO Replication
# Replication
role:slave
master_host:172.222.2.107  
master_port:6379
master_link_status:up  #保证主的up状态
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_repl_offset:14
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:8b1c8179e13edb736c619293ea6bffdc4a0704e5
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

检测同步数据是否实时同步

172.222.0.107:6379> set key4 vale4  #master
OK
172.222.0.107:6379> keys *
1) "key4"
2) "key1"
3) "key2"
4) "key3"

172.222.0.127:6379> keys *   #slave同步成功
1) "key3"
2) "key1"
3) "key2"
172.222.0.127:6379> keys *
1) "key4"
2) "key3"
3) "key1"
4) "key2"

172.222.0.127:6379> set key5 vlaue 6  #此时的从是只读状态,不能写入
(error) READONLY You can't write against a read only slave.
172.222.0.127:6379> 

#replica-read-only yes #是否设置从库只读 

#如果未设置master密码,会导致数据无法同步
Connecting to MASTER 172.222.2.107:6379
MASTER <->REPLICA sync started
Non blocking connect for SYNC fired the event.
Master replied to PTNG. replication can continue.
Unable to AUTH to MASTER: -ERR invalid password

查看slve同步日志

]#tail -f /apps/redis/logs/redis.log 
17569:S 11 Feb 13:00:30.252 * Connecting to MASTER 172.222.2.107:6379
17569:S 11 Feb 13:00:30.252 * MASTER <-> SLAVE sync started
17569:S 11 Feb 13:00:30.253 * Non blocking connect for SYNC fired the event.
17569:S 11 Feb 13:00:30.253 * Master replied to PING, replication can continue...
17569:S 11 Feb 13:00:30.255 * Partial resynchronization not possible (no cached master)
17569:S 11 Feb 13:00:30.256 * Full resync from master: 77cb5edf250507db19a83760a0bfd673620aecbf:0 #同步数据过程
17569:S 11 Feb 13:00:30.337 * MASTER <-> SLAVE sync: receiving 451 bytes from master
17569:S 11 Feb 13:00:30.338 * MASTER <-> SLAVE sync: Flushing old data
17569:S 11 Feb 13:00:30.338 * MASTER <-> SLAVE sync: Loading DB in memory
17569:S 11 Feb 13:00:30.338 * MASTER <-> SLAVE sync: Finished with success
17569:S 11 Feb 13:02:59.244 * Background saving started by pid 17762 #本机执行BGSAVE,后台RDB过程
17762:C 11 Feb 13:02:59.246 * DB saved on disk
17762:C 11 Feb 13:02:59.247 * RDB: 0 MB of memory used by copy-on-write
17569:S 11 Feb 13:02:59.283 * Background saving terminated with success

查看master同步日志

19540:M 11 Feb 12:59:39.179 # Server initialized
19540:M 11 Feb 12:59:39.179 * DB loaded from disk: 0.000 seconds
19540:M 11 Feb 12:59:39.179 * Ready to accept connections
19540:M 11 Feb 13:00:30.278 * Slave 172.222.2.127:6379 asks for synchronization
19540:M 11 Feb 13:00:30.278 * Full resync requested by slave 172.222.2.127:6379
19540:M 11 Feb 13:00:30.360 * Synchronization with slave 172.222.2.127:6379 succeeded
19540:M 11 Feb 13:02:20.016 * Background saving started by pid 19702
19702:C 11 Feb 13:02:20.019 * DB saved on disk
19702:C 11 Feb 13:02:20.019 * RDB: 0 MB of memory used by copy-on-write
19540:M 11 Feb 13:02:20.080 * Background saving terminated with success

主从复制过程

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位置,只同步新增加的数据,不再全量同步。

主从同步优化

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 #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不接收写操作(拒绝写入)。

slave切换master

#Master的切换会导致master_replid发生变化,slave之前的master_replid就和当前master不一致从而会引发所有slave的全量同步。

127.0.0.1:6379> SLAVEOF 172.222.2.117 6379
OK
127.0.0.1:6379> CONFIG SET masterauth hjq
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:172.222.2.117
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:28
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:e836b86e581cce2e8fd22d74340b462a85979904  
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:0
127.0.0.1:6379> keys *
1) "key1"
2) "key2"


19293:S 11 Feb 14:39:19.287 * Connecting to MASTER 172.222.2.117:6379
19293:S 11 Feb 14:39:19.288 * MASTER <-> SLAVE sync started
19293:S 11 Feb 14:39:19.288 * Non blocking connect for SYNC fired the event.
19293:S 11 Feb 14:39:19.290 * Master replied to PING, replication can continue...
19293:S 11 Feb 14:39:19.294 * Trying a partial resynchronization (request bab05f2732afa75a46bd9c64648ecf54c8c73c17:29).
19293:S 11 Feb 14:39:19.296 * Full resync from master: e836b86e581cce2e8fd22d74340b462a85979904:28
19293:S 11 Feb 14:39:19.296 * Discarding previously cached master state.
19293:S 11 Feb 14:39:19.384 * MASTER <-> SLAVE sync: receiving 439 bytes from master
19293:S 11 Feb 14:39:19.384 * MASTER <-> SLAVE sync: Flushing old data
19293:S 11 Feb 14:39:19.385 * MASTER <-> SLAVE sync: Loading DB in memory
19293:S 11 Feb 14:39:19.386 * MASTER <-> SLAVE sync: Finished with success


127.0.0.1:6379> SLAVEOF no one #止slave同步

slave节点再此slave

在这里插入图片描述

在有slave的”master”查看状态,也就是中间那个slave:

#redis-cli 
127.0.0.1:6379> info replication
NOAUTH Authentication required.
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:172.222.2.117  
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1 #最近一次与master通信已经过去多少秒。
master_sync_in_progress:0  #是否正在与master通信
slave_repl_offset:8568  #当前同步的偏移量。
slave_priority:100 #slave优先级,master故障后值越小越优先同步。
slave_read_only:1   
connected_slaves:1 #连接的slave
slave0:ip=172.222.2.107,port=6379,state=online,offset=8554,lag=1
master_replid:e836b86e581cce2e8fd22d74340b462a85979904
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:8568
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:8540
127.0.0.1:6379> 

常用问题汇总

master密码不对

即配置master密码不对,导致验证不通过而无法建立主从同步关系

在这里插入图片描述

redis版本不一致

不同的redis版本之间存在兼容性问题,因此各master和slave之间必须保持一直

在这里插入图片描述

无法建立连接

在开启了安全模式情况下,没有设置bind地址或者密码,或防火墙规则未放行

127.0.0.1:6379> redis-cli
127.0.0.1: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 '--protectedmode
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.


29475:S 11 Feb 16:19:21.979 * MASTER <-> SLAVE sync started
29475:S 11 Feb 16:19:21.980 # Error condition on socket for SYNC: No route to host
29475:S 11 Feb 16:19:22.985 * Connecting to MASTER 172.222.2.127:6379
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值