Redis集群的节点通信原理

Redis集群搭建中,数据如何在节点分布的原理,下面来介绍一下节点之间是如何进行通信(节点握手)

一、基础通讯原理

1、维护集群的元数据的两种方案介绍及对比

在分布式存储中需要提供维护节点 元数据信息的机制,所谓元数据是指:节点负责哪些数据,是否出现故障等状态信息。 常见的元数据维护方式分为:集中式和P2P方式

  1. 集中式
  2. 优点 :元数据的更新和读取,时效性非常好,一旦元数据出现了变更,立即就更新到集中式的存储中。
  3. 缺点 :所有的元数据的更新压力全部集中在一个地方,可能导致元数据的存储有压力。
  4. gossip
  5. 优点 :元数据的更新比较分散,不是集中在同一个地方,更新请求会陆陆续续到达所有节点上去更新,有一定的延时,降低了压力。
  6. 缺点 :元数据更新有延时,可能会导致集群的一些操作会有一些滞后。

集中式示例图-1:

集群元数据集中式存储的典型代表就是storm:

Redis集群的节点通信原理

集中式示例图-2:假如redis cluster采用集中式存储元数据如下图:

Redis集群的节点通信原理

P2P方式的gossip的redis cluster方式示例图-3:

Redis集群的节点通信原理

2、redis cluster节点间采用gossip协议进行通讯

回到redis cluster,Redis集群采用P2P的Gossip(流言)协议,跟集中式不同,不是将集群元数据(节点信息、hashslot->node之间的映射表关系,还有master->slave之间关系,故障的信息等)集中存储在某个节点上,Gossip协议工作原理就是节点彼此不断通信交换信息,一段时间后集群的所有的节点都会有完整的(集群)信息,这种方式类似流言传播

节点之间通信示意图

Redis集群的节点通信原理

3、10000端口

每个节点都有一个专门用于节点间通信的端口号,就是自己提供服务的端口号+10000。每个节点每隔一段时间都会往另外几个节点发送ping消息,同时其他节点接收到ping之后会返回pong消息。

4、节点间交换的信息

包含故障信息,节点的增加和移除,hash slot信息等等。

二、Gossip消息

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

  • meet消息:用于通知新节点加入(某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通信)。消息发送者通知接收者加入到当前集群,meet消息通信正常完成后,接收节点会加入到集群中并进行周期性的ping、pong消息交换
  • 例如:执行redis-trib.rb add-node 命令时,其实内部就是发送了一个gossip meet消息,给新加入的节点,通知那个节点去加入我们的集群
  • ping消息:集群内交换最频繁的消息,集群内每个节点每秒向多个其他节点发送ping消息,用于检测节点是否在线和交换彼此状态信息。ping消息发送封装了自身节点和部分其他节点的状态数据
  • ping消息深入ping很频繁,而且要携带一些元数据,所以可能会加重网络负担 每个节点每秒会执行10次ping,每次会选择5个最久没有通信的其他节点 当然如果发现某个节点通信延时达到了cluster_node_timeout / 2,那么立即发送ping,避免数据交换延时过长,落后的时间太长了 比如说,两个节点之间都10分钟没有交换数据了,那么整个集群处于严重的元数据不一致的情况,就会有问题 所以cluster_node_timeout可以调节,如果调节比较大,那么会降低发送的频率 每次ping,一个是带上自己节点的信息,还有就是带上1/10其他节点的信息,发送出去,进行数据交换 至少包含3个其他节点的信息,最多包含总节点-2个其他节点的信息
  • pong消息:当接收到ping、meet消息时,作为响应消息回复给发送方确认消息正常通信。pong消息内部封装了自身状态数据。节点也可以向集群内广播自身的pong消息来通知整个集群对自身状态进行更新,也可以用于信息广播和更新
  • fail消息:当节点判定集群内另一个节点下线时,会向集群内广播一个fail消息,其他节点接收到fail消息之后把对应节点更新为下线状态

接收节点会解析消息内容并根据自身的识别情况做出相应处理,对应流程:

Redis集群的节点通信原理
  • 解析消息头过程:消息头包含了发送节点的信息,如果发送节点是新节点且消息是meet类型,则加入到本地节点列表;如果是已知节点,则尝试更新发送节点的状态,如槽映射关系、主从角色等状态
  • 解析消息体过程:如果消息体的clusterMsgDataGossip数组包含的节点是新节点,则尝试发起与新节点的meet握手流程;如果是已知节点,则根据cluster MsgDataGossip中的flags字段判断该节点是否下线,用于故障转移

三、节点通讯优化

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

选择发送消息的节点数量

集群内每个节点维护定时任务默认每秒执行10次,每秒会随机选取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会影响消息交换的频率从而影响故障转移、槽信息更新、新节点发现的速度。因此需要根据业务容忍度和资源消耗进行平衡。同时整个集群消息总交换量也跟节点数成正比。

