前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis技术知识总结之五——Redis集群模式

Redis技术知识总结之五——Redis集群模式

作者头像
剑影啸清寒
发布2020-07-09 10:21:05
6170
发布2020-07-09 10:21:05
举报
文章被收录于专栏:琦小虾的Binary琦小虾的Binary

接上篇《Redis技术知识总结之四——Redis内存优化》

五. Redis 集群模式

参考地址: 《redis三种模式对比》

Redis 集群模式有三种:主从模式(Redis 2.8 版本之前)、哨兵模式(Redis 3.0 之前)、集群模式(Redis 3.0 之后)。

5.1 主从模式

同 Mysql 主从复制的原因一样,Redis 虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis 支持主从复制,Redis 的主从结构可以采用一主多从,或者级联结构,Redis 主从复制可以根据是否是全量分为全量同步和增量同步。下图为级联结构。

Redis 全量复制一般发生在 Slave 初始化阶段,这是 Slave 需要将 Master 上的所有数据都复制一份。具体步骤如下:

  1. Slave 服务器连接 Master 服务器,发送 SYNC 指令;
  2. Master 服务器接收到 SYNC 指令后,开始执行 BGSAVE 指令,生成 RDB 文件,并使用缓冲区记录生成 RDB 文件的这段时间里执行的所有写命令
  3. Master 服务器 BGSAVE 执行完毕,想所有 Slave 服务器发送快照文件,并在发送期间继续记录被执行的写命令
  4. Slave 服务器收到快照文件后,丢弃所有旧数据,载入收到的快照;
  5. Master 服务器快照发送完毕后,开始向 Slave 服务器发送缓冲区的写命令;
  6. Slave 服务器完成对快照的载入,开始接受发来的写命令请求,并执行来自 Master 缓冲区的写命令。
  7. 优点:
    • 用比较简便的方式实现了读写分离,解决了备份问题,提高了服务器的性能;
  8. 缺点:
    • 所有 Master, Slave 节点都是用 IP 和端口配置的,如果有节点故障下线,不能主动通知其他节点,只能手动修改配置的方式修复;
    • 如果 Master 节点故障,无法做到自动选举 Master 节点,需要手动修复;
    • 无法动态扩容;

5.2 哨兵模式

哨兵 (Sentinal) 的作用是监控 Redis 服务器的状态,可以实现在 Master 节点下线时,将其他 Slave 节点升级为 Master 节点的功能。多个哨兵可以监控同一个 Redis 节点,哨兵与哨兵之间也可以相互监视。

5.2.1 哨兵的工作原理

哨兵进程启动后,会读取配置文件内容,查找到 Master 服务器的 IP 与端口,与 Master 服务器建立两条连接。此外,只要给哨兵提供多个 Master 服务器的信息,就能实现一个哨兵监控多个 Master 服务器。

与 Master 服务器建立连接后,哨兵会按照一定频率执行三个操作:

  1. 定期向 Master 节点发送 INFO 命令;
    • 用于发现 Master 及其 Slave 节点信息,实现节点加入的自动发现;
  2. 定期向 Master 和其 Slave 节点的哨兵频道发送自己的信息;
    • 向 Master, Slave 共享自己的信息,用来让其他哨兵通过这些信息发现自己,这样就可以接收到其他哨兵给自己发的 PING 信息;此外,其他哨兵可以通过该信息判断 master 版本,如果当前哨兵的版本更高,则进行更新;
  3. 定期向 Master, Slave 和其他哨兵发送 PING 信息,监控它们是否已经停止服务;
    • 如果 PING 的节点超时没有回复,则哨兵认为该节点主观下线
    • 如果被哨兵认为主观下线的节点是 Master 节点,则会向其他哨兵进行询问,是否它们认为该 Master 节点主观下线。如果有半数以上的哨兵认为 Master 节点主观下线,则哨兵会认为该 Master 节点客观下线,并开始执行选举。

认为 Master 节点客观下线后,故障恢复的操作需要一个领头的哨兵执行。选举采用 RAFT 算法:

  1. 发现 master 下线的哨兵节点(我们称他为 A),向每个哨兵发送命令,要求对方选自己为领头哨兵;
  2. 如果目标哨兵节点没有选过其他人,则会同意选举 A 为领头哨兵;
  3. 如果有超过一半的哨兵同意选举 A 为领头,则 A 当选;
  4. 如果有多个哨兵节点同时参选领头,此时有可能存在一轮投票无竞选者胜出,此时每个参选的节点等待一个随机时间后再次发起参选请求,进行下一轮投票精选,直至选举出领头哨兵;

选出领头哨兵后,领头者开始对进行故障恢复,从出现故障的 master 的从数据库中挑选一个来当选新的 master,选择规则如下:

  1. 所有在线的 slave 中选择优先级最高的,优先级可以通过 slave-priority 配置;
  2. 如果有多个最高优先级的 slave,则选取复制偏移量最大(即复制越完整)的当选;
  3. 如果以上条件都一样,选取 id 最小的 slave;

