前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis的缓冲区

Redis的缓冲区

原创
作者头像
夜半钟鸣
修改2021-02-19 15:50:23
1.3K0
修改2021-02-19 15:50:23
举报
文章被收录于专栏:小树洞小树洞

前言

数据交互场景中,缓冲区的存在起到了至关重要的作用,比如

  • 关系型数据库中的数据缓冲区,可以加速数据的存和取,避免和磁盘的直接交互
  • 消息中间件也是利用了缓冲的思想,有效缓解了业务高峰期上游对下游系统的读写压力,起到“削峰填谷”作用

在Redis中,也存在缓冲区,即使Redis本身就是将数据存储在内存中,但也利用了内存缓冲区来避免因为请求处理速度跟不上请求接收速度而导致的数据丢失和性能问题。

有哪些缓冲区

客户端输入/输出缓冲区

Redis是C/S架构,所有的操作命令都会通过客户端然后发往服务端。

  • 客户端输入缓冲区: 即用来缓存客户端发往服务端的操作命令
  • 客户端输出缓冲区: 即用来缓存服务端返回给客户端的结果数据。

需要注意的是,Redis会给每个连接的客户端都设置一个输入缓冲区和输出缓冲区,如下图所示:

img
img

复制缓冲区/复制积压缓冲区

Redis的主从复制可以分为全量复制和增量复制。两种复制都会利用到缓冲区来暂存数据。

  • 复制缓冲区 主库接收到全量复制请求时,会创建RDB文件,同时会将接下来所有的写命令记录到复制缓冲区中,当从库接收并加载完RDB文件后,主库再向从库发送复制缓冲区中保存的所有写命令
  • 复制积压缓冲区 复制积压缓冲区是redis主库维护的一个固定长度(fixed-size)先进先出(FIFO)的队列,默认1MB。主库除了会将写命令发往从库,还会将命令写入复制积压缓冲区。这是为了防止主从断连而导致的数据丢失问题。

避免缓冲区溢出

缓冲区的大小总是有上限的,当其中的数据积压太多就会发生缓冲区溢出的情况。

下面来说下Redis几种缓冲区发生溢出的原因和解决方法

输入缓冲区溢出

溢出后果

  • 输入缓冲区溢出,则对应的客户端连接会被Redis关闭,导致业务受影响
  • 多个客户端连接占用的内存总量超过maxmemory阈值时会触发redis数据淘汰,当redis作为数据库前端缓存使用时会降低业务访问性能

原因

  • 写入了bigkey
  • redis主线程出现间歇性阻塞,请求处理速度变慢,导致缓冲区中堆积数据越来越多

查看输入缓冲区内存使用情况

代码语言:javascript
复制
1127.0.0.1:6379> client list2id=3 addr=127.0.0.1:45848 fd=8 name= age=2 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
  • qbuf表示已使用的缓冲区大小
  • qbuf-free表示还未使用的缓冲区大小

qbuf + qbuf-free = 32768 bytes=32KB, 即这个连接分配得到的缓冲区大小为32KB。

避免

  • 输入缓冲区大小阈值在redis代码中被设定为1GB,没有参数可以调整这个阈值,除非自己修改源代码更改
  • 制定key的创建规范,避免写入bigkey
  • 避免Redis主线程的阻塞发生

输出缓冲区溢出

溢出后果

输出缓冲区溢出,则对应的客户端连接会被Redis关闭,导致业务受影响

原因

  • 返回了bigkey等大的结果集
  • 缓冲区大小设置不合理
  • 执行了时间较长的monitor命令

避免

  • 避免bigkey 操作返回大量数据结果
  • 避免在线上环境持续使用monitor命令
  • 使用 client-output-buffer-limit 设置合理的缓冲区大小上限,或是缓冲区连续写入时间和写入量上限。

输出缓冲区大小设置

redis的客户端,除了主从架构中的从节点客户端(作用于和从节点进行数据同步)外,主要使用两类:

  • 常规和Redis服务端进行读写命令交互的普通客户端
  • 订阅了Redis频道的消息订阅客户端

以上两种客户端的输出缓冲区大小可以通过如下参数进行设置:

代码语言:javascript
复制
client-output-buffer-limit normal 0 0 0       # normal表示针对普通客户端,后续3个0依次表示缓冲区大小限制,缓冲区持续写入量限制,缓冲区持续写入时间限制,0表示不作限制,为建议值
2client-output-buffer-limit pubsub 8mb 2mb 60 # pubsub表示针对订阅客户端,8mb表示输出缓冲区大小上限,2mb和60表示:如果连续 60 秒内对输出缓冲区的写入量超过 2MB 的话,服务器端也会关闭客户端连接

复制缓冲区溢出

溢出后果

主节点会直接关闭和从节点进行复制操作的连接,导致全量复制失败

原因

  • 从节点接收和加载RDB文件较慢
  • 主节点数据量较大,复制积压缓冲区相对过小

避免

  • 控制主节点的数据量大小,2~4GB为佳
  • 合理设置针对从节点客户端的参数项client-output-buffer-limit
代码语言:javascript
复制
client-output-buffer-limit slave 512mb 128mb 60  # 521mb表示针对复制缓冲区大小上限,128mb和60表示:如果连续60s内的写入量超过128mb也会触发复制缓冲区溢出注意点

注意点:

  • 主从复制缓冲区的内存大小不会计入maxmemory,也就不会是内存达到上限触发数据淘汰策略的影响因素
  • 每个从节点客户端都占有一个复制缓冲区,含多个从库时需要考虑redis服务端的内存使用压力,防止发生OOM现象

复制积压缓冲区溢出

溢出后果

复制积压缓冲区发生溢出即新的命令会覆盖旧的命令,如果从节点还没有同步这些旧的数据,则会造成主从重新执行全量复制

原因

  • 写入频繁,复制积压缓冲区设置过小
  • 从节点写入性能较慢

避免

  • 检查从节点性能是否正常
  • 调整复制积压缓冲区大小参数repl_backlog_size 估算方法:second * write_size_per_second
    • second: 断线后从库重新连接上主库所需的平均时间(秒)
    • write_size_per_second: 主库平均每秒产生的写命令数据量

    repl_backlog_size可设为2倍于此估算值的大小

参考

https://time.geekbang.org/column/article/291277

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 有哪些缓冲区
    • 客户端输入/输出缓冲区
      • 复制缓冲区/复制积压缓冲区
      • 避免缓冲区溢出
        • 输入缓冲区溢出
          • 输出缓冲区溢出
            • 复制缓冲区溢出
              • 复制积压缓冲区溢出
              • 参考
              相关产品与服务
              云数据库 Redis
              腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档