持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情
前言
在Redis架构中,除了客户端与服务端之间存在缓冲区,如果使用了主从集群架构,同样会有缓冲区。那么你知道主从集群的缓冲区有哪些配置和细节吗?本文给你答案。
主从集群的缓冲区
如果你的Redis是主从集群的部署方式,那么数据同步同样会用到缓冲区。不管是全量复制还是增量复制,缓冲区都是为了保证主从节点的数据一致性。但全量复制和增量复制的缓冲区有较大差别,我们一一来说。
全量复制时缓冲区的溢出
全量复制过程中,主节点在向从节点传输RDB文件的同时,还会不断的接收客户端的写入命令,而这些命令就是会保存在复制缓冲区里。等到RDB文件都传输完成,复制缓冲区的数据才会发给从节点。
需要注意的是,主从集群往往有多个从节点,Redis的主节点会给每个从节点设置一个复制缓冲区,从而保证每个主从节点间的数据同步正常运行。
由上图很容易分析得出:当全量复制过程中,从节点接收RDB数据慢,而这时主节点又有大量的写命令产生,这就会导致在复制缓冲区的数据越来越多,糟糕的情况下最后还会导致缓冲区溢出。
当复制缓冲区发生溢出情况时,主节点会直接关闭和从节点之间的连接,从而导致全量复制的失败。为了避免复制缓冲区的溢出,我们可以从2个方面入手:
- 控制主节点的数据量:将主节点的数据量控制在4GB以内,这样全量同步的时间就不会太久。
- 调节 client-output-buffer-limit配置:调节主节点的数据量大小、写负载压力、内存大小。
主要说说第二点,举例说明参数配置:
config set client-output-buffer-limit slave 512mb 128mb 60
备注:slave代表是针对复制缓冲区;512mb代表缓冲区的内存上限值;128mb和60结合起来看,代表连续60秒写入量超过128MB也会触发缓冲区溢出。
通过这个配置,我们可以通过写命令数据量的多少和写命令速率,大概的了解缓冲区积压的写命令数据量。然后同设置的复制缓冲区大小比较,从而得出缓冲区的大小是否设置的合理。
需要注意的是:主节点的复制缓冲区大小,是所有从节点输出缓冲区占用内存的总和。因此,过多的从节点会导致主节点的复制缓冲区内存压力大,我们要重视这个问题,控制从节点的个数。
增量复制时缓冲区的溢出
增量复制的缓冲区,也叫做复制积压缓冲区,英文叫 repl_backlog_buffer 。 主节点将写命令同步给从节点时,也会同时把命令写到复制积压缓冲区中。
网络正常时,缓冲区的数据不会写到从节点。但如果从节点发生了网络故障,缓冲区就起作用了。从节点恢复时,这些积压缓冲区的数据,就会发送到从节点,从而进行增量同步。
复制积压缓冲区,数据结构上是一个有限的环形缓冲区,因此,当主节点将缓冲区写满后,再写入就会覆盖掉缓冲区内的旧数据。最糟糕的是,如果从节点没有同步这些覆盖的旧数据,就会触发主从节点的全量复制动作了。
为了避免溢出,我们可以调整repl_backlog_size这个参数。这个参数的调整,需要参考缓冲空间大小。而缓冲空间大小 = 主库写入命令速度 * 操作大小 - 主从库间网络传输命令速度 * 操作大小。我们为了应对突发激增的请求压力情况,经验上会把这个缓冲空间扩大一倍,也就是repl_backlog_size = 缓冲空间大小 * 2。
举个例子更好理解:比如主库每秒写入大概1000个数据,每个数据大小为2KB,网络传输速度每秒500个数据,缓冲空间大小 = 写入速度1000 * 2KB - 传输速度500 * 2KB,即1000KB,差不多1MB,最后我们将 repl_backlog_size设置为1MB * 2 = 2MB。
小结
本文总结了一下Redis主从集群中的缓冲区知识,在全量同步和增量同步中缓冲区都有各自的区别。熟知这些细节,可以让我们避免大部分的主从集群缓冲区溢出问题。