挑选出需要继任的 slave 后,领头哨兵向该节点发送命令,使其升格为 master,然后再向其他 slave 发送命令接受新的 master,最后更新数据。此外,已经停止的旧的 master 更新为新的 master 的从数据库,使其恢复服务后以 slave 的身份继续运行。

优点:

  1. Master 状态监测
  2. 如果 Master 异常,则会进行 Master-slave 转换,将其中一个 Slave 作为 Master,将之前的 Master 作为 Slave;
  3. Master-Slave 切换后,master_redis.conf、slave_redis.conf 和sentinel.conf 的内容都会发生改变,即 master_redis.conf 中会多一行 slaveof 的配置,sentinel.conf 的监控目标会随之调换;

缺点:

  1. 如果是从节点下线了,sentinel 是不会对其进行故障转移的,连接从节点的客户端也无法获取到新的可用从节点;
  2. 无法实现动态扩容;

5.3 集群模式

5.3.1 Redis 集群结构

Redis 集群模式如下图所示,每一个蓝色的圈都代表着一个 redis 的服务器节点,它们任何两个节点之间都是相互连通的,每一个节点都存有这个集群所有主节点以及从节点的信息。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。

一般集群建议搭建三主三从架构,三主提供服务,三从提供备份功能。

5.3.2 集群投票机制

Redis 节点之间通过互相的 ping-pong 判断是否节点可以连接上。如果有一半以上的节点去 ping 一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。这就是 Redis 的投票机制,具体原理如下图所示:

投票过程是集群中所有 master 参与,如果半数以上 master 节点与某个 master 节点通信超时 (cluster-node-timeout),认为该 master 节点挂掉。

整个集群不可用的判断条件:

  1. 如果集群任意 master 挂掉,且当前 master 没有 slave,这样该 master 无法转移,则集群进入 FAIL 状态;
    • 也可以理解成集群的 slot 映射 0-16383 不完整时进入 FAIL 状态;
  2. 如果集群超过半数以上 master 挂掉,无论是否有 slave,集群进入 FAIL 状态.

5.3.3 Redis 集群插槽分配

在集群模式下,通过 cluster info 命令可以查看集群的信息,包括每个 Redis 节点的 ID、IP+端口、身份 (master/slave)、连接数量、分配插槽 (slot) 信息。

以执行命令 set abc 123 为例,Redis 将数据存到集群中的步骤如下:

  1. 客户端发送命令set abc 123,某个 Redis 节点接收到命令;
  2. 通过方法 key(“abc”) 计算出 slot 值,根据 slot 值找到对应的 Redis 节点;
    • “abc” 的 slot 值为 7638;
  3. 重定向到该 Redis 节点,执行命令;

注:插槽与 key 的关系: key 的有效部分使用 CRC16 算法,计算出 Hash 值,然后对 16384 取余获得 slot 值。有效部分指:

  1. key 值中有大括号 {} 的情况:例如 key={hello}_grq 中的 “hello”;
  2. 如果没有大括号,则整个 key 都是有效部分;

5.3.4 Redis slot 重分配

Redis 集群提供了 16384 个 slot,通过 Ruby 脚本 redis-trib.rb 实现 slot 平均分配给 N 个 master 节点。如果有一部分 slot 没有指定到节点,那么分配在这部分 slot 上的 key 值将不能使用。

但如果向集群中加入新的 master 节点,或者将某个 master 节点删除,则需要通过执行 redis-trib.rb 脚本实现 slot 的重分配。

5.3.4.1 新增节点

新增节点后,实现 slot 重分配的步骤如下:

  1. 执行 ruby 脚本 redis-trib.rb add-node {待添加节点 IP + 端口}
    • 添加成功后,新添加的节点没有被分配 slot;
  2. 执行 redis-trib reshard + {待分配目的节点} 脚本命令,执行重分配操作;命令执行过程中,输入要移动的 slot 数、待分配目的节点 ID,以及从哪里分配节点(如果写 “all”,则将所有 master 节点的部分 slot 共同分配给该节点);
  3. 执行完毕;
5.3.4.2 删除节点

删除节点实现 slot 重分配步骤如下:

  1. 用 ruby 脚本将待删除节点的 slot 分配给其他 master 节点;
  2. 执行 ruby 脚本命令 redis-trib.rb del-node {待删除节点 IP + 端口} {待删除节点 ID}
  3. 执行完毕;

5.3.5 Redis 集群注意事项

  1. 多件命令操作(如 MGET, MSET),如果每一个 Key 都位于同一个节点,则可以正常支持,否则会提示错误;
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-07-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 五. Redis 集群模式
    • 5.1 主从模式
      • 5.2 哨兵模式
        • 5.2.1 哨兵的工作原理
      • 5.3 集群模式
        • 5.3.1 Redis 集群结构
        • 5.3.2 集群投票机制
        • 5.3.3 Redis 集群插槽分配
        • 5.3.4 Redis slot 重分配
        • 5.3.5 Redis 集群注意事项
    相关产品与服务
    云数据库 Redis
    腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档