Redis Cluster Gossip Protocol: MEET

2023-10-04 07:46

本文主要是介绍Redis Cluster Gossip Protocol: MEET,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

返回目录

CLUSTER MEET

过程说明

client Node A Node B cmd: cluster meet B_ip B_port [B_cport] Invalid node address specified: ip:port OK alt [ip or port or cport is invalid] clusterCron message1: MEET message2: PONG handshake completed clusterCron message3: PING message4: PONG handshake completed client Node A Node B

注意:B_ip 不能使用域名

Node A 收到client发送的meet命令后:
  1. 如果 B_cport 不存在,则 B_cport = B_port + 10000
  2. 检查 B_ip, B_port, B_cport 的合法性
  3. 在自己的cluster节点字典中查找是否存在这样的节点
    • 处于handshake状态 &&
    • ip == B_ip &&
    • port == B_port &&
    • cport == B_cport
      如果存在,说明相同的节点已经处于handshake阶段,不需要重复handshake,返回OK给client。
  4. 新建实体B:
    • 生成一个随机节点ID
    • 设置创建时间为当前时间
    • 添加标记: NODE_HANDSHAKE | NODE_MEET
    • 设置传入的 ip, port, cport
  5. 把实体B加入到自己的cluster节点字典
  6. 返回OK给client

clusterCron: 一个专门处理cluster间通信的周期性调度。

消息说明

以下执行步骤只挑选了主要的步骤。

message1:A meet B

Node A 在ClusterCron时:

  1. 检查B是否存在NODE_MEET标记,没有则返回
  2. 判断跟B的handshake是否已经timeout:
    当前时间 - 节点的创建时间 > max(cluster-node-timeout, 1000)
    cluster-node-timeout 是配置项)
  3. 如果timeout了,从cluster节点字典中删除B的信息并返回
  4. 检查是否存在指向Node B的link,如果没有则创建一个(方向为TO)
  5. 连通后发送message1(MEET)给Node B
  6. 从实体B中移除NODE_MEET标记

message2:B pong A

Node B在收到message1后:

  1. 如果没有配置 cluster-announce-ip,则从socket中查找自己的ip
  2. 新建实体A
    • 生成一个随机节点ID
    • 设置创建时间为当前时间
    • 通过socket查找Node A的ip
    • 添加标记: NODE_HANDSHAKE
    • 设置传入的 ip, port, cport
  3. 把实体A加入到cluster节点字典
  4. 处理消息中的gossip部分
  5. 回复message2(PONG)给Node A
  6. 到此,在Node B看来,还没有完成跟Node A的handshake,所以不会直接使用message1中Node A的ID,也不会更新A的slots分布

Node A在收到message2后:

  1. message2中获取Node B的ID,更新实体B。因为之前新建实体B时用的是随机ID,而这次message2中带的才是真正的ID,所以需要更新
  2. 移除实体B中的HANDSHAKE标记
  3. 根据message2中的信息设置实体B为master或者slave
  4. 到此,在A看来,已完成跟B的handshake过程。但此时A还没有获取B中的slots分布。handshake完成后的下一次ping/pong才会更新slots。

message3:B ping A

Node B 在ClusterCron时:

  1. 检查是否存在指向Node A的link,没有则创建一个(方向为TO)
  2. 连通后发送message3(PING)给Node A

Node A在收到message3后:

  1. 更新currentEpoch和configEpoch
  2. 如果没有配置 cluster-announce-ip,则从socket中查找自己的ip
  3. 回复message4(PONG)给Node B
  4. 更新实体B中slots的分布
  5. 处理gossip和extension部分

message4: A pong B

Node B在收到message4后:

  1. message4中获取Node A的ID,更新实体A。因为之前新建实体A时用的是随机ID,而这次message4中带的才是真正的ID,所以需要更新
  2. 移除实体A中的HANDSHAKE标记
  3. 根据message4中的信息设置实体B为master或者slave
  4. 到此,在B看来,已完成跟A的handshake过程。但此时B还没有获取A中的slots分布。handshake完成后的下一次ping/pong才会更新slots。

