主从简介
配置多台Redis服务器,以主机和备机的身份分开。主机数据更新后,根据配置和策略,自动同步到备机的master/salver机制,Master以写为主,Slave以读为主,二者之间自动同步数据。
![](https://img.haomeiwen.com/i17367901/e7aa4b5f924378ef.png)
目的:
- 读写分离,提交 redis 性能。
- 避免单点故障,容灾快速恢复。
原理:
每次从机联通后,都会给主机发送sync指令,主机立刻进行存盘操作,发送RDB文件,给从机
从机收到RDB文件后,进行全盘加载。之后每次主机的写操作命令,都会立刻发送给从机,从机执行相同的命令来保证主从的数据一致!
注意:主库接收到SYNC的命令时会执行RDB过程,即使在配置文件中禁用RDB持久化也会生成,但是如果主库所在的服务器磁盘IO性能较差,那么这个复制过程就会出现瓶颈,庆幸的是,Redis在2.8.18版本开始实现了无磁盘复制功能(不过该功能还是处于试验阶段),设置repl-diskless-sync yes。即Redis在与从数据库进行复制初始化时将不会将快照存储到磁盘,而是直接通过网络发送给从数据库,避免了IO性能差问题。
主从准备
主从复制可以配置到多个服务器中,这里为了偷懒,配置到单个服务器中(配置不同的端口)
- 准备三个文件
-rw-rw-r--. 1 admin admin 99 6月 16 19:33 redis_6379.conf
-rw-rw-r--. 1 admin admin 99 6月 16 19:34 redis_6380.conf
-rw-rw-r--. 1 admin admin 99 6月 16 19:34 redis_6381.conf
redis_6379.conf
# 导入默认配置,在默认配置中做覆盖
include ./redis.conf
# 配置端口
port 6379
# redis pid
pidfile /var/run/redis_6379.pid
# rdb
dbfilename dump_6379.rdb
# aof
appendfilename "appendonly_6379.aof"
redis_6380.conf
# 导入默认配置,在默认配置中做覆盖
include ./redis.conf
# 配置端口
port 6380
# redis pid
pidfile /var/run/redis_6380.pid
# rdb
dbfilename dump_6380.rdb
# aof
appendfilename "appendonly_6380.aof"
# 指定 master 密码,若没可以不用指定
masterauth 123321
redis_6381.conf
# 导入默认配置,在默认配置中做覆盖
include ./redis.conf
# 配置端口
port 6381
# redis pid
pidfile /var/run/redis_6381.pid
# rdb
dbfilename dump_6381.rdb
# aof
appendfilename "appendonly_6381.aof"
# 指定 master 密码,若没可以不用指定
masterauth 123321
- 清除:dump 及appendonly 文件
redis]$ rm -rf dump*
redis]$ rm -rf appendonly*
- 运行
redis]$ redis-server redis_6379.conf
redis]$ redis-server redis_6380.conf
redis]$ redis-server redis_6381.conf
- 检查是否启动
[admin@hadoop102 redis]$ ps -aux |grep redis
admin 10589 0.0 0.0 137076 7528 ? Ssl 19:46 0:00 redis-server 0.0.0.0:6379
admin 10599 0.0 0.0 137076 7532 ? Ssl 19:47 0:00 redis-server 0.0.0.0:6380
admin 10609 0.0 0.0 137076 7528 ? Ssl 19:47 0:00 redis-server 0.0.0.0:6381
admin 10631 0.0 0.0 112824 984 pts/1 S+ 19:48 0:00 grep --color=auto redis
- 登录各个服务器
[admin@hadoop102 redis]$ redis-cli -p 6379 -a 123321
127.0.0.1:6379>
[admin@hadoop102 redis]$ redis-cli -p 6380 -a 123321
127.0.0.1:6380>
[admin@hadoop102 redis]$ redis-cli -p 6381 -a 123321
127.0.0.1:6381>
- 查看 主从状态 info replication
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6380>
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6381>
咦!怎么都是master?如何配置从服务器呢?
-
临时建立
原则:配从不配主。
配置:在从服务器上执行 SLAVEOF ip:port 命令;
查看:执行info replication命令;
将 6380 、6381 配置成 6379的 从节点。
6380 slave
127.0.0.1:6380> SLAVEOF hadoop102 6379
OK
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:hadoop102
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1623844978
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
6381 slave
127.0.0.1:6381> SLAVEOF hadoop102 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:hadoop102
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1623844983
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6381>
6379 master
127.0.0.1:6379> info replication
# Replication
role:master
# 两个 slave
connected_slaves:2
slave0:ip=192.168.200.102,port=6380,state=online,offset=1051,lag=1
slave1:ip=192.168.200.102,port=6381,state=online,offset=1051,lag=1
master_repl_offset:1051
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:1050
这样主从复制就配置好了;若主从复制不起作用请参考
向 master 写入数据 slave 可以获取到
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6380> get name
"zhangsan"
127.0.0.1:6381> get name
"zhangsan"
该方式是一种临时方式(SLAVEOF host post),一旦 slave 服务器挂掉了重新连接,那么还会恢复成 master。
以 6381 演示说明:
关闭服务器
127.0.0.1:6381> SHUTDOWN
not connected>
重新启动
[admin@hadoop102 redis]$ redis-server redis_6381.conf
[admin@hadoop102 redis]$ redis-cli -p 6381 -a 123321
查看
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
若要成为 6379 的 slave 需要重新进行绑定
127.0.0.1:6381> SLAVEOF hadoop102 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:hadoop102
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:2385
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
-
永久建立
在从机的配置文件中,编写slaveof属性配置!
# slaveof <masterip> <masterport>
还是用 6381 做案例演示:
再次关闭服务器
127.0.0.1:6381> SHUTDOWN
not connected>
修改 redis_6381.conf 文件
[admin@hadoop102 redis]$ cat redis_6381.conf
# 导入默认配置,在默认配置中做覆盖
include ./redis.conf
# 配置端口
port 6381
# redis pid
pidfile /var/run/redis_6381.pid
# rdb
dbfilename dump_6381.rdb
# aof
appendfilename "appendonly_6381.aof"
masterauth 123321
# 绑定 master
slaveof hadoop102 6379
重新启动
[atguigu@hadoop102 redis]$ redis-server redis_6381.conf
[atguigu@hadoop102 redis]$ redis-cli -p 6381 -a 123321
查看身份
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:hadoop102
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:2973
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
这样就永久设置成 slave 了
-
恢复自由身
slave 如何重新恢复成 master 呢?
执行命令 **slaveof no one** 恢复自由身!
以 6381 服务为例
127.0.0.1:6381> slaveof no one
OK
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:3519
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
注意:永久建立(slaveof) ,重启之后依旧是 slave
slave 是禁止写入数据的,只能进行读,会报错(如下)。
127.0.0.1:6381> set k1 v1
(error) READONLY You can't write against a read only slave.
slave 能否支持写操作呢?
slave-serve-stale-data yes
slave-serve-stale-data 默认为 yes 表示 slave 只支持读操作,若需要支持写操作改成no即可。
还是以 6381 服务为例
关闭服务
127.0.0.1:6381> SHUTDOWN
not connected>
修改redis_6381.conf 配置
[admin@hadoop102 redis]$ cat redis_6381.conf
# 导入默认配置,在默认配置中做覆盖
include ./redis.conf
# 配置端口
port 6381
# redis pid
pidfile /var/run/redis_6381.pid
# rdb
dbfilename dump_6381.rdb
# aof
appendfilename "appendonly_6381.aof"
masterauth 123321
# 绑定 master
slaveof hadoop102 6379
# 支持写操作
slave-serve-stale-data no
重新启动
抱歉:刚才试了,还是不行。
127.0.0.1:6381> set name a
(error) READONLY You can't write against a read only slave.
但是不推荐这么做,这样会带来额外的性能消耗,maser不仅需要负责客户端的写请求,同时还需要同步slave 的数据,建议默认yes即可。
主从常见问题
①从机是从头开始复制主机的信息,还是只复制切入以后的信息?
答:从头开始复制,即完全复制。
②从机是否可以写?
答:默认情况不能,可以通过修改配置文件,设置slave-read-only no.但是从机写入的数据是不能同步到主机,因此没用设置的必要!
![](https://img.haomeiwen.com/i17367901/d8a5dd1a57d44715.png)
③主机shutdown后,从机是上位还是原地待命?
答:原地待命
④主机又回来了后,主机新增记录,从机还能否顺利复制?
答:可以
⑤从机宕机后,重启,宕机期间主机的新增记录,从机是否会顺利复制?
答:可以
⑥其中一台从机down后重启,能否重认旧主?
答:不一定,看配置文件中是否配置了slaveof
⑦如果两台从机都从主机同步数据,此时主机的IO压力会增大,如何解决?
答:按照主---从(主)---从模式配置!
网友评论