Redis核心技术与实战【学习笔记】 - 27.限制Redis Cluster规模的因素(通信开销)

news2024/11/16 16:53:50

简述

Redis Cluster 能保存的数据量以及支撑的吞吐量,跟集群实例规模相关。 Redis 官方给出了 Redis Cluster 的规模上线,就是一个集群运行 1000 个实例。

其实,限定 Redis Cluster 集群规模的一个关键因素就是,实例间的通信开销会随着实例规模的增加而增大,在集群超过一定规模时(比如 800 节点),集群吞吐量反而会下降。所以,集群的实际规模会受到限制。


1.实例间通信方法和对集群规模的影响

Redis Cluster 在运行时,每个实例上都会保存 Slot 和实例的对应关系(也就是 Slot 映射表),以及自身的状态信息。

为了让集群中的每个实例都知道所有实例的状态信息,实例之间会按照一定的规则进行通信。这个规则就是 Gossip 协议。

Gossip 协议的工作原理可以概括成两点:

  • 一是,每个实例之间会按照一定的频率,从集群中挑选一些实例,把 PING 消息发送给挑选出来的实例,用来检测这些实例是否在线,并交换彼此的状态信息。PING 消息中封装了发送消息的的实例自身状态信息部分其他实例的状态信息以及 Slot 映射表
  • 二是,一个实例在接受到 PING 消息后,会给发送 PING 消息的实例,发送一个 PONG 消息。PONG 消息的内容和 PING 消息的内容一样。

在这里插入图片描述

Gossip 协议可以保证在一段时间后,集群中的每一个实例都能获得其他所有实例的状态信息。

这样,即使有新节点加入、节点故障、Slot 变更等时间发生,实例间也可以通过 PING 、PONG 消息的传递,完成集群状态在每个实例上的同步。

经过刚刚的分析,我们知道,实例间使用 Gossip 协议进行通信,通信的开销受到通信消息大小通信频率这两方的影响。

消息越大、频率越高,相应的通信开销就越大。如果想要实现高效的通信,可以从这两方面入手去调优。

2.Gossip 消息大小

Redis 实例发送的 PING 消息的消息体是由 dusterMsgDataGossip 结构体组成的,这个结构体的定义如下所示:

typedef struct {
	char nodename[CLUSTER_NAMELEN]; //40字节
	uint32_t ping_sent; //4字节
	uint32_t pong_received; //4字节
	char ip[NET_IP_STR_LEN]; //46字节
	uint16_t port; //2字节
	uint16_t cport; //2字节
	uint16_t flags; //2字节
	uint32_t notused1; //4字节
} dusterMsgDataGossip 

其中,CLUSTER_NAMELEN 和 NET_IP_STR_LEN 的值分别是 40 和 46,分别表示 nodename 和 ip 这两个字节数组的长度是 40 字节和 46 字节,我们在把结构体中其他信息的大小加起来,就可以得到一个 Gossip 消息的大小了,104 字节

每个实例在发送一个 Gossip 消息时,除了会传递自身的状态信息,默认会还会传递集群十分之一实例的状态信息

所以,对于一个包含了 1000 个实例的集群来说,每个实例发送一个 PING 消息时,会包含 100 个实例的状态信息,总的数据量是 10400 字节,再加上实例自身的信息,一个 Gossip 消息大约 10KB

此外,为了让 Slot 映射表能够在不同实例间传播,PING 消息中还带有一个长度为 16384 bit 的 Bitmap,这个 Bitmap 的每一位对应了一个 Slot,如果某位为 1 ,表示这个 Slot 属于当前实例。这个 Bitmap 大小换算成字节后,是 2KB 。我们把实例状态信息和 Slot 分配信息相加,就可以得到一个 PING 消息的大小了,大约是 12KB

PONG 消息和 PING 消息的内容一样,所以,它的大小约是 12KB。每个实例发送了 PING 消息后,还会收到 PONG 消息,两个消息加起来有 24KB

虽然从绝对值上来看,24KB 并不算大,但是,如果实例正常处理的单个请求只有几 KB 的话,那么,实例为了维护集群状态一致传输的 PING/PONG 消息,就要比单个业务请求大了。而且,每个实例都会给其他实例发送 PING/PONG 消息。随着集群规模增加,这些心跳消息的数量也会越多,会占据一部分集群的网络通信带宽,进而会降低集群服务正常客户端请求的吞吐量。

除了心跳信息大小会影响到通信开销,如果实例间通信非常频繁,也会导致集群网络带宽被频繁占用。那么,Redis Cluster 中实例的通信频率是什么样的呢?

