记者:你了解Redis的缓冲区吗?

大家好,我是齐Xi(xρ)。

Redis当然大家都很熟悉,但是在使用层面看不到的地方很容易被忽略。今天要和大家分享的是Redis中各种缓冲区的作用,溢出的后果以及优化方向。

在开始正文之前,我想多说几句。无论Redis还是其他中间件,很多底层原理都是相似的,设计思路都是通用的。

如果你以后在学习任何新的框架/组件,可以试着把它们和已经学过的知识点联系起来,这样会更容易理解,不要说死记硬背了。

比如现在说的缓冲区的目的是什么?

没有它,为了性能。

要么缓存数据提高响应速度。例如,MySQL中有一个更改缓冲区。

要么担心消费者的速度跟不上生产,害怕数据丢失。因此,需要临时存储生产数据。这就是Redis的缓冲剂的作用。

另外,消费者的速度跟不上。如果是同步处理,会不会也拖慢了生产者,所以这里其实是在保证生产者的速度。

有的读者可能会说:废话,消费者跟不上,生产者有什么用?

其实,有没有可能消费者用的时候,生产者并不在意?前者负责处理后者需要什么,给它什么。生产者很忙,还有很多其他数据要处理,不能等消费者同时消费完了再做其他事情。

好像开头扩大了一点。我要了。下面我会详细说一下。如果你有任何问题,请上车。七夕正式开始。

首先,Redis有什么缓冲?

一个*** 4:

服务器将为每个连接的客户端设置一个输入缓冲区。

临时存储请求的数据。

输入缓冲区将临时存储客户端发送的命令,Redis主线程将从输入缓冲区读取命令并进行处理。

为了避免客户端和服务器的发送和处理速度不匹配,这和后面要提到的输出缓冲区是一样的。

首先,缓冲区是一个固定大小的内存区域。如果要填充这个地方,Redis会直接关闭客户端连接。

保护好自己。你的客户挂了总比我的服务器挂了好。一旦服务器挂机,所有客户端都没用了。

那么在填充缓冲器时有两种情况:

然后将上述原则映射到Redis的场景中。

一下子填满的情况可以是将大量数据写入Redis,数量级为百万。

另一种情况可能是Redis服务器由于耗时的操作而被阻塞,导致无法消耗输入缓冲区数据。

对应以上两种溢出场景,自然有优化方向。

在一下子填满的情况下,能不能考虑一下子不写那么多数据,能不能把数据拆开(其实一下子写很多数据是不合理的)

另外,是否可以增加缓冲区的大小?

这其实是不可以的,因为没有地方设置。目前,服务器为每个客户机输入缓冲区分配的默认大小是1GB。

然后是第二个溢出场景:两边处理速度不一致。

正常情况下,服务器应该不会长时间阻塞,所以我们需要看看是什么原因导致了阻塞,并解决它。

与输入缓冲区一样,服务器也会为每个连接的客户端设置一个输出缓冲区。

同上,它也是一个临时请求数据。

这个地方其实就是我在文章开头说的。生产者不关心消费者什么时候用,只负责处理消费者之前要求的东西。

服务器通常连接多个客户端,redis网络通信模块是单线程的(即使新版本支持多线程)。

如果没有输出缓冲会怎么样?

服务器处理了很多来自客户端A的请求,需要通过一个耗时的网络操作返回给客户端A。在这个过程中,客户端B的请求没有得到服务器的处理和响应,所以吞吐量不会上去。

有了缓冲区,至少服务器可以解放出来处理客户端b的请求。

这也是同一个输入缓冲区,我就不啰嗦了。如果溢出,服务器也会关闭客户端连接。

同样,不要一次读取大量数据;MONITOR命令不会连续在线执行。

输出缓冲区的大小可以通过client-output-buffer-limit设置。

但是一般来说我们不需要改,因为默认情况就够了,知道这里就好了。

温馨提醒下,如果不了解Redis同步/复制,比如完全/增量复制的读者,建议你看看我的文章:一篇文章让你了解Redis主从同步。

让我们回到正题。

有复制就要有主从,主从之间的数据复制包括全量复制和增量复制。

全复制是同步所有数据,而增量复制只会在主从库网络断开时,将主库收到的命令同步到从库。

临时数据。

在主节点上为每个从节点维护一个复制缓冲区。

在满量程复制时,主节点在向从节点传输RDB文件的同时,会继续接收客户端发送的写命令请求,并保存在复制缓冲区中,待RDB文件传输完成后,再发送给从节点执行。

从节点接收和加载RDB的速度很慢,同时主节点接收到大量的写命令,这些写命令会在复制缓冲区中累积,最终溢出。

一旦溢出,主节点会直接关闭与从节点的连接进行复制操作,导致完全复制失败。

可以将主节点的数据量控制在2~4GB(仅供参考),这样可以使满量程同步执行更快,避免复制缓冲区堆积过多命令。

您还可以调整缓冲区大小,或者之前的客户端输出缓冲区限制参数。

例如:config set client-output-buffer-limit slave 512mb 128 MB 60。

这是新副本中使用的缓冲区。

临时数据。

当从节点意外断开并重新连接时,在此期间未同步的数据可以从该缓冲器同步。

不会溢出来。(出乎意料。jpg)

缓冲区本质上是一个固定长度的先进先出队列,默认值为1MB。

所以当队列满了,不是错误,也不像上面的缓冲区直接关闭连接。相反,它会覆盖首先进入队列的数据。

因此,如果从节点没有同步这些旧命令数据,它将导致主节点和从节点完全复制,而不是增量复制。

调整复制积压缓冲区的大小。参数是repl_backlog_size。