首页 > 数据库 >redis缓冲区:缓冲区大小可以随意设置吗?

redis缓冲区:缓冲区大小可以随意设置吗?

时间:2022-10-28 11:05:31浏览次数:49  
标签:随意 redis Redis 命令 溢出 缓冲区 服务端 客户端

前言

我们都知道缓冲区是为了应对数据传递两端发送和接收速度不一致的方案。但如果缓冲区占用的资源超出设定的上限时,就会出现缓冲区溢出。

Redis是典型的客户端-服务端架构,在客户端与服务端通信过程中,缓冲区就是一个常用的方案。另外,在配置主从集群的Redis架构中,主从节点数据同步过程中,也用到了缓冲区。接下来我们看看客户端与服务端如果发生缓冲区溢出,我们该如何应对及规避。

客户端-服务端缓冲区

客户端和服务端,往往配置及网络状况不一致。为了应对请求的发送及处理速度的不匹配,服务端有做这么一个操作,就是给每个连接的客户端设置输入缓冲区和输出缓冲区

输入缓冲区会将客户端的发送命令暂存到缓冲区,Redis再从缓冲区取出命令来执行。当命令执行完成后,也不是直接的返回给客户端,也会将执行结果暂存到输出缓冲区,最后输出缓冲区将结果发送给客户端。画个图看看更好理解。

redis缓冲区:缓冲区大小可以随意设置吗?_redis

输入缓冲区溢出

由上面概念我们得知输入缓冲区是用来暂存客户端的请求命令,很容易分析得出输入缓冲区溢出的情况:

  • 发送了bigkey,比如发送了多个大数据量的哈希数据。
  • 服务端处理速度太慢,比如redis出现了阻塞。

如何解决输入缓冲区溢出问题呢?首先我们得知道缓冲区的资源使用问题。

我们可以用​​CLIENT LIST​​来获取每个客户端的输入缓冲区使用情况。

127.0.0.1:6379> client list
id=6 addr=127.0.0.1:59256 fd=8 name= age=8 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 events=r cmd=client

输出有很多信息,我们关注这几个数据:

  • cmd:表示客户端执行的最新命令;
  • qbuf:表示缓冲区已使用的内存大小;
  • qbuf-free:表示缓冲区的剩余空间。

通过这三个数据,我们能知道缓冲区的使用量及剩余空间。当发现qbuf-free很小时,就要注意缓冲区溢出的问题。这个时候再发送大量命令,就可能导致输入缓冲区溢出,Redis会将客户端连接直接关闭。

而且,当有多个客户端连接,输入缓冲区超过redis设置的maxmemory值时,就会触发Redis的另一机制---数据淘汰。更麻烦的是,如果整个Redis的内存占用过大,可能会导致内存溢出,这也就意味着Redis会崩溃。

输入缓冲区溢出的解决

为避免输入缓冲区溢出,我们一般能想到2个方法去应对:

  • 缓冲区阈值适当调大;
  • 控制命令写入和命令处理速度。

第一个方法,因redis没有设置参数来调节,所以方法行不通。而且 源码设置的阈值是1GB,这个数值已经够大了,改源码的意义也不大。

因此,我们寄希望于第二个方法,避免bigkey的写入、避免Redis主线程的阻塞。

输出缓冲区溢出

Redis为每个客户端有设置输出缓冲区,一部分是用来暂存OK响应和报错信息的,大小固定为16KB;还一部分是用来暂存大小可变的响应结果,它的大小是动态可变的。

分析一下输出缓冲区溢出的情况:

  • 结果中有bigkey;
  • 使用了MONITOR命令;
  • 缓冲区大小设置不合适。

第一点很好理解,不用多说。再看看第二点,MONITOR是监测Redis的命令,执行之后会持续监测Redis的每个命令操作。因此,MONITOR使用越久,监测的结果就越多,空间自然约占越多。因此我们慎用MONITOR命令,尽量不在生产环境使用。

