Redis6 的主从复制
2289字约8分钟
2024-08-10
主机数据更新后根据配置和策略,自动同步到备机的 master/salver 机制,master 以写为主,slave 以读为主
作用:
读写分离,性能扩展
容灾快速恢复(一台从挂掉了,快速切换到其他从机上)
主从复制
一台机器上启动多个配置,模拟一主两从
1、创建
/myredis
文件夹2、复制
redis.conf
配置文件到/myredis
文件夹中3、配置一主两从,创建三个配置文件,
redis6379.conf
、redis6380.conf
、redis6381.conf
4、修改(注意基本配置,如:
dameonize yes
、pid 文件名字 pidfile、指定端口 port、log 文件名称、rdb 或 aof 配置)
复制一份redis.conf
到创建的/myredis
目录
cp /etc/redis.conf /myredis
新建redis6379.conf
,引入redis.conf
配置,并做相应改动
# 创建 redis6379.conf 文件
vi redis6379.conf
# redis6379.conf 配置文件的内容
# 引入 redis.conf 配置文件
include /myredis/redis.conf
# 设置 redis-server 进程的 pid,即 Process ID(进程 ID)
pidfile /var/run/redis_6379.pid
# 设置端口号
port 6379
# 设置 rdb 持久化文件的名称
dbfilename dump6379.rdb
# 继续创建 6380、6381 的配置文件,这里直接通过复制的方式,然后去改
cp redis6379.conf redis6380.conf
cp redis6379.conf redis6381.conf
- 5、启动 redis(只是单纯启动,还没有配置主从),使用
info replication
查看主从复制相关信息
# myredis 目录下,启动 redis
redis-server redis6379.conf
redis-server redis6380.conf
redis-server redis6381.conf
# 打开三个窗口,用 redis-cli 连上 redis
redis-cli -p 6379
redis-cli -p 6380
redis-cli -p 6381
使用info replication
查看主从复制相关信息
127.0.0.1:6379> info replication
# Replication,当前端口的 redis 是主机
role:master
connected_slaves:0
# 没有从机
master_failover_state:no-failover
master_replid:40a7093fb83324a669504bf7cf3f275bd1701aa2
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
配置从机,不需要配主机。从机上执行slaveof 主机ip 端口号
(注意:如果 redis 配置了密码,那么在从机配置文件上加 masterauth password
)
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380> info replication
# Replication
127.0.0.1:6380> info replication
# Replication,当前机是从机
role:slave
# 主机 ip
master_host:127.0.0.1
# 主机端口
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
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:b8ba1d93c9a97a5666c282af873e41ed8559b0a7
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:6380>
# 将 6381 也配置成从机后,查看主机 6379 的信息
127.0.0.1:6379> info replication
# Replication
role:master
# 连接的从机 2 个
connected_slaves:2
# 从机 ip、端口号
slave0:ip=127.0.0.1,port=6380,state=online,offset=322,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=308,lag=1
master_failover_state:no-failover
master_replid:b8ba1d93c9a97a5666c282af873e41ed8559b0a7
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>
效果
- 在主机上添加值,从机上读取;从机上设置值失败
# 主机操作
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> get k1
"v1"
# 从机操作
127.0.0.1:6380> get keys
(nil)
127.0.0.1:6380> keys *
1) "k1"
127.0.0.1:6380> get k1
"v1"
127.0.0.1:6380> set k2 v2
# 报错,只能读不能写
(error) READONLY You can't write against a read only replica.
主机挂掉,直接重启就行,一切如初
从机重启需要重设:
slaveof 127.0.0.1 6379
可以将配置添加到redis.conf
文件中,永久生效
replicaof 127.0.0.1 6379
常用 3 招
一主二仆
从机宕机后,重启后是从头开始复制。
主机挂掉后,从机
info replication
依旧是从机,不做任何事情,主机重启后依旧是主机
薪火相传
将原来的一台从机变成另外一台从机的从机,至此,主机只有一台从机,从机下面有一台从机。数据同步如下图
反客为主
当一个 Master 宕机后,后面的 Slave 可以立刻升级为 Master,其后面的 Slave 不用做任何修改
用 slaveof no one
将从机变为主机(主机没挂掉执行这个命令也会让从机变为主机)
复制原理
从机第一次连接主机,主动发起的同步
Slave 启动成功连接到 Master 后发送一个 sync 命令
Master 接收到命令后启动后台的存盘进程,同时收集接收到的用于修改数据集命令,在后台进程执行完毕之后,Master 将传送整个数据文件到 Slave,以完成一次完全不同
全量复制:Slave 服务在接收到数据库文件数据后,将其存盘并加载到内存中
从机连接主机,进行了全量不同之后
增量复制:Master 继续将新的所有收集到的修改命令一次传送给 Slave,完成同步
但是只要是重新连接 Master,一次完全同步(全量复制)将被自动执行
哨兵模式
反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
操作步骤
调整为一主二仆模式,6379 主机、6380、6381 从机
自定义
/myredis
目录下新建sentinel.conf
配置文件,名字必须是这个配置哨兵
# mymaster 为监控对象起的服务器名称,1:表示至少有多少个哨兵同意迁移的数量
sentinel monitor mymaster 127.0.0.1 6379 1
# 如果 redis 有密码,添加如下配置
sentinel auth-pass mymaster 123456
- 启动哨兵
# 启动命令
redis-sentinel /myredis/sentinel.conf
当主机挂掉,从机选举中产生新的主机(大概 10 秒左右可以看到哨兵窗口日志,切换了主机)
优先级别:replica-priority(这是2.6.2版本的,其他版本配置名字 savle-priority)
原主机重启后变从机
# 将 6379 端口的 redis 关闭,哨兵这边日志如下
[root@iZ2zeciiosuxr5a7loycmeZ myredis]# redis-sentinel sentinel.conf
27300:X 12 Jun 2021 09:52:28.787 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
27300:X 12 Jun 2021 09:52:28.787 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=27300, just started
27300:X 12 Jun 2021 09:52:28.788 # Configuration loaded
27300:X 12 Jun 2021 09:52:28.788 * monotonic clock: POSIX clock_gettime
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 6.2.4 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379
| `-._ `._ / _.-' | PID: 27300
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | https://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
27300:X 12 Jun 2021 09:52:28.789 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
27300:X 12 Jun 2021 09:52:28.789 # Sentinel ID is 6a1dbaac55e8e83b3a48e8d24a8a7ea8aa1b482e
27300:X 12 Jun 2021 09:52:28.789 # +monitor master mymaster 127.0.0.1 6379 quorum 1
27300:X 12 Jun 2021 09:52:28.791 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
27300:X 12 Jun 2021 09:52:28.795 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
# 上面是启动哨兵的日志
# master 已经挂掉了
27300:X 12 Jun 2021 09:59:15.822 # +sdown master mymaster 127.0.0.1 6379
27300:X 12 Jun 2021 09:59:15.822 # +odown master mymaster 127.0.0.1 6379 #quorum 1/1
27300:X 12 Jun 2021 09:59:15.822 # +new-epoch 4
# try-failover 尝试故障转移
27300:X 12 Jun 2021 09:59:15.822 # +try-failover master mymaster 127.0.0.1 6379
27300:X 12 Jun 2021 09:59:15.826 # +vote-for-leader 6a1dbaac55e8e83b3a48e8d24a8a7ea8aa1b482e 4
# elected-leader 选举领导
27300:X 12 Jun 2021 09:59:15.826 # +elected-leader master mymaster 127.0.0.1 6379
27300:X 12 Jun 2021 09:59:15.826 # +failover-state-select-slave master mymaster 127.0.0.1 6379
# selected-slave 选择 6380 从机
27300:X 12 Jun 2021 09:59:15.910 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
# slaveof-noone 将从机变为主机命令
27300:X 12 Jun 2021 09:59:15.910 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
# promotion 晋升
27300:X 12 Jun 2021 09:59:15.986 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
27300:X 12 Jun 2021 09:59:16.304 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
27300:X 12 Jun 2021 09:59:16.304 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379
27300:X 12 Jun 2021 09:59:16.390 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
27300:X 12 Jun 2021 09:59:17.303 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
27300:X 12 Jun 2021 09:59:17.303 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
# 故障转移结束
27300:X 12 Jun 2021 09:59:17.404 # +failover-end master mymaster 127.0.0.1 6379
# 切换主机为 6380 端口
27300:X 12 Jun 2021 09:59:17.404 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380
27300:X 12 Jun 2021 09:59:17.404 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
# 6379 变为从机,重启后直接就是从机
27300:X 12 Jun 2021 09:59:17.404 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
- 复制延时
由于所有的写操作都是先在 Master 上操作,然后同步更新到 Slave 上,所有从 Master 同步到 Slave 机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave 机器数量的增加也会使这个问题更加严重。
故障恢复
1、从主服务的从服务中心挑选一个从服务,将其转为主服务。选择条件依次如下
1)、选择优先级靠前的(
redis.conf
中replica-priority 100
越小优先级越高)2)、选择偏移量最大的(指获得原主机数据最全的)
3)、选择 runid 最小的(每个 redis 实例启动后都会随机生成一个 40 位的 runid)
2、挑选出新的主服务之后,sentinel 向原主服务的从服务发送 slaveof 新主服务的命令,复制新 Master
3、当已下线的服务重新上线时,sentinel 会向其发送 slaveof 命令,让其成为新主的从