【Java八股学习】Redis高可用 思维导图

在这里插入图片描述

说明

文章内容通过学习小林Coding内的优质文章后整理而来,整理成思维导图的方式是为了帮助自己理解、记忆和复习。如若侵权请联系删除,再次对小林Coding内的优质文章表示感谢。参考文章如下:

思维导图会不断修改完善,下方的文字内容不一定会跟着修改,请大家以思维导图的内容为准。

Redis高可用

Redis部署方式

单服务器部署

  • 宕机,需要时间恢复,期间无法提供服务
  • 硬盘损坏,数据丢失

多服务器部署

  • 一台服务器出问题,其他服务器还能提供服务

  • 有什么问题

    • 服务器之间的数据如何保持一致
    • 数据的读写操作在服务器间如何分配
  • 问题如何解决

    • 交给主从复制

主从复制

是什么

  • 主从服务器使用读写分离方式,主可读写,从只读
  • 主发生写操作时自动将写操作同步给从

有什么用

  • 保证主从服务器的数据一致性

怎么确定主从关系

  • B服务器执行下面命令,就变成A服务器的从节点
  • replicaof <A 的 IP 地址> < A 的 Redis 端口号>

第一次同步

  • 为什么

    • 刚建立主从关系时,主从服务器的数据不一致,需要进行第一次同步
  • 什么步骤

      1. 建立链接、协商同步
      • 从执行 replicaof 命令后,就会给主发送 psync 命令

        • psync表示要进行数据同步

        • psync包含两参数

          • runID

            • 每个Redis服务器在启动时会生成一个随机runID来标识自己
            • 第一次同步,从不知道主的runID,因此设置为 ?
          • offset

            • 表示复制的进度
            • 第一次同步设置为-1
      • 主收到psync命令后,将 FULLRESYNC 作为响应命令返回给对方

        • FULLRESYNC返回两参数

          • 主的runID
          • 主的复制进度offset
      • 从收到响应之后,记录相应的参数

      1. 主同步全量数据给从
      • 步骤

        • 主执行 bgsave 命令fork子进程来生成 RDB 文件并发送给从
        • 从收到 RDB 文件后,先清空当前数据,后载入 RDB 文件
      • 问题

        • 在生产RDB文件期间,主收到的写操作不会写到RDB文件中,主从数据会不一致

        • 解决

          • 主在这三个时间间隙中将收到的写操作命令,写入到replication buffer里

            • 主生成RDB文件期间
            • 主发送RDB给从期间
            • 从加载RDB文件期间
      1. 主发送新写操作命令给从
      • 从载入RDB文件后,回复一个确认消息给主
      • 主将replication buffer里的写操作命令发送给从来执行,这时主从的数据就一致了

命令传播

  • 是什么

    • 主从完成第一次同步后,双方会维护一个 TCP 长连接,后续主通过该连接继续将写操作命令传播给从来执行,使主从数据一致

增量复制

  • 为什么需要增量复制

    • 主从服务器在命令传播时,网络连接不一定永远稳定,若网络不稳定,部分写操作命令同步失败,主从的数据就会不一致

    • 断开的网络恢复正常后,怎么重新保证主从的数据一致

      • Redis2.8前:主从重新进行数据全量复制,性能不好
      • Redis2.8后:使用增量复制,把网络断开期间的写操作命令同步给从
  • 过程

      1. 从恢复网络后,发送 psync 命令给主,此时 psync 命令里的offset不是 -1
      1. 主收到 psync 命令后,用 CONTINUE 响应命令告诉从将采用增量复制的方式同步数据
      1. 主将主从服务器断线期间,所执行的写命令发送给从执行
  • 问题

    • 主怎么知道那些是增量数据

      • 存储相关信息

        • repl_backlog_buffer

          • 一个环形缓冲区,用于主从断连后,从中找到差异的数据
        • replication offset

          • 标记环形缓冲区的同步进度

            • 主使用 master_repl_offset 记录自己写到的位置
            • 从使用 slave_repl_offset 记录自己读到的位置
      • 主进行命令传播时,不仅会将写命令发送给从,还会将写命令写入到 repl_backlog_buffer ,因此缓冲区里会保存着最近传播的写命令

      • 当从重新连上主服务器时,从通过 psync 命令将slave_repl_offset 发送给主,主根据 master_repl_offset 和 slave_repl_offset 之间的差距来决定对从服务器执行哪种同步操作

        • 从要读取的数据还在 repl_backlog_buffer 里,使用增量同步
        • 从要读取的数据不在 repl_backlog_buffer 里,使用全量同步
      • repl_backlog_buffer 默认大小是 1M,因其是环形缓冲区,当缓冲区写满后,主继续写入的话,就会覆盖之前的数据。若从想读的数据被覆盖,就只能进行全量同步,性能损耗较大

        • 优化:调整repl_backlog_buffer大小,降低覆盖概率

        • 设置多大?

          • sw(保险起见,可以设置为2sw)
          • s:从断线后重新连接主所需的平均秒数
          • w:主平均每秒产生的写命令数据量大小
        • 怎么设置

          • 修改redis.conf
          • repl-backlog-size 1mb

