21 | 缓冲区:一个可能引发“惨案”的地方
蒋德钧
该思维导图由 AI 生成,仅供参考
你好,我是蒋德钧。今天,我们一起来学习下 Redis 中缓冲区的用法。
缓冲区的功能其实很简单,主要就是用一块内存空间来暂时存放命令数据,以免出现因为数据和命令的处理速度慢于发送速度而导致的数据丢失和性能问题。但因为缓冲区的内存空间有限,如果往里面写入数据的速度持续地大于从里面读取数据的速度,就会导致缓冲区需要越来越多的内存来暂存数据。当缓冲区占用的内存超出了设定的上限阈值时,就会出现缓冲区溢出。
如果发生了溢出,就会丢数据了。那是不是不给缓冲区的大小设置上限,就可以了呢?显然不是,随着累积的数据越来越多,缓冲区占用内存空间越来越大,一旦耗尽了 Redis 实例所在机器的可用内存,就会导致 Redis 实例崩溃。
所以毫不夸张地说,缓冲区是用来避免请求或数据丢失的惨案的,但也只有用对了,才能真正起到“避免”的作用。
我们知道,Redis 是典型的 client-server 架构,所有的操作命令都需要通过客户端发送给服务器端。所以,缓冲区在 Redis 中的一个主要应用场景,就是在客户端和服务器端之间进行通信时,用来暂存客户端发送的命令数据,或者是服务器端返回给客户端的数据结果。此外,缓冲区的另一个主要应用场景,是在主从节点间进行数据同步时,用来暂存主节点接收的写命令和数据。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
Redis中的缓冲区是用来暂时存放命令数据的内存空间,以避免数据丢失和性能问题。然而,缓冲区的内存空间有限,若写入数据速度大于读取数据速度,就会导致缓冲区溢出,可能引发严重问题。本文详细介绍了客户端输入和输出缓冲区的溢出问题,以及相应的应对方案。对于输入缓冲区溢出,文章提到了通过CLIENT LIST命令查看和避免溢出的方法,同时强调了避免写入bigkey和处理速度过慢的重要性。此外,还介绍了Redis服务器端的maxmemory配置项和内存溢出问题。在输出缓冲区方面,文章重点讨论了避免bigkey操作返回大量数据结果、避免持续使用MONITOR命令以及使用client-output-buffer-limit设置合理的缓冲区大小上限等方法。此外,还介绍了在主从集群中的复制缓冲区溢出问题和相应的解决方案,包括控制主节点保存的数据量大小、设置合理的复制缓冲区大小以及控制从节点的数量。总的来说,本文强调了避免缓冲区溢出的重要性,同时指出了调整缓冲区大小的限制和应对策略。 在文章中,还介绍了Redis中使用的缓冲区的分类和应对缓冲区溢出的方法。文章指出了缓冲区溢出可能导致的网络连接关闭和命令数据丢失的问题,并提供了针对命令数据发送过快过大、处理较慢以及缓冲区空间过小的具体解决方案。通过本文的内容,读者可以清晰了解Redis中缓冲区的作用、溢出问题的影响以及相应的解决方法,有助于读者在实际应用中避免缓冲区溢出带来的问题。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Redis 核心技术与实战》,新⼈⾸单¥68
《Redis 核心技术与实战》,新⼈⾸单¥68
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(30)
- 最新
- 精选
- Kaito应用程序和Redis实例交互时,应用程序中使用的客户端需要使用缓冲区吗?如果使用的话,对Redis的性能和内存使用有什么影响? 客户端需要使用缓冲区,好处如下。 1、客户端和服务端交互,一般都会制定一个交互协议,客户端给服务端发数据时,都会按照这个协议把数据拼装好,然后写到客户端buffer中,客户端再一次性把buffer数据写到操作系统的网络缓冲区中,最后由操作系统发送给服务端。这样服务端就能从网络缓冲区中读取到一整块数据,然后按照协议解析数据即可。使用buffer发送数据会比一个个发送数据到服务端效率要高很多。 2、客户端还可以使用Pipeline批量发送命令到服务端,以提高访问性能。不使用Pipeline时,客户端是发送一个命令、读取一次结果。而使用Pipeline时,客户端先把一批命令暂存到buffer中,然后一次性把buffer中的命令发送到服务端,服务端处理多个命令后批量返回结果,这样做的好处是可以减少来回网络IO的次数,降低延迟,提高访问性能。当然,Redis服务端的buffer内存也会相应增长,可以控制好Pipeline命令的数量防止buffer超限。 缓冲区其实无处不在,客户端缓冲区、服务端缓冲区、操作系统网络缓冲区等等,凡是进行数据交互的两端,一般都会利用缓冲区来降低两端速度不匹配的影响。没有缓冲区,就好比一个个工人搬运货物到目的地,每个工人不仅成本高,而且运输效率低。而有了缓冲区后,相当于把这些货物先装到一个集装箱里,然后以集装箱为单位,开车运送到目的地,这样既降低了成本,又提高了运输效率。缓冲区相当于把需要运送的零散数据,进行一块块规整化,然后分批运输。 另外,关于Redis服务端为客户端分配的输出缓冲区,我想补充一点:主库上的从库输出缓冲区(slave client-output-buffer)是不计算在Redis使用的总内存中的,也就是说主从同步延迟,数据积压在主库上的从库输出缓冲区中,这个缓冲区内存占用变大,不会超过maxmemory导致淘汰数据。只有普通客户端和订阅客户端的输出缓冲区内存增长,超过maxmemory时,才会淘汰数据。2020-09-2840332
- 馒头超人有几个问题希望老师帮忙解答一下 1、TCP已经有读写缓冲区,redis为何还要单独维护读写缓冲区,两者的作用看起来是一致的 2、缓冲区类似队列,读写变成异步,主线程跟缓冲区交互,是什么线程负责缓冲区跟tcp的数据同步2020-10-21914
- Geek_aa296b各位大牛,是有额外的线程来处理 输入输出缓冲区吗,否则,是主线程处理的话,主线程阻塞的时候,客户端的数据是如何到输入缓冲区的?2020-12-1527
- Geek_72b9a7这个坑踩得很深,分享一个计算repl大小的脚本。https://blog.csdn.net/MyySophia/article/details/1071264592021-08-124
- 张凯qbuf=0 qbuf-free=0 这是什么情况导致的?2021-03-103
- Reborn 2.0老师, 我想问一下复制缓冲区(replication_buffer)在全量复制完成之后命令也同步完了还会存在么?2020-11-1122
- i_chase大佬,文章里客户端输入缓冲区是个什么概念?程序客户端有redis连接池,每个连接对于redis server都是一个客户端,每个连接都在redis server里有一个输入缓冲区吗?2022-11-09归属地:广东1
- escrayRedis 原本就是当做缓存在用,然后它又有自己的缓冲区,果然是应了那句话,在计算机领域,没有什么问题是加一层缓存解决不了的。 直接跳到课后问题,应用程序和 Redis 实例交互时,应用程序客户端应该也会使用缓冲区,对于 Redis 的性能和内存同样会有影响。如果不想造成缓冲区溢出那么也需要设置合理的缓冲区参数,以及设置合理的读写速率。 课后题的解答主要靠课代表 @Kaito2021-03-271
- 馒头超人有几个疑问希望老师帮忙解答: 1、tcp已经有读写缓冲区, redis 为何还要再单独维护读写缓冲区,两者的作用看起来是一样的2020-10-2131
- yeek服务器端处理请求的速度过慢,例如,Redis 主线程出现了间歇性阻塞,无法及时处理正常发送的请求,导致客户端发送的请求在缓冲区越积越多。 这句话有点没理解,redis大部分请求是阻塞的,对客户端来说需要等待服务器的相应结果,虽然相应结果不一定有用,但这样的情况,redis服务端如果处理请求较慢,那么客户端输入缓冲区应该是当前请求一直在hold吧?服务器处理慢会导致等待的客户端变多,整体积压的输入缓冲变多,但对单个缓冲区来说,溢出应该不是主要的吧? 不知道上述理解是否正确……2020-09-2851
收起评论