redis 缓冲区详解(性能优化缓冲区优化)

news2024/11/17 15:49:36

目录

前言

客户端输入缓冲区

输出缓冲区

集群缓冲区

全量复制缓冲区问题

增量复制缓冲区问题


前言

在我的《Redis 为啥那么快》这篇文章中,详细总结了Redis 为啥那么快。今天当我要详细阐述Redis 的缓冲区时,意识到应该加上Redis 的缓冲区。我们假设没有Redis 的缓冲区,客户端向服务端发送数据,必须等待Redis 的服务端去处理,大家都知道Redis 是单线程的,虽然这么说不是很准确,为了描述,也只好这么说了。如果没有及时处理,那客户端不就阻塞了吗,有多个客户端,redis 阻塞的时间不是更长了吗?现在我们有了缓冲区,客户端就可以把命令提交到客户端缓冲区,然后去输出缓冲区接收数据的返回,服务端直接从客户端读取数据,不用客户端持续等待。是不是就有点像Redis客户端和redis 服务端解绑了一样,谁都不知道谁的存在,只需要与中间的缓冲区交互就可以了。

如果我们使用不当,缓冲区可能会溢出,就会丢失数据。不给缓冲区设置大小,随着缓冲区的增大,最终会耗尽所有的内存,Redis 也就崩溃了。

下面我将从输入缓冲区,以及输出缓冲区,对于输出缓冲区,又从单个Redis 实例 到集群阐述这个问题。

为了描述客户端输入和输出缓冲区,我先画个图:

图1

客户端输入缓冲区

根据图1可以看到一个客户端对应一个输入缓冲区和输出缓冲区。Redis 客户端把命令写到输入缓冲区,Redis 主线程从输入缓冲区读取命令,在把返回的信息写到输出缓冲区,Redis 客户端从输出缓冲区读取响应命令。

我们上面讲到过,缓冲区不可能是无限大的,它是有大小的,就可能出现溢出。

客户端缓冲区的溢出有下面几种情况

  1. 写入了bigkey,比如写入的集合数据达到了百万级

  2. Redis 主线程发生阻塞,这个问题,以前文章阐述过,客户端不断向输入缓冲区写入命令,此时主线程无法处理,就溢出了

可以通过下面这种方式查看输入缓冲区的使用情况:client list

通过上图可以看到每个客户端对应一行数据,包括客户端的ip 地址,以及输入缓冲区使用了大小,输入缓冲区尚未使用的大小。

cmd,客户端最新执行的命令,qbuf 输入缓冲区已经使用的大小, qbuf-free 缓冲区尚未使用的大小。这个客户端分配的缓冲区大小 = qbuf+qbuf-free

如果 qbuf-free 很小的话,下次的命令大于 qbuf-free 的话,此时redis 又不能及时处理输入缓冲区数据时,就会造成输入缓冲区溢出,那么Redis 就会关闭这个客户端。

  1. Redis 服务器端不止一个客户端,当多个客户端连接占用的内存总量>redis 的 maxmemory 配置时,就会触发Redis 数据淘汰。

  2. 如果没有设置maxmemory时,那么多客户端连接可能会耗尽服务器所有内存,服务器奔溃了。

对于第1点,可能会说调大输入缓冲区,不好意思,没有这个参数可以设置,都是redis 代码写死的,大概是1G,不同版本也可能会不一样,记住是无法调整的,既然无法调整,那就是写命令,避免写入bigkey,避免redis 主线程阻塞 第2点,就是集群,现在都是这么干的

输出缓冲区

输出缓冲区有两部分组成:一部分,是一个大小为 16KB 的固定缓冲空间,用来暂存 OK 响应和出错信息;另一部分,是一个可以动态增加的缓冲空间,用来暂存大小可变的响应结果。

有下面几种情况下,输出缓冲区会溢出:

  1. 服务器端返回 bigkey 的大量结果,把溢出缓冲区内存打爆

  2. 执行了 MONITOR 命令 就会持续输出监控命令到输出缓冲区

  3. 输出缓冲区设置的太小,也就是 client-output-buffer-limit

输出缓冲区是如何设置的,可以用命令:client-output-buffer-limit,如下图

normal ,pubsub , slave 分布是下列,我分别讲解 分别是常规和 Redis 服务器端进行读写命令交互的普通客户端,(normal) 以及订阅了 Redis 频道的订阅客户端. (pubsub) 在 Redis 主从集群中,主节点上也有一类客户端(从节点客户端)用来和从节点进行数据同步 (slave)

普通客户端输出缓冲区设置 client-output-buffer-limit normal 0 0 0 第 1 个 0 设置的是缓冲区大小限制,第 2 个 0 和第 3 个 0 分别表示缓冲区持续写入量限制和持续写入时间限制。这个一般都会这么设置 普通客户端写入命令,都会等待Redis 返回,在发送下一个命令,不是大的bigkey,输出缓冲区不会阻塞,也不会溢出。所以这么设置

