Redis的所有读写操作都是在一条主线程中完成的,当Redis用于高并发场景时,非常重要。

  • 阻塞的原因有:
    1.内在原因:不合理使用数据结构和API、CPU饱和、持久化阻塞等
    2.外在原因:CPU、内存、网络

发现阻塞

应用内

Redis阻塞发生时,线上应用服务会最先感知到,这是应用方会受到大量Redis超时异常,应该在应用中加入异常统计并通过邮件/短信/微信报警,以便及时发现通知问题

调用Redis的API会分散在项目多个地方,全部监控代码会难以维护。可以用日志系统,当异常发生时,异常信息最终会被日志系统收集到日志文件,可以自定义日志文件专门统计异常和触发报警逻辑

非应用内

还可借助Redis监控系统发现阻塞问题,Redis相关的监控系统开源方案有很多,当系统检测到Redis运行起的一些关键指标出现不正常时触发报警。

内在原因

定位到具体的Redis节点异常后,应首先排查是否为Redis自身原因

  • 定位:
    1.API或数据结构使用不合理
    2.CPU饱和的问题
    3.持久化相关的阻塞

API或数据结构使用不合理

对于高并发场景应该尽量避免在大对象上执行算法复杂度超过O(n)的命令。

如何发现慢查询

Redis原生提供慢查询统计功能

  • slowlog get [n]:获得最近n条慢查询记录

如何发现大对象

Redis提供发现大对象的工具:redis-cli -h [ip] -p[port] bigkeys
image.png

CPU饱和

单线程的Redis处理命令时只能使用一个CPU,CPU饱和是指Redis把单核CPU使用率跑到接近100%。使用top命令可以查看
解决办法可以使用集群化水平扩展来分摊OPS压力

持久化阻塞

持久化阻塞的主要操作有:fork阻塞、AOF阻塞、HugePage写操作阻塞

fork阻塞

fork操作发生在RDB和AOF重写时,应避免使用过大内存实例和规避fork缓慢的操作系统

AOF刷盘阻塞

这种阻塞行为主要是硬盘压力引起,可能为Redis进程引起,也可能为其他进程引起

HugePage写操作阻塞

外在原因

  • 外部有:
    1.CPU竞争
    2.内存交换
    3.网络问题

CPU竞争

进程竞争

当其他进程过度消耗CPU时,将严重影响Redis吞吐量,可以通过top、sar等命令定位,可以调整服务之间部署结构

绑定CPU

部署Redis时为了充分利用多核CPU,通常一台机器部署多个CPU,并把Redis绑定到CPU上,降低CPU频繁切换上下文。但当Redis父进程创建子进程进行RDB/AOF重写时会产生激烈竞争,所以开启了持久化或主节点不建议绑定CPU

内存交换(swap)

内存交换对于Redis来说是非常致命的,Redis保证高性能的一个重要前提是所有的数据在内存中,如果使用硬盘速度差距很大
可使用如下命令查看
image.png
交换量为0或4KB为正常现场,说明Redis进程内存没有被交换

  • 预防被交换的方法:
    1.保证足够多的可用内存
    2.确保所有Redis实例设置最大可用内存,防止极端情况下Redis内存不可控增长
    3.降低系统使用swap优先级

网络问题

  • 主要为:
    1.拒绝连接
    2.网络延迟
    3.网卡软中断

连接拒绝

网络延迟

网卡软中断


这个家伙很懒,啥也没有留下😋