linux12 - Redis -> 04主从复制与哨兵模式

一、Redis集群

由于单机 Redis 存储能力受单机限制,以及无法实现读写操作的负载均衡和读写分离,无法保证高可用。
本篇就来介绍 Redis 集群搭建方案及实现原理,实现 Redis 对数据的冗余备份,从而保证数据和服务的高可用。
主从复制是哨兵和集群的基石,因此我们循序渐进,由浅入深一层层的将 Redis 高可用方案抽丝剥茧展示在大家面前。
1.主从复制
主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器,主从是哨兵和集群模式能够实施 的基础。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。默认 情况下,每台 Redis 服务器都是主节点;且一个主节点可以有零个或多个从节点(0+个从节点),但一个从节点只 能有一个主节点。一般主节点负责接收写请求,从节点负责接收读请求,从而实现读写分离。主从一般部署在不 同机器上,复制时存在网络延时问题,使用参数 repl-disable-tcp-nodelay 选择是否关闭 TCP_NODELAY,默认为关闭:

# 关闭:
无论数据大小都会及时同步到从节点,占带宽,适用于主从网络好的场景。
# 开启:
主节点每隔指定时间合并数据为 TCP 包节省带宽,默认为 40 毫秒同步一次,适用于网络环境复 杂或带宽紧张,如跨机房

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wt8YTb12-1621299654589)(C:\Users\17155\AppData\Roaming\Typora\typora-user-images\1621223608099.png)]

2.作用
# 1、数据冗余:
主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
# 2、故障恢复:
当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
# 3、负载均衡:
在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务,分担服 务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis 服务器的并发量。
# 4、读写分离:
主库写、从库读,读写分离不仅可以提高服务器的负载能力,同时可根据需求的变化,改变从库 的数量。
# 5、高可用基石:
除了上述作用以外,主从复制还是哨兵和集群能够实施的基础。
3.开启主从配置
配置主从可以在命令行或配置文件中配置,上面提到主节点负责写,从节点负责读,因此推荐开启从服务器 的只读配置,否则的话在从节点的写操作不会同步到主节点会导致数据不一致。
#1.查看主从信息
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:625361c542744a006584fa2766a7eba2928320da
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
#1.准备主从环境(一主两从)
[root@redis01 conf]# cp redis.conf  redis-6380.conf 
[root@redis01 conf]# cp redis.conf  redis-6381.conf 
[root@redis01 conf]# ll
总用量 256
-rw-r--r-- 1 root root 84893 5月   7 06:24 redis-6380.conf
-rw-r--r-- 1 root root 84893 5月   7 06:24 redis-6381.conf
-rw-r--r-- 1 root root 84893 5月   1 20:33 redis.conf
-rw-r--r-- 1 root root   217 5月   7 05:52 users.acl
#改配置文件对应端口号
[root@redis01 conf]# vim redis-6380.conf
port 6380
[root@redis01 conf]# vim redis-6381.conf 
port 6381
#将三个配置文件中aclfile一行内容注释掉

#2.启动三个Redis服务
[root@redis01 ~]# /usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf 
[root@redis01 ~]# /usr/local/redis/bin/redis-server /usr/local/redis/conf/redis-6380.conf 
[root@redis01 ~]# /usr/local/redis/bin/redis-server /usr/local/redis/conf/redis-6381.conf 
[root@redis01 ~]# netstat -lntp|grep redis
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      1297/redis-server 1 
tcp        0      0 127.0.0.1:6380          0.0.0.0:*               LISTEN      1426/redis-server 1 
tcp        0      0 127.0.0.1:6381          0.0.0.0:*               LISTEN      1432/redis-server 1 

#3.redis-cli连接三个服务端
[root@redis01 ~]# redis-cli -p 6379
127.0.0.1:6379> 
[root@redis01 conf]# redis-cli -p 6380
127.0.0.1:6380> 
[root@redis01 ~]# redis-cli -p 6381
127.0.0.1:6381> 