至此:
5. 当Node A和Node B都完成了handshake过程后,就会进入相互ping/pong/update等的阶段
6. 而Node B可以从Node A的ping/pong中获取到Node A的slots分布,从而更新到实体A
7. 只有handshake成功后的下一次ping/pong才会真正的更新自己cluster节点字典中的实体。

Demo

Node A的日志
# Step 1
# Node A向Node B发送message1(MEET),fe4d****这个ID是实体B随机生成的
3383:M 22 Nov 2022 15:02:45.098 . Connecting with Node fe4d416c13a24d5dc03a6fff25181d3ae15f95ad at 127.0.0.1:17000
# -----------------# Step 3
# Node A收到Node B回复的message2(PONG)
3383:M 22 Nov 2022 15:02:45.099 . --- Processing packet of type pong, 2256 bytes
3383:M 22 Nov 2022 15:02:45.099 . pong packet received: fe4d416c13a24d5dc03a6fff25181d3ae15f95ad
# 根据message2里面Node B的真实ID,更新实体B
3383:M 22 Nov 2022 15:02:45.099 . Renaming node fe4d416c13a24d5dc03a6fff25181d3ae15f95ad into 737418730813700da2f51ddeb8bdc8e3fd2a7805
# 在Node A看来,跟Node B的handshake过程结束
3383:M 22 Nov 2022 15:02:45.099 . Handshake with node 737418730813700da2f51ddeb8bdc8e3fd2a7805 completed.
# -----------------# Step 5
# Node A收到Node B发送来的message3(PING)
3383:M 22 Nov 2022 15:02:45.201 - Accepting cluster node connection from 127.0.0.1:56990
3383:M 22 Nov 2022 15:02:45.201 . --- Processing packet of type ping, 2256 bytes
# Node A 修正自己的IP
3383:M 22 Nov 2022 15:02:45.201 # IP address for this node updated to 127.0.0.1
# Node A根据message3,做一系列操作,包括更新实体B中的slots
3383:M 22 Nov 2022 15:02:45.201 . ping packet received: 737418730813700da2f51ddeb8bdc8e3fd2a7805
# Node A回复message4给Node B(日志没显示)
# -----------------# Step 8
# Node A再次收到Node B发送来的PING
3383:M 22 Nov 2022 15:02:45.303 . --- Processing packet of type ping, 2256 bytes
3383:M 22 Nov 2022 15:02:45.303 . ping packet received: 737418730813700da2f51ddeb8bdc8e3fd2a7805
# Node A回复PONG给Node B(日志没显示)
# -----------------
Node B的日志
# Step 2
# Node B收到NodeA发送来的message1
3372:M 22 Nov 2022 15:02:45.099 - Accepting cluster node connection from 127.0.0.1:44968
3372:M 22 Nov 2022 15:02:45.099 . --- Processing packet of type meet, 2256 bytes
# Node B修正自己的IP
3372:M 22 Nov 2022 15:02:45.099 # IP address for this node updated to 127.0.0.1
# 因为message1中Node A的ID在Node B的cluster节点字典中不存在对应的实体,所以received打印的是NULL
3372:M 22 Nov 2022 15:02:45.099 . meet packet received: NULL
# Node B回复message2给Node A(日志没显示)
# -----------------# Step 4
# Node B在clusterCron时向NodeA发送message3(PING)
3372:M 22 Nov 2022 15:02:45.201 . Connecting with Node ba747dfdcd40d974294054f1d7ca023678ff9874 at 127.0.0.1:16000
# -----------------# Step 6
# Node B收到Node A回复的message4(PONG)
3372:M 22 Nov 2022 15:02:45.204 . --- Processing packet of type pong, 2256 bytes
3372:M 22 Nov 2022 15:02:45.204 . pong packet received: ba747dfdcd40d974294054f1d7ca023678ff9874
# Node B根据message4中Node A的真实ID,更新实体A
3372:M 22 Nov 2022 15:02:45.204 . Renaming node ba747dfdcd40d974294054f1d7ca023678ff9874 into ea017e0f83612b1b32179b4277becba349db5590
# 在Node B看来,跟Node A的handshake过程结束
3372:M 22 Nov 2022 15:02:45.204 . Handshake with node ea017e0f83612b1b32179b4277becba349db5590 completed.
# -----------------# Step 7
# Node B在clusterCron时再次向Node A发送PING消息
3372:M 22 Nov 2022 15:02:45.303 . Pinging node ea017e0f83612b1b32179b4277becba349db5590
# -----------------# Step 9
# Node B收到Node A回复的PONG
3372:M 22 Nov 2022 15:02:45.303 . --- Processing packet of type pong, 2256 bytes
# Node B根据PONG,做一系列操作,包括更新实体A中的slots
3372:M 22 Nov 2022 15:02:45.303 . pong packet received: ea017e0f83612b1b32179b4277becba349db5590