订阅客户端设置缓冲区大小,为了好描述,这里用单位M client-output-buffer-limit pubsub 8mb 2mb 60 订阅客户端和普通客户端不太一样,订阅客户端不是阻塞的,如果向频道发送大量的数据就会占用较多的输出缓冲区 8Mb 输出缓冲区大小,2mb 60 表示60秒写2MB 的数据。这两个条件只要满足一个,客户端就会关闭连接

集群缓冲区

主从集群间数据复制包括两种全量复制和增量复制。这两种复制都会用到缓冲区,这两个问题,我们分开讨论。

全量复制缓冲区问题

全量复制指的是从节点与主节点第一次连接,主节点会把主节点的RDB 传给从节点去执行。这就是全量复制。此时主节点会继续接收客户端的写请求,而这些请求会先保存在复制缓冲区中,等RDB传输完成后,在把复制缓冲区的命令给从节点,如果有多个从节点,那就有多个复制缓冲区。用来保证所有主从节点间数据同步。

那么如果在全量复制时,从节点接收和加载 RDB 较慢,同时主节点接收到了大量的写命令,写命令在复制缓冲区中就会越积越多,最终导致溢出。

其实我们可以看到主节点的复制缓冲区就是从节点的输出缓冲区,如果这个缓冲区溢出了,那么主节点也会直接关闭和从节点进行复制操作的连接,导致全量复制失败。

如何避免了复制缓冲区溢出,我感觉有两点:

  1. 控制主节点保存数据量的大小,一般会把主节点数据量控制在2-4GB,这样,RDB 文件小,主从同步快,同时也不至于复制缓冲区因为写了太多而没有及时传给从节点导致复制缓冲区溢出

  2. 可以通过 client-output-buffer-limit 命令设置复制缓冲区合适的大小。主要是根据,主从节点数量大小、主节点的写负载压力和主节点本身的内存大小。

  3. 还有一个问题我要提一下,复制缓冲区的内存开销是每个从节点客户端输出缓冲区占用内存的总和,这一点大家一定要记住。

可以这么设置:

client-output-buffer-limit slave 512mb 128mb 60

复制缓冲区大小是512mb,60秒写入128M。两个条件满足其中之一表示复制缓冲区溢出,此时全量复制失败了

所有从节点的客户端输出缓冲区之和是512mb

增量复制缓冲区问题

增量复制只会把主从库网络断连期间主库收到的命令,同步给从库。主节点把接收到的写命令同步给从库时,同时也会把这些命令写入 复制积压缓冲区。主从网络中断后,再次和主节点恢复连接后,从节点就会从复制积压缓冲区中,读取断连期间主节点接收到的写命令,进而进行增量同步。

首先我们要明白复制积压缓冲区是一个大小有限的环形缓冲区。当主节点把复制积压缓冲区写满后,会覆盖缓冲区中的旧命令数据。如果从节点还没有同步这些旧命令数据,就会造成主从节点间重新开始执行全量复制。

其次可以 repl_backlog_size 调整复制积压缓冲区的大小,这个大小怎么设置呢,根据下面的规则:

这个参数和所需的缓冲空间大小有关。缓冲空间的计算公式是:缓冲空间大小 = 主库写入命令速度 * 操作大小 - 主从库间网络传输命令速度 * 操作大小。在实际应用中,考虑到可能存在一些突发的请求压力,我们通常需要把这个缓冲空间扩大一倍,即 repl_backlog_size = 缓冲空间大小 * 2,这也就是 repl_backlog_size 的最终值。

好了,写到这里,有问题记得给我留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1509604.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何用BI工具对数据进行预处理?数据分析的这项技巧你必须掌握。

在当今数字化时代,数据不仅是企业决策的基础,也是创新和发展的关键推动力。在面对庞大而复杂的数据集时,如何进行高效的预处理成为了数据分析领域中至关重要的一步。 在进行数据处理和分析的日常工作中,业务普遍使用Excel和SQL这两…

异步编程和asyncio

介绍异步编程的重要性和在Python中的应用,特别是在I/O密集型任务和网络编程场景下。 目录 理解异步编程 异步编程基本概念 任务与Future 异步编程的工作原理 事件循环 协程(Coroutines) 异步与同步代码的结合 深入asyncio模块 事件循…

day61 数据库约束 jdbc

回顾 1 SQL语句的分类 2创建表的语法 create table 表名( 列名 数据类型 not null, 列名 数据类型 ); 3 删除表 drop table 表名; 数据完整性分类 1实体完整性 (表中每条记录唯一) 2域完整性 3引用完整性 数据完整性约束 实体完整性约束 主键约束 表…

使用 mysqldump 迁移 MySQL 表 OceanBase

使用 mysqldump 迁移 MySQL 表 OceanBase 一、什么是mysqldump二、使用mysqldump导出MySQL数据三、将数据导入到OceanBase四、注意 一、什么是mysqldump mysqldump 是 MySQL 数据库管理系统中的一个工具,用于将数据库中的数据导出为文本文件。它可以将整个数据库、…

spring boot 访问 static public 目录下的静态资源报404解决办法

1.前提是你没有修改spring boot 默认拦截路径,跟默认访问资源的目录。 在idea 设置中 把 compiler 下的 Buid project automatically 勾选上