#4.从节点加入主节点
127.0.0.1:6381> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6379> info replication  #查看集群信息
# Replication
role:master
connected_slaves:0
master_replid:847d3c77d3c9b1fab59a1b2cf8f2e64c8e300655
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

#5.撤销集群主节点
SLAVEOF NO ONE
config set masteruser  #从节点设置主节点用户命令
config get masteruser  #从节点查看主节点用户命令
[root@redis01 conf]# cp redis.conf  redis-6381.conf 
[root@redis01 conf]# ll
total 256
-rw-r--r-- 1 root root 84979 Jul 20 16:32 redis-6380.conf
-rw-r--r-- 1 root root 84979 Jul 20 16:33 redis-6381.conf
-rw-r--r-- 1 root root 84979 Jul 20 16:20 redis.conf
-rw-r--r-- 1 root root    32 Jul 20 16:20 user.acl
#改配置文件对应端口号
[root@redis01 conf]# vim redis-6380.conf
port 6380
[root@redis01 conf]# vim redis-6381.conf 
port 6381
#将三个配置文件中aclfile一行内容注释掉

4.主从复制的原理

# 1、主从复制过程大体分为3个阶段:
1、连接建立阶段(即准备阶段)
2、数据同步阶段
3、命令传播阶段
# 2、在从节点执行slaveof命令后,复制过程便开始按下面的流程运作:
  1、保存主节点信息:
    配置slaveof之后会在从节点保存主节点信息
  2、主从建立socket连接:
    定时发现主节点以及尝试建立连接
   3、发送ping命令:
    从节点定时发送 ping 给主节点,主节点返回 PONG。若主节点没有返回 PONG 或因阻 塞无法响应导致超时,则主从断开,在下次定时任务时会从新 ping 主节点
   4、权限验证:
    若主节点开启了 ACL 或配置了 requirepass 参数,则从节点需要配置 masteruser 和 masterauth 参数才能保证主从正常连接(密码主从)
   5、同步数据集:
    首次连接,全量同步
   6、命令持续复制:
    全量同步完成后,保持增量同步
# 3、当节点被当做从节点的时候,需要注意将从节点设置为只读,这样做的目的是为了保证集群的数据一致性。
5.全量复制与部分复制
1、全量复制
redis 全量复制的原理是,首先将 master 本身的 RDB 文件同步给 slave,而在同步期间,master 写入的命令 也会记录下来(master 内部有一个复制缓冲区,会记录同步时 master 新增的写入),当 slave 将 RDB 加载完后, 会通过偏移量的对比将这期间 master 写入的值同步给 slave

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Writ1oLS-1621299654590)(C:\Users\17155\AppData\Roaming\Typora\typora-user-images\1621223800443.png)]

2、部分复制
当 master 和 slave 断开连接时,master 会将期间所做的操作记录到复制缓存区当中(可以看成是一个队列, 其大小默认 1M)。待 slave 重连后,slave 会向 master 发送 psync 命令并传入 offset 和 runId,这时候,如果 master 发现 slave 传输的偏移量的值,在缓存区队列范围中,就会将从 offset 开始到队列结束的数据传给 slave,从而达 到同步,降低了使用全量复制的开销
6.全量复制的开销
bgsave 的开销,每次 bgsave 需要 fork 子进程,对内存和 CP的开销很大
RDB 文件网络传输的时间(网络带宽)
从节点清空数据的时间
从节点加载 RDB 的时
可能的 AOF 重写时间(如果我们的从节点开启了 AOF,则加载完 RDB 后会对 AOF 进行一个重写,保证 AOF 是最新的)
7.主从复制存在的问题
# 1、手动故障转移
# 2、写能力和存储能力受限

二、哨兵

