Redis④ —— 高可用

1. 主从复制

  • 一主多从模式,采用读写分离的方式
  • 主服务器可以进行读写操作,当发生写操作时自动将写操作同步给从服务器,而从服务器一般是只读,并接受主服务器同步过来写操作命令,然后执行这条命令。
  • 主从服务器之间的命令复制是异步进行的

1.1 第一次同步

  • 建立连接、协商同步
    • 主服务器会把所有的数据都同步给从服务器(全量复制)。
  • 主服务器同步数据给从服务器
    • 主服务器会执行 bgsave 命令来生成 RDB 文件,然后把文件发送给从服务器
    • 从服务器收到 RDB 文件后,会先清空当前的数据,然后载入 RDB 文件(异步)
    • 为了保证主从服务器的数据一致性,主服务器在下面这三个时间间隙中将收到的写操作命令,写入到 replication buffer 缓冲区里
      • 主服务器生成 RDB 文件期间;
      • 主服务器发送 RDB 文件给从服务器期间;
      • 从服务器加载 RDB 文件期间;
  • 主服务器发送新写操作命令给从服务器
    • 主服务器将 replication buffer 缓冲区里所记录的写操作命令发送给从服务器,从服务器执行来自主服务器 replication buffer 缓冲区里发来的命令,这时主从服务器的数据就一致了

1.2 命令传播

  • 主从服务器在完成第一次同步后,双方之间就会维护一个 TCP 连接。
  • 连接是长连接的,目的是避免频繁的 TCP 连接和断开带来的性能开销

1.3 分摊主服务器的压力

  • 从服务器可以有自己的从服务器,可以把拥有从服务器的从服务器当作经理角色,它不仅可以接收主服务器的同步数据,自己也可以同时作为主服务器的形式将数据同步给从服务器
  • 通过这种方式,主服务器生成 RDB 和传输 RDB 的压力可以分摊到充当经理角色的从服务器

1.3.1 增量复制

  • 网络断开又恢复后,从主从服务器会采用增量复制的方式继续同步,也就是只会把网络断开期间主服务器接收到的写操作命令,同步给从服务器。
  • 主服务器怎么知道要将哪些增量数据发送给从服务器呢
    • repl_backlog_buffer ,是一个「环形」缓冲区,用于主从服务器断连后,从中找到差异的数据;
    • replication offset ,标记上面那个缓冲区的同步进度,主从服务器都有各自的偏移量,主服务器使用 master_repl_offset 来记录自己「 」到的位置,从服务器使用 slave_repl_offset 来记录自己「」到的位置。
  • 如果判断出从服务器要读取的数据还在 repl_backlog_buffer 缓冲区里,那么主服务器将采用增量同步的方式;
  • 相反,如果判断出从服务器要读取的数据已经不存在 repl_backlog_buffer 缓冲区里,那么主服务器将采用全量同步的方式。

2. 哨兵机制

  • 实现主从节点故障转移。它会监测主节点是否存活,如果发现主节点挂了,它就会选举一个从节点切换为主节点,并且把新主节点的相关信息通知给从节点和客户端
  • 哨兵其实是一个运行在特殊模式下的 Redis 进程,相当于是"观察者节点",观察的对象是主从节点。
  • 主要负责三件事情:监控、选主、通知
  • 哨兵节点通过 Redis 的发布者/订阅者机制,哨兵之间可以相互感知,相互连接,然后组成哨兵集群,同时哨兵又通过 INFO 命令,在主节点里获得了所有从节点连接信息,于是就能和从节点建立连接,并进行监控了。
  • 流程:
    • 判断主节点下线
      • 某个哨兵判定主节点下线(主观下线)后,就会向其他哨兵发起命令,其他哨兵收到这个命令后,就会根据自身和主节点的网络状况,做出赞成投票或者拒绝投票的响应。当赞成数到达预定值后,标记为客观下线
    • 选出哨兵leader
      • 拿到半数以上的赞成票
      • 拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值
    • 哨兵leader进行主从故障转移
      • 在已下线主节点(旧主节点)属下的所有「从节点」里面,挑选出一个从节点,并将其转换为主节点,选择的规则:
        • 过滤掉已经离线的从节点
        • 过滤掉历史网络连接状态不好的从节点
        • 将剩下的从节点,进行三轮考察:优先级、复制进度、ID 号。在每一轮考察过程中,如果找到了一个胜出的从节点,就将其作为新主节点
      • 让已下线主节点属下的所有「从节点」修改复制目标,修改为复制「新主节点」
      • 将新主节点的 IP 地址和信息,通过「发布者/订阅者机制」通知给客户端
      • 继续监视旧主节点,当这个旧主节点重新上线时,将它设置为新主节点的从节点