消息数据量

每个ping消息的数据量体现在消息头和消息体中,其中消息头主要占用空间的字段是myslots[CLUSTER_SLOTS/8],占用2KB,这块空间占用相对固定。消息体会携带一定数量的其他节点信息用于信息交换,消息体携带数据量跟集群的节点数息息相关,更大的集群每次消息通信的成本也就更高,因此对于Redis集群来说并不是大而全的集群更好

Redis集群的节点通信原理

四、面向集群的jedis内部实现原理

1.基于重定向的客户端
redis-cli c,自动重定向

①请求重定向
客户端可能会挑选任意一个redis实例去发送命令,每个redis实例接收到命令之后,都会接受key对应的hash slot,如果在本地就在本地处理,否则返回moved给客户端,让客户端进行重定向。
cluster keyslot mykey ,可以查看一个key对应的hash slot是什么。
用redis-cli的时候,可以加入-c参数,支持自动的请求重定向,redis-cli接收到moved之后,会自动重定向到对应的节点执行命令。

②计算hash slot
计算hash slot的算法,就是根据key计算CRC16值,然后对16384取模,拿到对应的hash slot。
用hash tag可以手动指定key对应的slot,同一个hash tag下的key,都会在一个hash slot中,比如set mykey1:{100}和set mykey2:{100}。

③hash slot查找
节点间通过gossip协议进行数据交换,就知道每个hash slot在那个节点上面了

2.smart jedis
①什么是smart jedis:
基于重定向的客户端,很消耗网络IO,因为大部分情况下,可能都会出现一次请求重定向,才能找到正确的节点。

所以大部分的客户端,比如java redis客户端,就是jedis,都是smart的。

本地维护一份hashslot -> node的映射表,缓存,大部分情况下,直接走本地缓存就可以找到hashslot -> node,不需要通过节点进行moved重定向。

②JedisCluster的工作原理
A:在JedisCluster初始化的时候,就会随机选择一个node,初始化hash slot到node的映射表,同时为每个节点创建一个JedisPool连接池。
B:每次基于JedisCluster执行操作,首先会在本地计算key的hash slot,然后在本地映射表中找到节点。
C:如果那个node真好还是持有那个hash slot,那么就OK。
D:如果JedisCluster API返回的是moved,那么利用该节点的数据,更新本地的hash slot 和node的映射表。
E:重复上面的步骤,知道找到对应的节点,如果重试超过5次,就会报错,抛出JedisClusterMaxRedirectionException异常。

jedis老版本,可能会出现在集群某个节点故障还没完成自动切换恢复时,频繁更新hash slot,频繁ping节点检查活跃,导致大量网络IO开销。

jedis最新版本,对于这些过度的hash slot更新和ping,都进行了优化,避免了类似问题。

③hash slot迁移和ask重定向
A:如果hash slot正在进行迁移,那么会返回ask重定向给jedis,
B:jedis接收到ask重定向之后,会重新定位到目标节点去执行。
C:但是因为ask发生在hash slot迁移过程中,所以收到ask是不会更新hash slot本地缓存。
D:已经可以确定说hash slot已经迁移完了,moved是会更新本地hash slot到node的映射缓存的。

(3)高可用与主备切换原理

redis cluster的高可用原理,几乎和哨兵时类似的。
1.判断节点宕机
①如果一个节点认为另一个节点道济,那么就是pfail,主观宕机。

②如果多个节点都认为另外一个 节点宕机了,那就是fail,客观宕机。

③在cluster-node-timeout内,某个几点一直没有返回pong,那么就认为pfail。

④如果一个节点认为某个节点pfail了,那么会在gossip ping消息中,发送给其他节点,如果超过半数的节点都认为pfail了,那就好变成fail。

2.从节点过滤
①对宕机的master node,从其所有的slave node中,选择一个切换成master node。

②检查每个slave node与master node断开连接的时机,如果超过了cluster-node-timeout * cluster-slave-validity-factor,那么这个节点就没有资格切换成 master node,直接被过滤。

3.从节点选举
①每个从几点,都根据自己对master复制数据的offset,来设置一个选举时间,offset越大的从节点,选举时间越靠前,优先进行选举。

②所有的master node开始slave选举投票,给要进行选举的slave进行投票,如果大部分master node(N/2 + 1)都投票给了某个从节点,那么选举通过,那个从节点可以切换成master node。

③从节点执行主备切换,从节点切换为主节点。

4.与哨兵进行比较
整个流程跟哨兵相比,非常类似,所以说,redis cluster功能强大,直接集成了replication和sentinal的功能

https://blog.csdn.net/nihao12323432/article/details/81204499