哨兵(sentinel),用于对主从结构中的每一台服务器进行监控,当主节点出现故障后通过投票机制来挑选 新的主节点,并且将所有的从节点连接到新的主节点上。前面的主从是最基础的提升 Redis 服务器稳定性的一种 实现方式,但我们可以看到 master 节点仍然是一台,若主节点宕机,所有从服务器都不会有新的数据进来,如何让主节点也实现高可用,当主节点宕机的时候自动从从节点中选举一台节点提升为主节点就是哨兵实现的功能。
1.作用
# 1、监控:
监控主从节点运行情况
# 2、通知:
当监控节点出现故障,哨兵之间进行通讯
# 3、自动故障转移:
当监控到主节点宕机后,断开与宕机主节点连接的所有从节点,然后在从节点中选取一个作为主节点,将其他的从节点连接到这个最新的主节点。最后通知客户端最闲的服务地址
2.哨兵的工作方式
1.每个 Sentinel 以每秒钟一次的频率向它所知的 Master,Slave 以及其他 Sentinel 实例发送一个 PING 命令。
2.如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 own-after-milliseconds 选项所指定 的值,则这个实例会被 Sentinel 标记为主观下线。(主观下线不影响其他功能)
3.如果一个 Master 被标记为主观下线,则正在监视这个 Master 的所有 Sentinel 要以每秒一次的频率确认 Master 的确进入了主观下线状态。
4.当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认 Master 的确进入了主观下 线状态,则 Master 会被标记为客观下线。 (客观下线直接杀死)
5.在一般情况下,每个 Sentinel 会以每 10 秒一次的频率向它已知的所有 Master,Slave 发送 INFO 命令。
6.当 Master 被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会 从 10 秒一次改为每秒一次。
7.若没有足够数量的 Sentinel 同意 Master 已经下线,Master 的客观下线状态就会被移除。 若 Master 重新向Sentinel 的 PING 命令返回有效回复,Master 的主观下线状态就会被移除。
3.哨兵架构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iWQl0N2B-1621299654592)(C:\Users\17155\AppData\Roaming\Typora\typora-user-

4.配置哨兵
#1.配置文件详解:
# 端口
port 26379
# 是否后台启动
daemonize yes
# pid 文件路径
pidfile /var/run/redis-sentinel.pid
# 日志文件路径
logfile "/var/log/sentinel.log"
# 定义工作目录
dir /tmp
# 定义 Redis 主的别名, IP, 端口,这里的 2 指的是需要至少 2 个 Sentinel 认为主 Redis 挂了才最终会
采取下一步行为
# sentinel monitor [集群名称] [集群主节点 IP] [断开] []
sentinel monitor mymaster 127.0.0.1 6379 2
# 如果 mymaster 30 秒内没有响应,则认为其主观失效
sentinel down-after-milliseconds mymaster 30000
# 如果 master 重新选出来后,其它 slave 节点能同时并行从新 master 同步数据的台数有多少个,显然该值
越大,所有 slave 节点完成同步切换的整体速度越快,但如果此时正好有人在访问这些 slave,可能造成读取
失败,影响面会更广。最保守的设置为 1,同一时间,只能有一台干这件事,这样其它 slave 还能继续服务,
但是所有 slave 全部完成缓存更新同步的进程将变慢。
sentinel parallel-syncs mymaster 1
# 该参数指定一个时间段,在该时间段内没有实现故障转移成功,则会再一次发起故障转移的操作,单位毫秒
sentinel failover-timeout mymaster 180000
# 不允许使用 SENTINEL SET 设置 notification-script 和 client-reconfig-script。
sentinel deny-scripts-reconfig yes
#1.添加配置文件
[root@redis01 ~]# cd /usr/local/redis/conf/
[root@redis01 conf]# vim sentinel-26379.conf
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel-26379.pid"
logfile "/var/log/sentinel-26379.log"
dir "/tmp"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 2000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
# sentinel auth-pass mymaster 123
[root@redis01 conf]# vim sentinel-26380.conf 
port 26380
daemonize yes
pidfile "/var/run/redis-sentinel-26380.pid"
logfile "/var/log/sentinel-26380.log"
dir "/tmp"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 2000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

[root@redis01 conf]# vim sentinel-26381.conf 
port 26381
daemonize yes
pidfile "/var/run/redis-sentinel-26381.pid"
logfile "/var/log/sentinel-26381.log"
dir "/tmp"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 2000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

#2.启动
[root@redis01 redis]# ./bin/redis-sentinel ./conf/sentinel-26379.conf 
[root@redis01 redis]# ./bin/redis-sentinel ./conf/sentinel-26380.conf 
[root@redis01 redis]# ./bin/redis-sentinel ./conf/sentinel-26381.conf 

#3.验证
[root@redis01 redis]# ps -ef |grep redis
root       2107      1  0 11:57 ?        00:00:00 ./bin/redis-sentinel *:26379 [sentinel]
root       2113      1  0 11:57 ?        00:00:00 ./bin/redis-sentinel *:26380 [sentinel]
root       2119      1  0 11:57 ?        00:00:00 ./bin/redis-sentinel *:26381 [sentinel]

#4.查看集群主节点监控
[root@redis01 redis]# redis-cli -p 26379
127.0.0.1:26379> sentinel master mymaster
 1) "name"
 2)"mymaster"
 3) "ip"
 4) "127.0.0.1"
 5) "port"
 6) "6379"
 7) "runid"
 8) "50d713000de317940645802862c2d53a6c116189"  #有runid ID号就证明监控成功