3. 切片集群模式

  • 当 Redis 缓存数据量大到一台服务器无法缓存时,就需要使用 Redis 切片集群方案,它将数据分布在不同的服务器上,以此来降低系统对单主节点的依赖,从而提高 Redis 服务的读写性能。
  • 采用哈希槽(Hash Slot),来处理数据和节点之间的映射关系。一个切片集群共有 16384 个哈希槽 ,这些哈希槽类似于数据分区,每个键值对都会根据它的 key,被映射到一个哈希槽中
    • 根据键值对的 key,按照 CRC16 算法 计算一个 16 bit 的值
    • 再用 16bit 值对 16384 取模,得到 0~16383 范围内的模数,每个模数代表一个相应编号的哈希槽
  • 哈希槽怎么被映射到具体的 Redis 节点上的呢
    • 平均分配: 在使用 cluster create 命令创建 Redis 集群时,Redis 会自动把所有哈希槽平均分布到集群节点上。比如集群中有 9 个节点,则每个节点上槽的个数为 16384/9 个。
    • 手动分配: 可以使用 cluster meet 命令手动建立节点间的连接,组成集群,再使用 cluster addslots 命令,指定每个节点上的哈希槽个数。
      • 在手动分配哈希槽时,需要把 16384 个槽都分配完,否则 Redis 集群无法正常工作

4. 集群脑裂

4.1 什么是脑裂?

  • 由于网络问题,主节点与从节点失联,但是主节点与客户端网络正常,客户端仍然向主节点写数据,但是此时主节点无法同步数据给从节点。哨兵模式选举新的leader作为主节点,这时集群有两个主节点了。

4.2 为什么集群脑裂会导致数据丢失?

  • 网络好了之后,哨兵会把原来的主节点降级为从节点,然后从节点会向新的主节点请求数据同步。
  • 第一次同步是全量同步,该从节点会清除自己本地的数据,然后再全量同步。这样会导致客户端之前写入的数据都丢失了

4.3 如何解决

  • 当主节点发现从节点下线或者通信超时的总数量小于阈值时,那么禁止主节点进行写数据,直接把错误返回给客户端。
  • 等到新主库上线时,就只有新主库能接收和处理客户端请求,此时,新写的数据会被直接写到新主库中。而原主库会被哨兵降为从库,即使它的数据被清空了,也不会有新数据丢失。
相关推荐
旺仔学长 哈哈11 分钟前
Spring Boot 智能停车场管理系统---附源码+数据库文档
数据库·spring boot·后端·智能停车场
ClickHouseDB28 分钟前
ClickHouse托管Postgres:OLTP+OLAP,新能力解锁最佳数据平台
java·前端·数据库
数智化管理手记1 小时前
主数据重复、错漏频发?一站式主数据管理平台如何落地?
大数据·运维·数据库·人工智能·数据挖掘
吴声子夜歌1 小时前
MongoDB 4.2——选择片键
数据库·mongodb
天天进步一点点2 小时前
QSqlQuery删除sqlite数据库执行drop数据表报错database table is locked unable to fetch row问题
数据库·oracle·sqlite
音视频工程实战2 小时前
PromptQL 新手入门与实战指南
数据库·sql·算法
清川渡水2 小时前
NL2SQL 的正确打开方式:从「AI 猜 SQL」到「置信度闭环」的工程化落地
数据库·人工智能·sql
TDengine (老段)2 小时前
TDengine Go 与 Rust 连接器 — 高性能异步访问
大数据·数据库·物联网·golang·rust·时序数据库·tdengine
东方佑3 小时前
MA-RMSNorm:打破“缩放换智能”的魔咒,大模型归一化的一次范式革命!
数据库·人工智能·计算机视觉
云和恩墨3 小时前
「云帆计划·长沙站」活动成功举办,云和恩墨与紫薇垣和湖南金悦科技分别签约并授牌,本地伙伴生态建设加速
数据库·科技