Redis:性能优化之Redis Cluster的通信详解

【关于作者】

关于作者,目前在蚂蚁金服搬砖任职,在支付宝营销投放领域工作了多年,目前在专注于内存数据库相关的应用学习,如果你有任何技术交流或大厂内推及面试咨询,都可以从我的个人博客(https://0522-isniceday.top/)联系我
前言

Redis Cluster集群环境下,实例越多真的越好吗,吞吐量就越大吧

redis官方建议是一个集群不超过1000个实例,原因是再多可能吞吐量反而会有降低的风险,那么为什么会这样呢?我们可以继续往下看

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

由于Redis Cluster集群环境下,各个实例之间需要同步slot及实例的映射信息、当前实例的信息等。因此实例之间的通信是不可以避免了,redis会按照一定的规则同步实例的信息及slot映射的信息,这个规则就是Gossip协议

1.1.Gossip协议:

保证一段时间后,集群内的每个实例都能获得其他实例的信息,哪怕新加入的实例、实例故障、Slot变更

工作原理主要包括如下:

  • 每个实例会按照一定的频率挑选一些实例,并把PING消息发送给挑选出的实例,用户探测是否存活及交换信息,PING消息中包含该实例自身的状态信息、部分其他实例的信息(默认包含实例十分之一的实例)、Slot映射表

  • 实例接收到PINT信息后,会回一个PONG信息,内容和PING一致

    img

通过了解Gossip协议之后,我们可以知道通信对集群可能造成的影响主要包括两个方面:

  • 通信消息大小
  • 通信频率

消息越大、频率越高,开销自然也就越大

1.2.通信频率大小

Redis实例的PING消息的结构体clusterMsgDataGossip如下:

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字节
} clusterMsgDataGossip;

从结构体中我们可以得知,一条PING消息包含自身的状态信息(104字节)、默认十分之一的实例的状态信息(10*104字节)、Slot映射表(一个16384位的bitmap,如果slot在该实例上,则为1,否则为0),所以一个PING消息的大小如下:

104 + 100 * 104(假设集群中1000个实例)+ 16384/8(slot映射表) ≈ 12 KB

再加上PONG消息,那么就是12 * 2 = 24KB的消息大小了,可能24KB不算大,但是这也是相较于业务而言,如果正常业务的单个请求只要几KB,那么就大于正常请求了,并且随着集群规模增大,心跳消息的数量会越来越多,进而影响网络带宽的占用

1.3.实例通信频率

之前说了Gossip规则是挑选一些实例进行PING发送,那么具体规则是怎么样的呢?

实例默认会每秒从实例列表中挑选5个实例,再从5个实例中挑出最久没有通信的实例,发送PING消息。

但是随机挑选5个实例,还是无法保证集群最久没有通信的实例会被挑选入5个实例,这有可能出现这些未被挑选的实例一直没有被发送PING信息,导致维护的集群状态过时了

为了避免,Redis Cluster实例会按照100ms每次遍历本地实例列表,如果发现有实例最近一次接受PONG命令的时间,已经大于配置项cluster-node-timeout的一半(cluster-node-timeout/2),就会立即给该实例发生PING信息。

集群规模扩大后,可能会由于网络阻塞或不正常的网络竞争导致实例列表大部分的实例都超时,这个时候就会频繁的发送PING信息,导致额外的网络开销

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

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

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

  • 从降低通信数据量角度入手:

    由于实例之间需要依靠通信的数据进行集群的状态的数据同步,因此数据量不太好缩减,会影响集群状态的数据同步

  • 从降低通信频率角度入手:

    前面我们知道了实例每秒的通信次数,并且通信次数是依赖于配置项cluster-node-timeout(默认15s),

    这个参数如果过大:如果实例发生了故障,那么我们就需要等待cluster-node-timeout时长后,才能检测出故障

    参数设置过小:那么通信的频率会越来越频繁

    我们可以适当调大该配置项,例如20s或25s,这样可以有效避免过多的集群消息占用网络带宽

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈哈张大侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值