【Redis】主从复制和哨兵模式

一、简介

1、什么是主从复制
主机数据更新后根据配置和策略,自动同步到备机的master/slave机制
Matser以写为主,Slave以读为主,简单来说如下图

在这里插入图片描述

2、主从复制的好处

  • 读写分离:Matser以写为主,Slave以读为主
  • 容灾的快速恢复:当一台从服务器发生宕机,可以快速切换到其他的从服务器提供读操作

二、搭建一主多从

由于我本地只有一台虚拟机,所以我打算开启三个redis进程来模拟一主多从

前提:redis.conf中的protected-mode改为 fasle,否则不能进行主从复制

1、在根目录创建myredis文件夹

mkdir myredis

2、复制我们当前的redis配置文件到/myredis文件夹路径下

cp /opt/decade/redis.conf /myredis/redis.conf

3、配置一主两从,创建配置文件

touch redis6379.conf

4、分别修改配置文件的内容
可以使用include来引入我们原本的redis.conf
然后修改pid、端口和RDB相关配置

问题:是否需要关闭AOF,防止后面主从复制的时候,生成的RDB持久化文件为空?

include /myredis/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb

然后使用cp拷贝一下redis6379.conf,使用vi修改配置

5、分别启动三个redis服务

cd /opt/decade/redis/bin/
redis-server /myredis/redis6379.conf
redis-server /myredis/redis6380.conf
redis-server /myredis/redis6381.conf

在这里插入图片描述

6、客户端使用指定端口号连接服务器

redis-cli -p 6379
redis-cli -p 6380
redis-cli -p 6381

使用info replication获取 主/从 服务器的详细信息

127.0.0.1:6379> info replication
# Replication
role:master   //当前角色 : 主服务器
connected_slaves:0   //连接的从服务器的个数
master_failover_state:no-failover
master_replid:b1642741686dc1a03075ae00a67269a41b53b0e8
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
127.0.0.1:6379>

7、设置从机
只需要使用客户端连接指定端口号的服务器
使用slaveof [ip] [port]就可以,我们使用6380和6381执行此命令

然后分别使用info replication查看主从服务器详情,并且在master上执行set操作

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=70,lag=1
slave1:ip=127.0.0.1,port=6380,state=online,offset=70,lag=1
master_failover_state:no-failover
master_replid:09702c2e350d2ddaebeeda41fed8e0396031bce7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:70
127.0.0.1:6379>
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379>
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:6379>

我们发现,master上设置的数据会同步到slave上,但是slave不能使用set操作,这就是上面说的读写分离

[root@192 bin]# redis-cli -p 6380
127.0.0.1:6380>
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_read_repl_offset:42
slave_repl_offset:42
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:09702c2e350d2ddaebeeda41fed8e0396031bce7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:42
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:14
127.0.0.1:6380>
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.
127.0.0.1:6380>
[root@192 bin]# redis-cli -p 6381
127.0.0.1:6381>
127.0.0.1:6381> slaveof 127.0.0.1 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_read_repl_offset:56
slave_repl_offset:56
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:09702c2e350d2ddaebeeda41fed8e0396031bce7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:56
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:42
127.0.0.1:6381>
127.0.0.1:6381> get k1
"v1"
127.0.0.1:6381>

三、复制原理和一主二仆

一主二仆就是一个master下面有两个slave

1、当从服务器宕机之后

  • 重启该服务器,并不会恢复为slave角色,而是会成为单独的master
  • 当我们使用slaveof host port命令将从服务器重新加入到主从关系中后,从服务器会重新复制主服务器的数据(结合主从复制原理看)

2、当主服务器宕机之后

  • 从服务器并不会抢夺主服务器的master角色,只是会显示master的状态master_link_status为down
  • 主服务器重启之后,仍然是master角色

3、主从复制原理

  • 全量同步阶段

    • 从服务器连接到主服务器,发送sync命令
    • 主服务器接收到该命令,开始执行BGSAVE命令生成RDB文件,并使用缓冲区记录此后执行的所有写命令
    • 当主服务器BGSAVE执行完后,向所有从服务器发送RDB快照文件,并在发送期间继续记录被执行的写命令
    • 从服务器收到快照文件后丢弃所有旧数据,重新读取收到的快照文件
    • 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令
    • 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令
    • 完成上述步骤之后,从服务器就可以开始接收来自客户端的读请求
  • 增量同步阶段

    • 主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令

简单概括一下就是:主从刚刚连接的时候,进行全量同步,全同步结束后,进行增量同步,从服务器在任何时候都可以要求全量同步

四、薪火相传和反客为主

1、薪火相传
薪火相传可以理解为,slave从服务器还存在属于它自己的从服务器,主服务器master的数据会沿着关系链往下同步
在这里插入图片描述
我现在令6379端口为master,6380为它的slave,然后再设置6381作为6380的slave
可以看出,master中设置的key会传递到slave下的slave中

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=168,lag=1
master_failover_state:no-failover
master_replid:67b215bc1ddef32238a07d2fad45b2d37d8fbed3
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:168
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:168
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379>
127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380>
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_read_repl_offset:234
slave_repl_offset:234
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=234,lag=1
master_failover_state:no-failover
master_replid:67b215bc1ddef32238a07d2fad45b2d37d8fbed3
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:234
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:169
repl_backlog_histlen:66
127.0.0.1:6381> get k1
"v1"
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_read_repl_offset:346
slave_repl_offset:346
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:67b215bc1ddef32238a07d2fad45b2d37d8fbed3
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:346
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:169
repl_backlog_histlen:178
127.0.0.1:6381>
127.0.0.1:6381> get k1
"v1"

2、反客为主
当master宕机之后,在它下面的slave上手动使用slaveof no one命令将其立即晋升为master

思考:

  • master重启之后还是master吗?
  • 如果是一主二仆,那么另外一个仆也会归属于这个slave吗?

五、哨兵模式

1、什么是哨兵模式
可以理解为上面反客为主的自动版,我们会在后台监控主机是否发生故障,如果主服务器宕机,选择出一个从服务器,将他们作为新的主服务器,其余的从服务器跟随新的主服务器

2、如何使用哨兵模式

  • 创建一个sentinel.conf并填写要监控的master信息
    sentinel monitor < master-name > < ip > < port > < count >
    master-name:给主服务器起的名字
    count:最少需要几台 Sentinel哨兵 发现有问题,才会发生故障转移

  • 然后使用redis安装目录bin下的redis-sentinel来启动哨兵
    例如redis-sentinel /myredis/sentinel.conf

  • 停掉master进程,看看会发生什么

3、预期结果
选举出一个slave来代替原来的master,而且旧master重启之后,它的角色也不会变回去

4、转换过程

  • 新主登基:从旧master的slave中挑选一个作为新master
  • 群仆俯首:sentinel向旧master的剩余slave发送slaveof指令,让它们变为新master的从服务器
  • 旧主俯首:旧master重启后,sentinel向其发送slaveof指令,让它变为新master的从服务器

5、选举原则

  • 根据配置文件redis.conf中的优先级配置replica-priority大小选出新的主机,值越小优先级越高
  • 选择偏移量最大的:选举和旧master同步率较高或者从旧master获取数据较全的那个slave
  • 选择runid最小的:每个redis实例启动时会生成40位runid

6、Java开发
涉及到哨兵模式时,连接池就不能使用之前的JedisPool了,而是换成JedisSentinelPool类

如有错误,欢迎指正!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值