redis最大多少个节点问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis最大多少个节点问题相关的知识,希望对你有一定的参考价值。

参考技术A

转自 https://blog.csdn.net/chenxuegui1234/article/details/100171599

现在redis集群架构,redis cluster用的会比较多。

如下图所示

对于客户端请求的key,根据公式HASH_SLOT=CRC16(key) mod 16384,计算出映射到哪个分片上,然后Redis会去相应的节点进行操作!

那大家思考过,为什么有16384个槽么?

ps:CRC16算法产生的hash值有16bit,该算法可以产生2^16-=65536个值。换句话说,值是分布在0~65535之间。那作者在做mod运算的时候,为什么不mod65536,而选择mod16384?

其实我当初第一次思考这个问题的时候,我心里是这么想的,作者应该是觉得16384就够了,然后我就开始查这方面资料。

很幸运的是,这个问题,作者是给出了回答的!

地址如下: https://github.com/antirez/redis/issues/2576

作者原版回答如下:

The reason is:

So 16k was in the right range to ensure enough slots per master with a max of 1000 maters, but a small enough number to propagate the slot configuration as a raw bitmap easily. Note that in small clusters the bitmap would be hard to compress because when N is small the bitmap would have slots/N bits set that is a large percentage of bits set.

因此,能看懂上面那段话的读者。这篇文章不用看了,因为作者讲的很清楚了。本文只是对上面那段话做一些解释而已。

我们回忆一下Redis Cluster的工作原理!

这里要先将节点握手讲清楚。我们让两个redis节点之间进行通信的时候,需要在客户端执行下面一个命令

<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; font-weight: 400; position: relative; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-family: Consolas, Inconsolata, Courier, monospace; font-size: 14px; line-height: 22px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">127.0.0.1:7000>cluster meet 127.0.0.1:7001
</pre>

如下图所示

意思很简单,让7000节点和7001节点知道彼此存在!

在握手成功后,两个节点之间会 定期 发送ping/pong消息,交换 数据信息 ,如下图所示。

在这里,我们需要关注三个重点。

到底在交换什么数据信息?

交换的数据信息,由消息体和消息头组成。

消息体无外乎是一些节点标识啊,IP啊,端口号啊,发送时间啊。这与本文关系不是太大,我不细说。

我们来看消息头,结构如下

注意看红框的内容,type表示消息类型。

另外,消息头里面有个myslots的char数组,长度为16383/8,这其实是一个bitmap,每一个位代表一个槽,如果该位为1,表示这个槽是属于这个节点的。

到底数据信息究竟多大?

在消息头中,最占空间的是myslots[CLUSTER_SLOTS/8]。这块的大小是:

16384÷8÷1024=2kb

那在消息体中,会携带一定数量的其他节点信息用于交换。

那这个其他节点的信息,到底是几个节点的信息呢?

约为集群总节点数量的1/10,至少携带3个节点的信息。

这里的重点是: 节点数量越多,消息体内容越大。

消息体大小是10个节点的状态信息约1kb。

那定期的频率是什么样的?

redis集群内节点,每秒都在发ping消息。规律如下

因此,每秒单节点发出ping消息数量为

1+10*num(node.pong_received>cluster_node_timeout/2)

那大致带宽损耗如下所示,图片来自《Redis开发与运维》

讲完基础知识以后,我们可以来看作者的回答了。

(1)如果槽位为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大。

如上所述,在消息头中,最占空间的是myslots[CLUSTER_SLOTS/8]。

当槽位为65536时,这块的大小是:

65536÷8÷1024=8kb

因为每秒钟,redis节点需要发送一定数量的ping消息作为心跳包,如果槽位为65536,这个ping消息的消息头太大了,浪费带宽。

(2)redis的集群主节点数量基本不可能超过1000个。

如上所述,集群节点越多,心跳包的消息体内携带的数据越多。如果节点过1000个,也会导致网络拥堵。因此redis作者,不建议redis cluster节点数量超过1000个。

那么,对于节点数在1000以内的redis cluster集群,16384个槽位够用了。没有必要拓展到65536个。

(3)槽位越小,节点少的情况下,压缩率高

Redis主节点的配置信息中,它所负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中,会对bitmap进行压缩,但是如果bitmap的填充率slots / N很高的话(N表示节点数),bitmap的压缩率就很低。

如果节点数很少,而哈希槽数量很多的话,bitmap的压缩率就很低。

ps:文件压缩率指的是,文件压缩前后的大小比。

综上所述,作者决定取16384个槽,不多不少,刚刚好!

有n个节点的有向图中的最大边数是多少? [关闭]

【中文标题】有n个节点的有向图中的最大边数是多少? [关闭]【英文标题】:What is the maximum number of edges in a directed graph with n nodes? [closed] 【发布时间】:2011-06-30 19:31:18 【问题描述】:

有n个节点的有向图中的最大边数是多少?有上限吗?

【问题讨论】:

@LiorKogan “算法”部分呢? 抱歉,我没有看到任何“算法”部分。只是一个组合问题 我投票结束这个问题,因为它与编程无关。 我投票结束这个问题,因为它不是一个专门的编程问题。 【参考方案1】:

除了 Chris Smith 提供的直观解释之外,我们还可以从不同的角度考虑为什么会出现这种情况:考虑无向图。