经理角色分摊主服务器的压力

  • 为什么要分摊

    • 主从在第一次数据同步的过程中,主会生成 RDB 文件和传输 RDB 文件,这两个操作比较耗时

      • 主生成 RDB 文件时,会忙于使用 fork() 创建子进程,如果主的内存数据非常大,执行 fork() 函数时会阻塞主线程,使得 Redis 无法正常处理请求
      • 传输 RDB 文件会占用主的网络带宽,影响主响应命令请求
  • 怎么分摊

    • 从有自己的从节点,将拥有从节点的从当作经理角色,它不仅接收主的同步数据,同时作为主将数据同步给自己的从节点
  • 怎么操作

    • 服务器执行下面命令,将其作为经理服务器的从节点。执行完成之后,经理就会将数据同步给自己的从节点
    • replicaof <想作为经理的IP> <Redis端口>

哨兵机制

为什么需要哨兵机制

  • 主从模式是读写分离的,如果主节点挂了,则没法服务客户端的写请求,也没有主节点给从节点同步数据。
  • 如果需要恢复服务,需要人工介入,恢复主节点或将一个从节点改为主节点。需要一套更加智能的方式
  • Redis2.8后提供哨兵模式,可检测主节点是否存活,若主节点挂了,则重新推举一个从节点成为主节点,并且把新主节点的相关信息通知给从节点和客户端(主从故障迁移)

哨兵介绍

  • 是什么

    • 哨兵其实是一个运行在特殊模式下的 Redis 进程
  • 做什么

    • 监控主从节点的状态
    • 选主
    • 通知

如何判断主节点是否故障

  • 主节点主观下线

    • 哨兵节点每隔 1 秒给所有主从节点发送 PING 命令,当主从节点收到 PING 命令后,会发送一个响应命令给哨兵,如果主节点或者从节点没有在规定的时间内响应,哨兵就会将它们标记为【主观下线】
    • 规定时间设置: 修改哨兵配置文件的down-after-milliseconds,单位是毫秒
  • 主节点客观下线

    • 可能主节点没有故障,只是因为主节点的系统压力比较大或者网络发送了拥塞,导致没有在规定时间内响应哨兵的 PING 命令(会造成误判)

    • 为了减少误判,针对主节点还设置了【客观下线】状态,即经过集群投票(让多个哨兵一起判断,避免单个哨兵自身网络不好误判主节点下线)认定的下线为【客观下线】(单个节点判断的为【主观下线】)

    • 投票步骤

      • 当一个哨兵判断主节点为【主观下线】后,向其他哨兵发起is-master-down-by-addr 命令,其他哨兵收到这个命令后,就会根据自身和主节点的网络状况,做出赞成投票或者拒绝投票的响应
      • 当这个哨兵的赞同票数达到哨兵配置文件中的 quorum 配置项设定的值后,这时主节点就会被【该哨兵】标记为【客观下线】(如集群中有三个哨兵,quorum为2,则三个哨兵中至少需要两个赞成,发起投票者也算赞成)
      • quorum 一般设置为(哨兵个数/2)+ 1

