首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >016.Redis Cluster通信原理

016.Redis Cluster通信原理

作者头像
CoderJed
发布2020-03-25 17:51:44
1.4K0
发布2020-03-25 17:51:44
举报
文章被收录于专栏:Jed的技术阶梯Jed的技术阶梯

1. 通信流程

分布式系统元数据存储的两种方案

  • 集中式存储,典型产品:Zookeeper
  • 优势:更新效率快
  • 劣势:所有的元数据信息集中在一个外部系统中,这个外部系统的压力很大
  • 使用Gossip协议进行通信
  • 优势:减少了元数据存储压力
  • 劣势:元数据更新有延迟,需等待全部master的元数据达成一致 每个master都会自己维护一份完整的元数据信息,只要自己的元数据有变化,就会发送消息给其他master,通过master之间的两两通信来保持元数据一致

Redis Cluster采用P2P的Gossip协议进行通信,节点之间不断的交换信息,这些信息包括节点负责哪些slot、是否出现故障等信息

  • 集群中的每个节点都会单独开通一个TCP通道,用于节点之间彼此通信,通信端口号为基础端口号+10000,例如10.0.0.100:6379的通信端口号为16379
  • 每个节点在固定周期内通过特定规则选择几个节点发送ping消息
  • 接收到ping消息的节点用pong消息作为响应

集群中的每个节点通过一定的规则挑选要通信的节点,每个节点可能知道其他全部节点,也可能仅知道部分节点,只要这些节点之间可以正常通信,最终它们会达到一致状态,当节点出现故障、新节点加入、主从角色变化、slot信息变更等事件发生时,通过不断的ping/pong消息通信,经过一段时间后所有的节点都会知道整个集群全部节点的最新状态,从而达到集群状态同步的目的。

2. Gossip消息

Gossip消息类型

Gossip协议的主要职责就是信息交换。信息交换的载体就是节点彼此发送的Gossip消息,常用的Gossip消息可分为:ping消息、pong消息、meet消息、fail消息等。

  • meet消息:用于通知新节点加入。消息发送者通知接收者加入到当前集群,meet消息通信正常完成后,接收节点会加入到集群中并进行周期性的ping、pong消息交换。
  • ping消息:集群内交换最频繁的消息,集群内每个节点每秒向多个其他节点发送ping消息,用于检测节点是否在线和交换彼此状态信息。ping消息发送封装了自身节点和部分其他节点的状态数据。
  • pong消息:当接收到ping、meet消息时,作为响应消息回复给发送方确认消息正常通信。pong消息内部封装了自身状态数据。节点也可以向集群内广播自身的pong消息来通知整个集群对自身状态进行更新。
  • fail消息:当节点判定集群内另一个节点下线时,会向集群内广播一个fail消息,其他节点接收到fail消息之后把对应节点更新为下线状态。

Gossip消息中的包含的信息

一个Gossip的消息头中包含的信息:

  • 消息总长度
  • 协议版本
  • 消息类型,用于区分是meet、ping、pong等消息
  • 当前发送消息的节点的配置版本
  • 主/从节点的配置版本
  • 复制偏移量
  • 发送节点的nodeId
  • 发送节点负责的slot信息
  • 如果发送节点是slave,那么还包括对应的master的nodeId
  • 端口号
  • 集群状态
  • 节点标识(主从角色/是否下线等)

消息体包含的信息:

  • 目标节点的nodeId
  • 最后一次向目标节点发送ping消息的时间
  • 最后一次接收目标节点的pong消息时间
  • 目标节点的IP和port
  • 目标节点的标识(主从角色/是否下线等)

一个节点处理ping/meet消息的流程

  • 解析消息头,消息头包含了发送节点的信息
    • 如果发送节点是新节点且消息是meet类型,则加入到本地节点列表
    • 如果是已知节点,则尝试更新发送节点的状态,如槽映射关系、主从角色等状态
  • 解析消息体
    • 如果消息体内包含的节点是新节点,则尝试发起与新节点的meet握手流程
    • 如果是已知节点,则根据消息体中的目标节点的标识判断该节点是否下线,用于故障转移
  • 消息处理完后回复pong消息,内容同样包含消息头和消息体,发送节点接收到回复的pong消息后,采用类似的流程解析处理消息并更新与接收节点最后通信时间,完成一次消息通信

3. 节点选择

虽然Gossip协议的信息交换机制具有天然的分布式特性,但它是有成本的。由于内部需要频繁地进行节点信息交换,而ping/pong消息会携带当前节点和部分其他节点的状态数据,势必会加重带宽和计算的负担。Redis集群内节点通信采用固定频率(定时任务每秒执行10次)。因此节点每次选择需要通信的节点列表变得非常重要。通信节点选择过多虽然可以做到信息及时交换但成本过高。节点选择过少会降低集群内所有节点彼此信息交换频率,从而影响故障判定、新节点发现等需求的速度。因此Redis集群的Gossip协议需要兼顾信息交换实时性和成本开销,通信节点选择的规则如下:

选择发送消息的节点数量

  • 每秒会随机选取5个节点,找出其中最久没有通信的节点发送ping消息,用于保证Gossip信息交换的随机性
  • 每100毫秒都会扫描本地节点列表,如果发现节点最近一次接受pong消息的时间大于cluster_node_timeout/2,则立刻发送ping消息,防止该节点信息太长时间未更新
  • 根据以上规则得出每个节点每秒需要发送ping消息的数量=1+10*num(node.pong_received>cluster_node_timeout/2),因此cluster_node_timeout参数对消息发送的节点数量影响非常大
  • 当我们的带宽资源紧张时,可以适当调大这个参数,如从默认15秒改为30秒来降低带宽占用率。
  • 过度调大cluster_node_timeout会影响消息交换的频率从而影响故障转移、槽信息更新、新节点发现的速度,因此需要根据业务容忍度和资源消耗进行平衡。
  • 整个集群消息总交换量也跟节点数成正比,所以并非redis cluster的节点越多,其性能越好,随着节点数的增多,交换元数据的消耗也会加大

cluster_node_timeout

真实世界的机房网络往往并不是风平浪静的,它们经常会发生各种各样的小问题。比如网络抖动就是非常常见的一种现象,突然之间部分连接变得不可访问,然后很快又恢复正常。为解决这种问题,Redis Cluster 提供了一个配置选项cluster-node-timeout ,表示当某个节点持续 timeout 的时间失时,才可以认定该节点出现故障,需要进行主从切换。如果没有这个选项,网络抖动会导致主从频繁切换 (数据的重新复制)。

还有另外一个选项cluster-slave-validity-factor作为倍乘系数来放大这个超时时间来宽松容错的紧急程度。如果这个系数为零,那么主从切换是不会抗拒网络抖动的,即cluster-slave-validity-factor=0cluster-node-timeout配置实效,只要一发现某个节点失联,立马进行主从切换;如果这个系数大于 0,它就成了主从切换的松弛系数,cluster-node-timeout * cluster-slave-validity-factor的时间,将作为主从切换之间的最大容忍时间,例如cluster-node-timeout=5000,cluster-slave-validity-factor=3,那么在一个节点失联15s之后,才可以进行主从切换。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 通信流程
    • 分布式系统元数据存储的两种方案
    • 2. Gossip消息
      • Gossip消息类型
        • Gossip消息中的包含的信息
          • 一个节点处理ping/meet消息的流程
          • 3. 节点选择
            • 选择发送消息的节点数量
              • cluster_node_timeout
              相关产品与服务
              云数据库 Redis
              腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档