最后看看第三点,输出缓冲区的大小是可配置的,配置项是client-output-buffer-limit

client-output-buffer-limit normal 0 0 0
| | | | - - - 持续写入时间限制
| | | - - - - 缓冲区持续写入量限制
| |- - - - - -缓冲区持续写入量限制
| - - - - - - - - 普通客户端

备注:normal代表普通客户端, 第一个0表示缓冲区大小限制,第二个0表示缓冲区持续写入量限制,第三个0表示持续写入时间限制。

配置时,我们首先要确认下客户端与服务端的交互方式。如果是普通客户端(命令读写),因为都是阻塞式的发送命令,经验上通常都设置为0;但如果是发布订阅模式的客户端,客户端和服务器间的消息发送方式不属于阻塞式发送,因此需要给缓冲区限制一下。

client-output-buffer-limit pubsub 8mb 2mb 60

如上配置,pubsub表示是订阅客户端,8mb表示缓冲区上限8MB,2mb 60表示60秒内连续写入到输出缓冲区的数据量超过2MB,服务端会关闭客户端连接。

小结

本文总结了一下客户端与服务端缓冲区的知识以及如何避免缓冲区溢出的方法。熟悉这些知识,对我们排查Redis问题有很大的帮助。

标签:随意,redis,Redis,命令,溢出,缓冲区,服务端,客户端
From: https://blog.51cto.com/u_15773567/5803812

相关文章

  • RedisTimeSeries实时时序数据库
    一、时序数据库是什么?时间序列数据库TimeSeriesDatabase(TSDB)时序数据是随时间不断产生的一系列数据,简单来说,就是带时间戳的数据。1.时序数据库相关概念度量Me......
  • Redis基础课程讲义
    1.1什么是RedisRedis是一个基于内存的key-value结构数据库。Redis是互联网技术领域使用最为广泛的存储中间件,它是「RemoteDictionaryService」的首字母缩写,也就是「远......
  • Redis缓存满了怎么办
    Redis缓存满了怎么办?​ 当使用redis作为数据库的缓存,是为了避免业务应用直接从后端数据库读取数据;采用redis储存数据可以提升系统的响应速度.​ 但是如果将大量数据全......
  • C/C++清理输入缓冲区中的内容
    C/C++清理输入缓冲区中的内容1.清理输入缓冲区最后剩下的单个回车符:方法一:用getchar函数读取回车符:方法二:用scanf("%*c")读取掉回车符:方法三:用scanf("%c",&ch):2.清理输入......
  • Redis持久化----RDB
    Redis持久化----RDB原理当采用RDB这种方式来持久化Redis中的数据时,是向RDB文件中写入redis的快照;什么是内存快照:​ 所谓内存快照,就是指内存中的数据在某⼀个时刻的......
  • Redis的单线程和高性能
    Redis是单线程吗?Redis的单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的,这也是Redis对外提供键值存储服务的主要流程。但Redis的其他功能,比如持久......
  • Redis开发规范与性能优化
    目录一、键值设计二、命令使用三、客户端使用四、系统内核参数优化一、键值设计1.key名设计【建议】可读性和可管理性以业务名(或数据库名)为前缀(防止key冲突),用冒号......
  • redis使用实例
    //检查key是否存在,返回boolean值1.stringRedisTemplate.hasKey(Stringkey)//根据key获取缓存中value2.stringRedisTemplate.opsForValue().get(Objectkey)//截取key......
  • OpenResty+mysql+redis
    1、       ad_load.lua  nginx.conf1、读取mysql并缓存redis     参考:https://www.cnblogs.com/bbgs-xc/p/14437703.html https:/......
  • Redis常用概念及操作
    目录概述是什么?常见的作用缓存分布式锁五种数据结构String常用命令应用场景Hash常用命令应用场景优缺点优点缺点Set常用命令应用场景List常用命令Zset常用命令应用场景其它......