多场成像,快速提高机器视觉检测能力--51camera

多阵列CMOS传感器与芯片级涂层二向色滤光片相结合,可在单次扫描中同时捕获明场、暗场和背光图像。 多场成像是一种新的成像技术,它可以在不同的光照条件下同时捕获多幅图像。再加上时间延迟积分(TDI),这种新兴的成像技术可以克服许多限制的传…

关于VScode中使用yapf,更改settings.json文件中的column_limit没有作用的解决方法。

目录 一、yapf一行中最大字符限制修改 二、忽略flake8对一行中最大字符限制警告 写在前面,不知道啥情况,按照常见的方式更改settings.json文件不起作用,如这些大佬的文章VSCode配置yapf python格式化 配置一行的长度 、vscode中使用yapf自动格…

思科网络中如何配置扩展ACL协议

一、什么是扩展ACL协议?有什么作用及配置方法? (1)扩展ACL(Extended Access Control List)协议是一种网络安全协议,用于在路由器或防火墙上实现对数据包的细粒度访问控制。与标准ACL相比&#…

【Python】牛客网—软件开发-Python专项练习

专栏文章索引:Python 1.(单选)下面哪个是Python中不可变的数据结构? A.set B.list C.tuple D.dict 可变数据类型:列表list[ ]、字典dict{ }、集合set{ }(能查询,也可更改)数据发生改…

对象注入的几种方式

⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:JavaEE 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 注入对象 1. 属性注入2. 构造方法注入3. S…

RabbitMQ详解与常见问题解决方案

文章目录 什么是 RabbitMQ?RabbitMQ 和 AMQP 是什么关系?RabbitMQ 的核心组件有哪些?RabbitMQ 中有哪几种交换机类型?Direct Exchange(直连交换机)Topic Exchange(主题交换机)Headers Exchange(头部交换机)Fanout Exchange(广播交…

(黑马出品_07)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

(黑马出品_07)SpringCloudRabbitMQDockerRedis搜索分布式 微服务技术分布式搜索 今日目标1.数据聚合1.1.聚合的种类1.2.DSL实现聚合1.2.1.Bucket聚合语法1.2.2.聚合结果排序1.2.3.限定聚合范围1.2.4.Metric聚合语法1.2.5.小…

01_04_JavaWEB03_XML、Tomcat、http

XML_Tomcat10_HTTP 参考尚硅谷再总结复习 一 XML XML是EXtensible Markup Language的缩写,翻译过来就是可扩展标记语言。所以很明显,XML和HTML一样都是标记语言,也就是说它们的基本语法都是标签。 可扩展 三个字表面上的意思是XML允许自定义…

云服务器2核4G配置,阿里云和腾讯云哪个便宜?性能更好?

租用2核4G服务器费用多少?2核4G云服务器多少钱一年?1个月费用多少?阿里云2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年;腾讯云轻量2核4G服务器5M带宽165元一年、252元15个月、540元三…

RNN实战

本主要是利用RNN做多分类任务,在熟悉RNN训练的过程中,我们可以理解 1)超参数 batch_size和pad_size对训练过程的影响。 2)文本处理过程中是如何将文本的文字表示转化为向量表示 3)RNN梯度消失和序列长度的关系 4&#…

企商在线CTO楼炜:论云计算与产业互联网

024年全国两会召开之际,3月4日,全国政协委员、京东集团技术委员会主席曹鹏提交了《发挥产业互联网平台作用 打造实体产业数字化转型直效通道》提案,提出了产业互联网平台在整合供应链、资金、技术、资讯、培训、人才等各类资源的重要作用。云…

python实现生成树

生成树 生成树(Spanning Tree)是一个连通图的生成树是图的极小连通子图,它包含图中的所有顶点,并且只含尽可能少的边。这意味着对于生成树来说,若砍去它的一条边,则会使生成树变成非连通图;若给…

ChatGpt只能看,但无法发送消息的解决办法

这几天发现chatgpt没法发送消息了,我以为是网络问题,又过了几天还是不能发,我以为是梯子的问题,可给我急坏了,于是我用无痕模式发现可以访问额. 但是无痕模式毕竟不是长久之计,于是找到了一个方法 1.首先把电脑缓存全清除了 第一种方法: 快捷键是 : ctrlshiftdel (这会吧浏览…

电脑切屏卡顿,尤其是打游戏时切屏卡顿问题解决方法

博主在打游戏时喜欢切后台但是最近发现切屏尤其慢,异常卡顿,但是是新换的电脑,所以苦恼了半天,上网搜也没有结果,说的都是些配置低,系统文件损坏等问题,所以再检查分辨率时发现问题所在 屏幕分辨…

Visual Studio 2022 配置“Debug|x64”的 Designtime 生成失败。IntelliSense 可能不可用。

今天写代码,无缘无故就给我整个这个错误出来,我一头雾水。 经过我几个小时的奋战,终于解决问题 原因就是这个Q_INTERFACES()宏,我本想使用Q_DECLARE_INTERFACE Q_INTERFACES这两个Qt宏实现不继承QObject也能使用qobjec…