程序地带

Redis性能篇(五)Redis缓冲区


Redis被广泛使用的一个很重要的原因是它的高性能。因此我们必要要重视所有可能影响Redis性能的因素、机制以及应对方案。影响Redis性能的五大方面的潜在因素,分别是:


Redis内部的阻塞式操作
CPU核和NUMA架构的影响
Redis关键系统配置
Redis内存碎片
Redis缓冲区

这一讲,我们来学习一下Redis缓冲区的相关知识。


缓冲区的功能是用一块内存来暂存命令数据,避免出现因为数据和命令的处理速度慢于发送速度而导致的数据丢失和性能问题。但缓冲区的内存空间有限,如果发生溢出,就会丢失数据。


Redis缓冲区有两个应用场景:


在客户端和服务器端之间进行通信时,用来暂存客户端发送的命令数据,或者是服务器端返回给客户端的数据结果;
主从节点间进行数据同步时,用来暂存主节点接收的写命令和数据。
客户端输入和输出缓冲区

image


如何应对输入缓冲区溢出

可能导致溢出的情况有两种:写入了bigkey;服务器端处理请求的速度过慢。


如何查看输入缓冲区的内存使用情况:使用CLIENT LIST命令:


CLIENT LIST id=5 addr=127.0.0.1:50487 fd=9 name= age=4 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,表示输入缓冲区尚未使用的大小;

客户端输入缓冲区大小=qubf+qbuf-free。


如何避免输入缓冲区溢出:一是把缓冲区调大;二是从数据命令的发送和处理速度入手。


首先,输入缓冲区不能通过参数调整,在代码里设置客户端输入缓冲区大小上限阈值为1GB。


其次,避免客户端写入bigkey。


如何应对输出缓冲区溢出

可能导致溢出的情况有三种:


服务器端返回bigkey的大量结果;
执行了MONITOR命令;
缓冲区大小设置得不合理。

首先,避免bigkey操作返回大量数据结果,可以使用SCAN命令。


其次,避免在线上环境中持续使用MONITOR命令。。MONITOR命令是用来监测Redis执行的。执行后,会持续输出监测到各个命令操作。MONITOR的输出结果会持续占用输出缓冲区,越占越大,最后发生溢出。MONITOR命令主要用在调试环境中,不要在线上生产环境中持续使用MONITOR。


最后,使用client-output-buffer-limit设置合理的缓冲区大小上限,或是缓冲区连续写入时间和写入量上限:


设置缓冲区大小的上限阈值;
设置输出缓冲区持续写入数据的数量上限阈值,和持续写入数据的时间的上限阈值。

按照客户端类型不同,设置也不同:


普通客户端:client-output-buffer-limit normal 0 0 0。通常把普通客户端的缓冲区大小限制,以及持续写入量限制、持续写入时间限制都设置为0,也就是不做限制;
订阅客户端:client-output-buffer-limit pubsub 8mb 2mb 60;
从节点客户端:在介绍主从集群中的缓冲区时再具体说明。
主从集群中的缓冲区

主从集群间的数据复制包括全量复制和增量复制。无论哪种复制,都会用到缓冲区。


复制缓冲区的溢出问题

全量复制时,从节点接收和加载RDB慢,同时主节点接收到大量的写命令,复制缓冲区越积越多,最后导致溢出。一旦发生溢出,主节点会关闭从节点的连接,导致全量复制失败。


如何避免复制缓冲区发生溢出

首先,控制主节点保存的数据量大小,通常控制在2~4GB。


其次,通过client-output-buffer-limit配置项来设置合理的复制缓冲区大小:


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


在实际应用中设置复制缓冲区的大小时,可以根据写命令数据的大小和应用的实际负载情况来估计缓冲区中累积的写命令数据量。然后再和所设置的复制缓冲区大小进行比较,判断设置的缓冲区大小是否足够支撑累积的写命令数据量。


关于复制缓冲区的问题,因为复制缓冲区是在主节点上的,如果集群中的从节点非常多,主节点的内存开销就会非常大。所以,必须得控制和主节点连接的从节点个数。


复制积压缓冲区的溢出问题

增量复制时使用的缓冲区称为复制积压缓冲区。在基础篇第6讲中已经学过复制积压缓冲区了,叫repl_backlog_buffer。


首先,复制积压缓冲区是一个大小有限的环形缓冲区。当写入速度比读取速度要快,会导致溢出。主节点会关闭和从节点的连接,要重新进行同步。


为了应对复制积压缓冲区的溢出问题,可以调用复制积压缓冲区的大小,通过设置repl_backlog_size这个参数值。


总结

按缓冲区的用途分为:


客户端的输入和输出缓冲区;
主从集群中主节点上的复制缓冲区和复制积压缓冲区。

从缓冲区溢出对Redis的影响分类:


缓冲区溢出导致网络连接关闭;
缓冲区溢出导致命令数据丢失。

缓冲区溢出的原因及解决方案:


命令数据发送过快过大。普通客户端避免使用bigkey,复制缓冲区避免过大的RDB文件;
命令数据处理较慢。减少Redis主线程上的阻塞操作,例如使用异步的删除操作;
缓冲区空间过小。使用clinet-output-buffer-limit配置项设置合理的输出缓冲区、复制缓冲区和复制积压缓冲区大小。
参考资料
21 | 缓冲区:一个可能引发“惨案”的地方

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/liang24/p/14232895.html

随机推荐

Android 上传开源项目到 jcenter 实战踩坑之路

本文微信公众号「AndroidTraveler」首发。背景其实Android上传开源项目到jcenter并不是一件新鲜事,网上也有很多文章。包括我本人在将开源项目上传到jcenter的时候也是参考了一...

安卓小煜 阅读(528)

【Android】Android 性能优化 内存优化

内存优化关于性能优化我们可以不知道其他的,但一定要知道内存优化。因为内存泄漏可以Android的常客。那么什么是内存泄漏呢?内存不在GC的掌控范围之内了。那么Java的GC...

熊芳波 阅读(976)

JS正则表达式光速入门

什么是正则表达式正则表达式以前学过几次,但总是学了就忘,今天特意把所学都写下来。正则表达式是用于匹配字符串中字符组合的模式,在JavaScript中ÿ...

_zlfan 阅读(100)

C语言----无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。示例 1:输入:s="abcabcbb"输出:3 解释:因为无重复字符的最长子串是"abc...

ftzchina 阅读(795)