3.实例间通信频率

Redis Cluster 的实例启动后,默认会每秒从本地的实例表中随机选出 5 个实例,再从这 5 个实例中找出一个最久没有通信的实例,把 PING 消息发送给该实例。这是周期性发送 PING 消息的基本做法。

但是,这里有一个问题:实例被选出来的这个最久没有通信的实例,毕竟是从随机选出的 5 个实例中挑选的,这并不能保证这个实例就一定是真个集群中最久没有通信的实例。

所以,这可能会出现,有些实例一直没有被发送 PING 消息,导致它们维护的集群状态已经过期了

为了避免这种情况,Redis Cluster 的实例会按照每 100ms 一次的频率,扫描本地的实例列表,如果发现有实例最近一次接受 PONG 消息的时间,已经大于配置项 cluster-node-timeout 的一半了(cluster-node-timeout / 2),就会立刻给该实例发送 PING 消息,更新这个实例上的集群状态信息

在集群规模扩大之后,因为网络拥塞或是不同服务器间的流量竞争,会导致实例间的网络通信延迟增加。如果有部分实例无法收到其他实例发送的 PONG 消息,就会引起实例之间频繁的发送 PING 消息,这又会对集群网络通信带来额外的开销了。

我们来总结下单实例每秒发送的 PING 消息数量,如下所示:

PING 消息发送数量 = 1 + 10*实例数(最近一次接受 PONG 消息的时间超出 cluster-node-timeout / 2)

  • 1 是指单实例常规按照每 1 秒发送一个 PING 消息
  • 10 是指每 1 秒内实例会执行 10 次检查,每次检查后会给 PONG 消息超时的实例发送消息。

借助一个例子,分析下在这种通信频率下,PING 消息占用集群带宽的情况。

假设单个实例检测发现,每 100 毫米有 10 个实例的 PONG 消息接受超时,那么,这个实例每秒就会发送 101 (101 = 1 + 10*10)个 PING 消息,越占 1.2MB/s 带宽。如果集群中有 30 个实例按照这种频率发送消息,就会占用 36 MB/s 带宽,这会挤占集群中用于服务正常请求的带宽。

4.如何降低实例间的通信开销

为了降低实例间的通信开销,从原理上说,我们可以减小实例传出的消息大小(PING/PONG 消息、Slot 分配信息),但是因为集群实例依赖 PING、PONG 消息和 Slot 分配信息,来维持集群状态的统一,一旦减小了传递的消息大小,就会导致实例间的通信信息减少,不利于集群维护,所以,我们不能采用这种方式。

经过刚才的学习,我们现在知道,实例间发送消息的频率有两个:

  • 每个实例每 1 秒发送一条 PING 消息。这个频率不算高,如果再降低该频率的话,集群中各实例的状态可能就没有办法及时传播了。
  • 每个实例每 100 毫秒会做一次检查,给 PONG 消息接收超过 cluster-node-timeout / 2 的节点发送 PING 消息。实例按照每 100 毫秒进行检测的频率,是 Redis 默认的周期性检查任务的统一频率,我们一般不需要修改它。

那么,就只有修改 cluster-node-timeout 这个配置项了。

配置项 cluster-node-timeout 定义了集群实例被判断为故障的心跳超时时间,默认是 15 秒。如果 cluster-node-timeout 值比较小,那么,在大规模集群中,就会比较频繁地出现 PONG 消息接收超时的情况,从而导致实例每秒要执行 10 次“给 PONG 下消息超时的实例发送 PING 消息” 这个操作。

所以,为了避免过多的心跳消息挤占集群带宽,我们可以调大 cluster-node-timeout 的值,比如说调大到 20 秒或 25 秒。这样一来,PONG 消息接收超时的情况就会有所缓解,单实例也不用频繁地每秒 执行 10 次心跳发送操作了。

当然,我们也不要把 cluster-node-timeout 调的太大,否则,如果实例真的发生故障了,我们就需要等待 cluster-node-timeout 时长后,才能检测出故障,这又会导致实际的故障恢复时间被延长,会影响到集群服务的正常使用。

为了验证调整 cluster-node-timeout 值后,是否能减少心跳消息占用的带宽,给你一个小建议:你可以在调整 cluster-node-timeout 值的前后,使用 tcpdump 命令转去实例发送心跳信息网络包的情况

tcpdump host 127.0.0.1 port 7001 -i 网卡名 -w /tmp/r1.cap

通过分析网络包的数量和大小,可以判断调整 cluster-node-timeout 值前后,心跳消息占用的带宽情况了。