要了解为什么在 DIRECTED 图中答案是 n*(n-1),请考虑一个无向图(这意味着如果两个节点(A 和 B)之间存在链接,那么您可以转到两种方式:从 A 到 B 和从 B 到 A)。无向图中的最大边数为n(n-1)/2,显然在有向图中有两倍

很好,您可能会问,但是为什么在无向 中最多有n(n-1)/2 边? 为此,考虑 n 个点(节点)并询问从第一个点可以形成多少条边。显然,n-1 边缘。现在,假设您连接了第一个点,可以从第二个点绘制多少条边?由于第一个点和第二个点已经连接,因此可以完成n-2 边。等等。所以所有边的总和是:

Sum = (n-1)+(n-2)+(n-3)+...+3+2+1 

由于 Sum 中有 (n-1) 项,并且此类序列中 Sum 的平均值((n-1)+0)/2 (last + first)/2, Sum = n(n-1)/2

【讨论】:

【参考方案2】:

在带有自循环的图中

max edges= n*n

比如我们有4个节点(顶点)

4 nodes = 16 edges= 4*4

【讨论】:

【参考方案3】:

有向图:

问题:有n个顶点的有向图中的最大边数是多少?

假设没有自环。 假设从给定的起始顶点到给定的结束顶点最多有一条边。

每条边由它的起始顶点和结束顶点指定。有 n 个 起始顶点的选择。因为没有自环,所以有 结束顶点的 n-1 个选择。将这些相乘即可 可能的选择。

回答n(n−1)

无向图

问题:n个顶点的无向图中的最大边数是多少?

假设没有自环。 假设从给定的起始顶点到给定的结束顶点最多有一条边。

在无向图中,每条边由它的两个端点指定 顺序无关紧要。因此,边的数量是数量 从顶点集合中选择的大小为 2 的子集。由于该集 顶点的大小为 n,此类子集的数量由 二项式系数 C(n,2)(也称为“n 选择 2”)。使用 二项式系数的公式,C(n,2) = n(n-1)/2。

回答(n*(n-1))/2

【讨论】:

【参考方案4】:

换一种说法:

完整图是一个无向图,其中每对不同的顶点都有一条连接它们的唯一边。从某种意义上说,这很直观,您基本上是从 n 个顶点的集合中选择 2 个顶点。

nC2 = n!/(n-2)!*2! = n(n-1)/2

这是无向图可以拥有的最大边数。现在,对于有向图,每条边都转换为两条有向边。所以只需将前面的结果乘以 2。这会给你结果:n(n-1)

【讨论】:

【参考方案5】:

在有 N 个顶点的有向图中,每个顶点可以连接到图中的 N-1 个其他顶点(假设没有自环)。因此,边的总数可以是N(N-1)。

【讨论】:

此答案不会提供其他答案中尚不存在的任何内容。此外,/2 用于无向图。【参考方案6】:

无向是 N^2。简单 - 每个节点都有 N 个边选项(包括他自己),总共有 N 个节点,因此 N*N

【讨论】:

N^2 包括方向的重复,因此您计算的比实际边缘更多。 1,2 与无向中的 2,1 相同。在一个无向图它的n(n-1)/2.【参考方案7】:

在无向图中(不包括多重图),答案是 n*(n-1)/2。在有向图中,两个节点之间可能在两个方向上都出现一条边,那么答案是 n*(n-1)。

【讨论】:

【参考方案8】:

如果不允许多边,则图中可以有多达n(n-1)/2 条边。

如果我们将顶点标记为1,2,...,n 并且从ij iff i&gt;j 存在一条边,这是可以实现的。

见here。

【讨论】:

【参考方案9】:

也可以认为是选择节点对 n 的方式数选择 2 = n(n-1)/2。如果只有任何一对只能有一条边,则为真。否则乘以 2

【讨论】:

【参考方案10】:

正确答案是 n*(n-1)/2。每条边都被计算了两次,因此除以 2。完整的图有最大边数,由 n 选择 2 = n*(n-1)/2 给出。

【讨论】:

仅当您在图表中禁止有向循环时才适用。 这仅适用于无向图 N*(N-1)/2 仅适用于无向图,因为每个节点的边数从 (n-1),(n-2),(n-3) 逐渐减少, ....,1 (所有的总和为 n(n-1)/2。但是,对于有向图,您应该考虑每个顶点的外字边,因此是 n(n-1)。【参考方案11】:

如果图不是多重图,那么它显然是 n * (n - 1),因为每个节点最多可以有到每个其他节点的边。如果这是一个多重图,则没有最大限制。

【讨论】:

【参考方案12】:

如果您有N 节点,则有N - 1 有向边无法从它引出(到达每个其他节点)。因此,最大边数为N * (N - 1)

【讨论】:

正确。如果允许边从节点到自身,则最大值为N^2 @M.A 如果您谈论的是无向图,那么您是正确的。然而,在有向图中,边 (A,B) 与边 (B,A) 不同 N*(N-1) 是有向图中的边数。无向图中的边数为 (N * (N-1)) / 2 即假设图是有向的 与@ypercube 思路相同,答案是正确的,但不考虑有向图中的自环。

以上是关于redis最大多少个节点问题的主要内容,如果未能解决你的问题,请参考以下文章

spark中每个worker节点运行多少个executor进程?

为啥redis集群的最大槽数是16384个?

你可以在redis中存储的最大值是多少?

一棵含有N个结点的K叉树,可能达到的最大深度和最小深度分别是多少?

Firebase 性能:每个节点有多少个子节点?

socketio集群节点挂了怎么办