5.三个定时任务
# 1.每 10 秒每个 sentinel 会对 master 和 slave 执行 info 命令,这个任务达到两个目的:
a) 发现 slave 节点 b) 确认主从关系
# 2.每 2 秒每个 sentinel 通过 master 节点的 channel 交换信息(pub/sub)。
master 节点上有一个发布订阅的频 道(sentinel:hello)。sentinel 节点通过__sentinel__:hello 频道进行信息交换(对节点的"看法"和自身的信息), 达成共识。
# 3.每 1 秒每个 sentinel 对其他 sentinel 和 redis 节点执行 ping 操作(相互监控),这个其实是一个心跳检测, 是失败判定的依据
6.主观下线与客观下线
1、主观下线
所谓主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断,即 单个 sentinel 认为某个服务下线(有可能是接收不到订阅,之间的网络不通等等原因)。如果服务器在 down-after-milliseconds 给定的毫秒数之内, 没有返回 Sentinel 发送的 PING 命令的回复, 或者返回一个错误, 那么 Sentinel 将这个服务器标记为主观下线(SDOWN )。sentinel 会以每秒一次的频率向所有与其建立了命令 连接的实例(master,从服务,其他 sentinel)发 ping 命令,通过判断 ping 回复是有效回复,还是无效回复来判 断实例时候在线(对该 sentinel 来说是“主观在线”)。sentinel 配置文件中的 down-after-milliseconds 设置了判 断主观下线的时间长度,如果实例在 down-after-milliseconds 毫秒内,返回的都是无效回复,那么 sentinel 回认为 该实例已(主观)下线,修改其 flags 状态为 SRI_S_DOWN。如果多个 sentinel 监视一个服务,有可能存在多个 sentinel 的 down-after-milliseconds 配置不同,这个在实际生产中要注意。
2、客观下线
客观下线(Objectively Down, 简称 ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的服务器下线判断,然后开启 failover。

客观下线就是说只有在足够数量的 Sentinel 都将一个服务器标记为主观下线之后, 服务器才会被标记为客 观下线(ODOWN)。

只有当 master 被认定为客观下线时,才会发生故障迁移。

当 sentinel 监视的某个服务主观下线后,sentinel 会询问其它监视该服务的 sentinel,看它们是否也认为该服 务主观下线,接收到足够数量(这个值可以配置)的 sentinel 判断为主观下线,既任务该服务客观下线,并对其 做故障转移操作。

客观下线条件只适用于主服务器: 对于任何其他类型的 Redis 实例, Sentinel 在将它们判断为下线前不需 要进行协商, 所以从服务器或者其他 Sentinel 永远不会达到客观下线条件。只要一个 Sentinel 发现某个主服务 器进入了客观下线状态, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对失效的主服务器执行自动故障 迁移操
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FikL-09-19

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值