5.小结

Redis Cluster 实例间以 Gossip 协议进行通信。Redis Cluster 运行时,各实例需要通过 PING 、PONG 消息进行信息交换,这些心跳信息包括了当前实例和部分其他实例的状态信息,以及 Slot 分配信息。这种通信机制有助于 Redis Cluster 中的所有实例都拥有完成的集群状态信息。

但是,随着集群规模的增加,实例间的通信量也会增加。如果我们盲目地对 Redis Cluster 进行扩容,就可能会遇到集群性能变慢的情况。这是因为,集群中大规模的实例间心跳消息会挤占集群处理正常请求的带宽。而且,有些实例可能因为网络拥塞导致无法及时收到 PONG 消息,每个实例在运行时会周期性地(每秒 10 次)检测是否有这种情况发生,一旦发生,就会立即给这些 PONG 消息超时的实例发送心跳信息。集群规模越大,网络拥塞的概率就越高,相应的,PONG 消息超时的发生概率就越高,这就会导致集群中有大量的心跳消息,影响集群服务的正常请求。

虽然,我们可以通过调整 cluster-node-timeout 配置项减少心跳消息占用带宽情况,但是,在实际应用中,如果不是特别需要大容量集群,我建议你把 Redis Cluster 的规模控制在 400~500 个实例。

假设单个实例每秒支撑 8 万请求操作(8 万 QPS),每个主实例配置一个从实例,那么 400~500 个实例可支撑 1600 万 ~ 2000 万 QPS(200/250 个主实例 * 8 万 QPS = 1600/2000 万 QPS),这个吞吐量性能可以满足不少业务应用的需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1443930.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL优化器

优化器 MySQL存储引擎中存在了一个可插拔的优化器OPTIMIZER_TRACE,可以看到内部查询计划的TRACE信息,从而可以知道MySQL内部执行过程 查询优化器状态 show variables like optimizer_trace;Variable_name Valueoptimizer_trace enabledoff,one_lineoff…

大模型实战营第二期——3. 基于 InternLM 和 LangChain 搭建你的知识库

github地址:InternLM/tutorial-书生浦语大模型实战营文档地址:基于 InternLM 和 LangChain 搭建你的知识库视频地址:基于 InternLM 和 LangChain 搭建你的知识库Intern Studio: https://studio.intern-ai.org.cn/console/instance动手学大模型…

如何在苹果Mac上进行分屏,多任务处理?

Apple 在 macOS Catalina 中引入了 Split View,让您可以同时查看两个应用程序。如果同时处理多个应用程序,但在它们之间切换时感到沮丧,小编教给大家在 Macbook Pro/Air 或 iMac 上使用分屏功能流畅地进行多任务处理。 注意:您可…

C# 委托(delegate)本质理解

