【Redis】Redis学习⑧ - redis高可用与集群-配置redis主从
一、简介
-
虽然Redis可以实现单机的数据持久化,但无论是RDB也好或者AOF也好,都解决不了单点宕机问题,即一旦redis服务器本身常出现系统故障、硬件故障等问题后,就会直接造成数据的丢失,因此需要使用另外的技术来解决单点问题。
-
主备模式,可以实现Redis数据的跨主机备份
程序端连接到高可用负载的VIP,然后连接到负载服务器设置的Redis后端real server,此模式不需要在程序里面配置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
replicaof 192.168.56.199 6379
config set masterauth 123456
- 同步日志
#同步数据的过程
2880:S 21 Oct 2023 17:53:57.155 * MASTER <-> REPLICA sync: receiving 176 bytes from master
2880:S 21 Oct 2023 17:53:57.155 * MASTER <-> REPLICA sync: Flushing old data
2880:S 21 Oct 2023 17:53:57.155 * MASTER <-> REPLICA sync: Loading DB in memory
2880:S 21 Oct 2023 17:53:57.155 * MASTER <-> REPLICA sync: Finished with success
#后台RDB过程
2880:S 21 Oct 2023 17:57:27.094 * 10 changes in 300 seconds. Saving...
2880:S 21 Oct 2023 17:57:27.094 * Background saving started by pid 3845
3845:C 21 Oct 2023 17:57:27.103 * DB saved on disk
3845:C 21 Oct 2023 17:57:27.103 * RDB: 4 MB of memory used by copy-on-write
2880:S 21 Oct 2023 17:57:27.202 * Background saving terminated with success
- 当前slave状态
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.56.199
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:2326
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:04aa9f5efbb60c2d200c373f330ae3b4ffec2527
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2326
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1009
repl_backlog_histlen:1318
- 保存配置到redis.conf
replicaof 192.168.56.199 6379
masterauth 123456
- slave状态只读无法写入数据
127.0.0.1:6379[1]> set key1 value1
(error) READONLY You can't write against a read only replica.
- master日志
10849:M 21 Oct 2023 17:35:20.637 * Starting BGSAVE for SYNC with target: disk
10849:M 21 Oct 2023 17:35:20.637 * Background saving started by pid 10860
10860:C 21 Oct 2023 17:35:20.649 * DB saved on disk
10860:C 21 Oct 2023 17:35:20.650 * RDB: 4 MB of memory used by copy-on-write
10849:M 21 Oct 2023 17:35:20.672 * Background saving terminated with success
10849:M 21 Oct 2023 17:35:20.672 * Synchronization with replica 192.168.56.200:6379 succeeded
-
主从复制过程
Redis支持主从复制分为全量同步和增量同步,首次同步是全量同步,主从同步可以让从服务器从主服务器备份数据,而且从服务器还可以有从服务器,即另外一台redis服务器可以从一台从服务器进行数据同步,redis的主从同步是非阻塞的,其收到从服务器的sync(2.8版本之前是PSYNC)命令会fork一个子进程在后台执行bgsave命令,并将新写入的数据写入到一个缓冲区里面,bgsave执行完成之后将生成的RDB文件发送给客户端,客户端将收到后的RDB文件载入自己的内存,然后主redis将缓冲区的内容全部发送给从redis;
之后的同步从服务器会发送一个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把呢不能开始增加了部分复制的功能。
yes为支持disk,master将RDB文件先保存到磁盘再发送给slave,no为直接将RDB文件发送给slave,默认即为no,Master RDB文件不需要与磁盘交互。
repl-diskless-sync yes
Master准备好RDB文件后等待传输的时间
repl-diskless-sync-delay 5
slave端server端发送ping的时间区间设置,默认为10秒
repl-ping-slave-period 10
设置超时时间
repl-timeout 60
是否启用TCP_NODELAY。
如果选择“yes” Redis会合并小的TCP包从而节省带宽,但会增加同步延迟(40ms),造成master和slave数据不一致。
如果选择“no” 则redis master会立即发送同步数据,没有延迟,前者关注性能,后者关注一致性。
repl-disable-tcp-nodelay no
master的写入数据缓冲区,用于记录自上一次同步后到下一次同步过程中间的写入命令,计算公式:b repl-backlog-size = 允许从节点最大中断时常 * 主实例offset每秒写入量
比如master每秒最大写入64mb,最大允许中断60秒,那么就要设置为64mb*60秒=3840mb(3.8G)
repl-backlog-size 1mb
如果一段时间后没有slave连接到master,则backlog size的内存将会被释放。如果值为0则表示永远不释放这部分内存。
repl-backlog-ttl 3600
slave端的优先级设置,值是一个整数,数字越小表示优先级越高。当master故障时将会按照优先级来选择slave端进行恢复,如果值设置为0,则表示该slave永远不会被选择。
replica-priority 100
设置当一个master端的可用slave少于N个,延迟时间大于M秒时,不接收写操作
min-slaves-to-write 0
min-slaves-max-lag 10
- slave切换master
Master的切换会导致master_replid发生变化,slave之前的master——replid就和master不一致从而会引发所有slave的全量同步。
当前状态:
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.56.199
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:434
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:f2fbcf1ee68b64bc88c8942ea704e77853f37412
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:434
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:434
停止slave同步并查看当前状态
127.0.0.1:6379> slaveof no one
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:a7991c5b142e4b8475e1f95206b467827f327850
master_replid2:f2fbcf1ee68b64bc88c8942ea704e77853f37412
master_repl_offset:490
second_repl_offset:491
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:490
测试可以写入数据
127.0.0.1:6379> set key1 value2
OK
- Reis版本需一致