这篇关于Redis Cluster Gossip Protocol: MEET的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1607

相关文章

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

laravel框架实现redis分布式集群原理

在app/config/database.php中配置如下: 'redis' => array('cluster' => true,'default' => array('host' => '172.21.107.247','port' => 6379,),'redis1' => array('host' => '172.21.107.248','port' => 6379,),) 其中cl

Redis的rehash机制

在Redis中,键值对(Key-Value Pair)存储方式是由字典(Dict)保存的,而字典底层是通过哈希表来实现的。通过哈希表中的节点保存字典中的键值对。我们知道当HashMap中由于Hash冲突(负载因子)超过某个阈值时,出于链表性能的考虑,会进行Resize的操作。Redis也一样。 在redis的具体实现中,使用了一种叫做渐进式哈希(rehashing)的机制来提高字典的缩放效率,避

【吊打面试官系列-Redis面试题】说说 Redis 哈希槽的概念?

大家好,我是锋哥。今天分享关于 【说说 Redis 哈希槽的概念?】面试题,希望对大家有帮助; 说说 Redis 哈希槽的概念? Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽, 集群的每个节点负责一部分 hash 槽。

Redis地理数据类型GEO

通常要计算两个地理位置的距离不是很方便,这里可以直接通过Redis提供的GEO操作来完成地理位置相关的计算 1)添加地理位置 语法:geoadd key longitude latitude member [longitude latitude member] ...字段说明:key:存放地理位置的集合名称longitude:地理坐标的经度latitude:地理坐标的纬度member:表示这

Redis-主从集群

主从架构 单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。 主从数据同步原理 全量同步 主从第一次建立连接时,会执行全量同步,将master节点的所有数据都拷贝给slave节点,流程: 判断是否是第一次同步,如果是,返回版本信息(replication id 和offset),将salve节点的版本信息变为master的

Redis安装使用总结

一、下载安装 从 github 下载:https://github.com/MSOpenTech/redis/releases 或者 https://github.com/ServiceStack/redis-windows 解压缩,如图: 二、配置 打开redis.windows-sevice.conf文件, 2.1 绑定ip:搜索127.0.0.1 ,发现bind 127.0.0.

面对Redis数据量庞大时的应对策略

面对Redis数据量庞大时的应对策略,我们可以从多个维度出发,包括数据分片、内存优化、持久化策略、使用集群、硬件升级、数据淘汰策略、以及数据结构选择等。以下是对这些策略的详细探讨: 一、数据分片(Sharding) 当Redis数据量持续增长,单个实例的处理能力可能达到瓶颈。此时,可以通过数据分片将数据分散存储到多个Redis实例中,以实现水平扩展。分片的主要策略包括: 一致性哈希:使用一