目录 代码如下,很简单 运行的结果 反编译程序查看 关注两点: 什么是委托 委托的三个步骤 委托的意义 代码如下,很简单 namespace Delegate { class Program { delegate void SayHi(); void SayHi_1() …

专业135+总400+中国科学院大学859国科大信号与系统考研经验电子信息与通信,真题,大纲,参考书

今年考研专业课859信号与系统135,总分400上岸国科大,总结一下自己这一年的复习经验,希望对后面报考中科院大学的同学有所帮助。 专业课: 国科大不同研究所都是统一命题,859信号与系统的参考书目是郑君里的《信号与系…

移动光猫gs3101超级密码及改桥接模式教程

文章目录 超级管理员账号改桥接模式路由器连接光猫,PPPOE拨号即可!附录:如果需要改桥接的话不知道拨号密码咋办打开光猫Telnet功能Telnet 登录 参考文章 移动光猫吉比特GS3101超级账号获取更改桥接 移动光猫gs3101超级密码及改桥接模式教程 …

C#入门及进阶|数组和集合(六):集合概述

1.集合概述 数组是一组具有相同名称和类型的变量集合,但是数组初始化后就不便于再改变其大小,不能实现在程序中动态添加和删除数组元素,使数组的使用具有很多局限性。集合能解决数组存在的这个问题,下面我们来学习介绍集合…

微服务入门篇:http客户端Feign(远程调用,自定义配置,Feign的性能优化,Feign服务抽取)

目录 1.基于Feign的远程调用1.RestTemplate方式调用存在的问题2.Feign的介绍3.定义和使用Feign客户端 2.自定义配置1.方式一:配置文件方式2.方式二: java代码方式,需要先声明一个Bean: 3.Feign的性能优化1.Feign底层的客户端实现2.连接池配置 4.Feign的最…

春节假期:思考新一年的发展思路

春节假期是人们放松身心、享受家庭团聚的时刻,但除了走亲戚、玩、吃之外,我们确实也需要思考新的一年的发展思路。以下是一些建议,帮助您在春节假期中为新的一年做好准备: 回顾过去,总结经验:在春节期间&a…

Blazor 子组件交互例子

源码 子组件 SwitchBar.razor &#xfeff;using Microsoft.Extensions.Logging inject ILogger<Index> Logger<div style"ClassString" onclick"OnClick">ChildContent </div>code {[Parameter]public RenderFragment? ChildContent…

AJAX——认识URL

1 什么是URL&#xff1f; 统一资源定位符&#xff08;英语&#xff1a;Uniform Resource Locator&#xff0c;缩写&#xff1a;URL&#xff0c;或称统一资源定位器、定位地址、URL地址&#xff09;俗称网页地址&#xff0c;简称网址&#xff0c;是因特网上标准的资源的地址&…

LeetCode---383周赛

题目列表 3028. 边界上的蚂蚁 3029. 将单词恢复初始状态所需的最短时间 I 3030. 找出网格的区域平均强度 3031. 将单词恢复初始状态所需的最短时间 II 一、边界上的蚂蚁 这题没什么好说的&#xff0c;模拟就行&#xff0c;本质就是看前缀和有几个为0。 代码如下 class S…

【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱1(附带项目源码)

效果演示 文章目录 效果演示系列目录前言人物和视角基本控制简单的背包系统和物品交互绘制背包UI脚本控制 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第25篇中&#xff0c;我们将…

游戏服务器哪家强?国内几款主流云服务器测评

游戏服务器租用多少钱一年&#xff1f;1个月游戏服务器费用多少&#xff1f;阿里云游戏服务器26元1个月、腾讯云游戏服务器32元&#xff0c;华为云26元&#xff0c;游戏服务器配置从4核16G、4核32G、8核32G、16核64G等配置可选&#xff0c;游戏专业服务器公网带宽10M、12M、15M…

【大厂AI课学习笔记】【1.6 人工智能基础知识】(1)人工智能、机器学习、深度学习之间的关系

6.1 人工智能、机器学习与深度学习的关系 必须要掌握的内容&#xff1a; 如上图&#xff1a;人工智能>机器学习>深度学习。 机器学习是人工智能的一个分支&#xff0c;该领域的主要研究对象是人工智能&#xff0c;特别是如何在经验学习中改进具体算法的性能。 深度学习…

算法||实现典型数据结构的查找、添加和删除数据 并分析其时间和空间复杂度

实现典型数据结构的查找、添加和删除数据 并分析其时间和空间复杂度 线性结构&#xff1a; 数组&#xff1a;是一种线性表数据结构&#xff0c;它用一组连续的内存空间&#xff0c;来存储一组具有相同类型的数据。 查找数据 &#xff1a;随机访问 流程图 /** 查询元素下标…

02 数据库管理 数据表管理

文章目录 数据库管理数据表管理基础数据类型表的基本操作 数据库管理 查看已有库 show databases; 创建库 create database 库名 [character set utf8]; e.g. 创建stu数据库&#xff0c;编码为utf8 create database stu character set utf8; create database stu charsetutf8;…

LSF 主机状态 unreach 分析

在LSF集群运行过程中&#xff0c;有主机状态变为 unreach。熟悉LSF的朋友都知道主机状态为 unreach 表示主机上的 SBD 服务中断服务了&#xff0c;但其它服务 LIM 和 RES 还在正常运行。 影响分析 那么主机上的 SBD 服务中断的影响是什么呢&#xff1f; 我们需要先明白 SBD …

Java 学习和实践笔记(6)

各数据类型所占的空间&#xff1a; byte: 1个字节 short&#xff1a;2个字节 int&#xff1a;4个 long&#xff1a;8个 float&#xff1a;4个 double: 8个 char:1个 boolean:1bit 所有引用数据类型都是4个字节&#xff0c;实际其值是指向该数据类型的地址。 上图中稍特…

使用Softing edgeConnector模块将云轻松连接到Siemens PLC

一 工业边缘的连接解决方案 云服务提供商 (CSP) 引入了服务和功能&#xff0c;以简化基于云的工业物联网解决方案的实施。Azure Industrial IoT Platform或AWS IoT SiteWise支持标准协议和接口&#xff0c;例如OPC UA或MQTT。但是&#xff0c;如果您希望在典型的旧改项目中连接…