哪个哨兵进行主从故障转移

  • 在判断主节点客观下线后,由哪个节点(Leader)来进行主从故障转移?

  • 候选者

    • 那个将主节点标记为【客观下线】的节点,其实就是第一个判断主节点为【主观下线】的节点
    • 如果某个时间点有两个哨兵节点判断到主节点为客观下线,则有两个候选者
  • Leader选举

    • 候选者会让其他哨兵对它进行投票,每个哨兵只有一次投票机会,候选者可以投给自己

    • 多个候选者,哨兵投给谁?

      • 先收到谁的命令,就投给谁(先到先得)
    • 需要满足

        1. 拿到半数以上(大于半数)的赞成票
        1. 拿到的票数需要大于等于哨兵配置文件中的 quorum 值
      • 注意:候选者会默认给自己投一票,没有则需要重新选举
    • 为什么哨兵节点至少要有 3 个

      • 哨兵集群中只有 2 个哨兵节点,此时如果一个哨兵想要成功成为 Leader,必须获得 2 票,只要挂一个,就没办法进行主从节点切换
      • 哨兵集群中有 3 个哨兵节点,要挂一个,还是有机会投票成功。挂两个就需要人工介入
    • 为什么 quorum 设置为(哨兵个数/2)+ 1

      • 如集群有三个节点,其中两个节点宕机,quorum设置为1
      • 这时可以完成客观下线,却不能完成主从切换,因此quorum设置为1没有意义

主从故障转移的过程

  • 挑选从节点

    • 做什么

      • 在已下线主节点属下的所有从节点里面,挑选出一个状态良好、数据完整的从节点,给其发送SLAVEOF no one命令将其转换为主节点
    • 怎么做

        1. 过滤掉下线和网络状态不好的节点
        • Redis 有个叫 down-after-milliseconds * 10 配置项,其 down-after-milliseconds 是主从节点断连的最大连接超时时间。如果在 down-after-milliseconds 毫秒内,主从节点都没有通过网络联系上,我们就可以认为主从节点断连了。如果发生断连的次数超过了 10 次,就说明这个从节点的网络状况不好,不适合作为新主节点
        1. 优先级最高的从节点胜出
        • Redis 有个叫 slave-priority 配置项,可以根据服务器配置给从节点设置优先级
        1. 复制进度最靠前的从节点胜出
        • 如果某个从节点的 slave_repl_offset 最接近 master_repl_offset,说明它的复制进度是最靠前的
        1. ID 号小的从节点胜出
        • 每个从节点都有一个编号,这个编号就是 ID 号,是用来唯一标识从节点的
  • 被挑选从节点转化为主节点

    • 哨兵 leader 向被选中的从节点发送 SLAVEOF no one 命令,让这个从节点解除从节点的身份,将其变为新主节点
    • 在发送 SLAVEOF no one 命令之后,leader 会以每秒一次的频率向被升级的从节点发送 INFO 命令(没进行故障转移之前,INFO 命令的频率是每十秒一次),并观察命令回复中的角色信息,当被升级节点的角色信息从原来的 slave 变为 master 时, leader 就知道从节点顺利升级为主节点了
  • 将从节点指向新主节点

    • 哨兵 leader 向所有从节点发送 SLAVEOF 命令让它们成为新主节点的从节点
  • 通知客户端主节点更换信息

    • 通过 Redis 的发布者/订阅者机制来实现。每个哨兵节点提供发布者/订阅者机制,客户端可以从哨兵订阅消息
    • 主从切换完成后,哨兵就会向 +switch-master 频道发布新主节点的 IP 地址和端口的消息,客户端收到信息,然后用新主节点的 IP 地址和端口进行通信
    • 通过发布者/订阅者机制机制,客户端不仅可以在主从切换后得到新主节点的连接信息,还可以监控到主从节点切换过程中发生的各个重要事件。有助于客户端了解主从切换进度
    • 事件通知有哪些?
  • 旧主节点上线,将其变为从节点

    • 主从切换后,哨兵集群继续监视旧主节点,当旧主节点重新上线时,哨兵集群就会向它发送 SLAVEOF 命令,让它成为新主节点的从节点

哨兵集群是如何组成

  • 配置哨兵

    • sentinel monitor
  • 哨兵之间相互感知

    • 配置哨兵时,不需要填其他哨兵信息,哨兵节点之间可以通过 Redis 的发布者/订阅者机制来相互发现
    • 在主从集群中,主节点上有一个名为sentinel:hello的频道,不同哨兵就是通过它来相互发现,实现互相通信的
  • 哨兵集群如何知道从节点信息

    • 主节点知道所有从节点信息,所以哨兵会每 10 秒一次的频率向主节点发送 INFO 命令来获取所有从节点的信息
  • 24
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hello Dam

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

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

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

打赏作者

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

抵扣说明:

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

余额充值