https://www.cnblogs.com/jack1995/p/10915801.html

Original: https://www.cnblogs.com/duanxz/p/15893958.html
Author: duanxz
Title: Redis集群的节点通信原理

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/528784/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 基于灰色模型和Bootstrap理论的大规模定制质量控制方法研究

    基于GM的生产质量预测: 原始质量指标数列为: 是的累加序列为: 经过该处理,可以使粗糙的原始离散数列变为光滑的离散数列。 建立基本的预测模型GM(1,1),其白化方程为 式中,a…

    Linux 2023年6月14日
    067
  • .NET客户端实现Redis中的管道(PipeLine)与事物(Transactions)

    序言 Redis中的管道(PipeLine)特性:简述一下就是,Redis如何从客户端一次发送多个命令,服务端到客户端如何一次性响应多个命令。 Redis使用的是客户端-服务器模型…

    Linux 2023年5月28日
    0113
  • KVM 虚机镜像操作, 扩容和压缩

    qemu-img命令 创建镜像 qemu-img create 创建一个设备空间大小为10G的镜像 qemu-img create -f qcow2 centos7-guest.q…

    Linux 2023年5月27日
    073
  • Mysql 5.7开启binlog日志

    Mysql 5.7开启binlog日志 前言 binlog是MySQL的二进制日志,并且是MySQL中最重要的日志。binlog记录了对MySQL数据库执行更改的所有操作,包括对数…

    Linux 2023年6月6日
    095
  • Question09-查询学过编号为”01″并且也学过编号为”02″的课程的同学的信息

    * — 学过01,且学过02 — 学过01 SELECT sc.SID FROM SC sc WHERE sc.CID = ’01’; — 学过02 SELECT sc.SI…

    Linux 2023年6月7日
    086
  • 惊了!修仙=编程??

    大家好,我是良许。 印象中,我们接触到的编程书籍都是这样的: 这样的书籍,去除阅读属性之后,还可以用来垫电脑屏幕、垫桌脚、盖泡面、砸产品经理,实乃居家、旅行、自卫必备神器! 这种书…

    Linux 2023年6月14日
    088
  • 进程相关指令

    pgrep 查找进程名 KILL 删除 执行中的进程和工作 free 打印系统情况和内存情况 free [-bkmgotsh] free -h total used free sh…

    Linux 2023年6月7日
    096
  • Java分布式集群,使用synchronized和Redis保证Job的原子性

    1.使用synchronized保证并发时,同时只会有一个请求执行该代码段; 2.在执行前先设置并获取Reids标记,先设置然后获取确保是否已经执行;SetOption.SET_I…

    Linux 2023年5月28日
    089
  • WPF 多线程下跨线程处理 ObservableCollection 数据

    本文告诉大家几个不同的方法在 WPF 里,使用多线程修改或创建 ObservableCollection 列表的数据 需要明确的是 WPF 框架下,非 UI 线程直接或间接访问 U…

    Linux 2023年6月6日
    088
  • 生成随机数的若干种方法

    背景: 创建账户时我们需要配置初始随机密码,使用手机号注册时需要随机验证码,抽奖活动需要随机点名,俄罗斯方块游戏需要随机出形状。这些案例都在说明一个问题,随机数据很重要!而在 Sh…

    Linux 2023年6月6日
    079
  • shell脚本

    一、shell脚本基本介绍 格式要求 脚本要以 #!/bin/bash 开头,debain需要改成#!/bin/dash 脚本需要有可执行权限 shell常用执行方式 输入脚本的绝…

    Linux 2023年6月6日
    083
  • wsl2环境搭建

    我电脑配置不高,开虚拟机跑linux总觉得太卡。最近才了解到windows早就上了wsl2——一款较为轻量的虚拟机软件。所以本篇博客偏笔记向,存粹记录以便多次使用。 WSL2安装 …

    Linux 2023年6月7日
    078
  • 领导:谁再用redis过期监听实现关闭订单,立马滚蛋!

    在电商、支付等领域,往往会有这样的场景,用户下单后放弃支付了,那这笔订单会在指定的时间段后进行关闭操作,细心的你一定发现了像某宝、某东都有这样的逻辑,而且时间很准确,误差在1s内;…

    Linux 2023年5月28日
    084
  • oracle ORA-31655

    原因:是因为不是同一个schema,导致的问题产生 解决方案: 在导入语句最后添加上remap_schema=old:new 着old是原schema,也就是导出的用户名,new是…

    Linux 2023年6月8日
    074
  • MySQL概述

    数据库 ~存储数据的仓库,数据是有组织的进行存储 ~英文:Database,简称DB 数据库管理系统 ~管理数据库的大型软件 ~英文:DataBase Management Sys…

    Linux 2023年6月7日
    096
  • Github访问加速

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年6月8日
    073
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球