redis--堵塞

一、简介

众所周知Redis 是典型的单线程架构,所有的读写操作都是在一条主线程中完成的。当Redis用于高并发场景时,这条线程就变成了它的生命线。如果出现阻塞,哪怕是很短时间,对于我们的应用来说都是噩梦,导致阻塞问题的场景大致分为内在原因和外在原因
 
 

二、造成堵塞内在原因

1.API 或 数据结构 使用不合理

通常 Redis 执行命令速度非常快,但也存在例外,如对一个包含上万个 元素的hash 结构执行 hgetall 操作,由于数据量比较大且命令算法复杂度是 O( n ),这条命令执行速度必然很慢。这个问题就是典型的不合理使用 API 和数据结构。对于高并发的场景我们应该尽量避免在大对象上执行算法复杂度超过O n )的命令

排查:
(1)发现慢查询:执行 slowlog get {n}
(2)发现大对象:执行 redis-cli -h {ip} -p {port} --bigkeys

解决:

(1)解决慢查询:调整命令为低算法度命令
(2)调整大对象:把大对象拆分为多个小对象,防止一次命令操作过多数据

 

2.CPU饱和

单线程的 Redis 处理命令时只能使用一个 CPU 。而 CPU 饱和是指 Redis 把 单核CPU 使用率跑到接近 100% 。使用 top 命令很容易识别出对应 Redis 进程的 CPU使用率。
 
排查
(1)查看CPU使用率:执行  top 命令

(2)查询Redis并发量:执行 redis-cli -h {ip} -p {port} --stat 命令
解决:
(1)集群化水平拓展分摊OPS压力
(2)检查是否有过度的内存优化

3.持久化堵塞

对于开启了持久化功能的 Redis 节点,需要排查是否是持久化导致的阻 塞。持久化引起主线程阻塞的操作主要有:fork 阻塞、 AOF 刷盘阻塞、 HugePage写操作阻塞

(1)fork堵塞
fork操作发生在RDBAOF重写时,Redis主线程调用fork操作产生共享 内存的子进程,由子进程完成持久化文件重写工作。如果fork操作本身耗时 过长,必然会导致主线程的阻塞
排查:
检查最近fork操作耗时:执行 info status 获取到 latest_fork_usec 指标,若fork操作耗时超过1秒,避免使用过大的内存实例和规避fork缓慢的操作系统

(2)AOF刷盘堵塞
当我们开启AOF持久化功能时,文件刷盘的方式一般采用每秒一次,后 台线程每秒对AOF文件做fsync操作。当硬盘压力过大时,fsync操作需要等 待,直到写入完成。

排查:
如果主线程发现距离上一次的fsync成功超过2秒,为了 数据安全性它会阻塞直到后台线程执行fsync操作完成。这种阻塞行为主要 是硬盘压力引起

(3)HugePage写操作阻塞

子进程在执行重写期间利用 Linux 写时复制技术降低内存开销,因此只 有写操作时Redis 才复制要修改的内存页。对于开启 Transparent HugePages 的 操作系统,每次写命令引起的复制内存页单位由4K 变为 2MB ,放大了 512 倍,会拖慢写操作的执行时间,导致大量写操作慢查询。例如简单的incr 命令也会出现在慢查询中。

三、外在原因

1.CPU竞争

(1)进程竞争 Redis 是典型的 CPU 密集型应用,不建议和其他多核 CPU 密 集型服务部署在一起。当其他进程过度消耗CPU 时,将严重影响 Redis 吞吐 量。可以通过top sar 等命令定位到 CPU 消耗的时间点和具体进程,这个问 题比较容易发现,需要调整服务之间部署结构
(2) 绑定CPU:部署Redis时为了充分利用多核CPU,通常一台机器部署多个实例。常见的一种优化是把Redis进程绑定到CPU上,用于降低CPU频繁上下文切换的开销(开启了持久化或参与复制的主节点不建议绑定CPU,因为子进程会占用90%竞争)

2.内存交换

内存交换( swap )对于 Redis 来说是非常致命的, Redis 保证高性能的一个重要前提是所有的数据在内存中。如果操作系统把Redis 使用的部分内存 换出到硬盘,由于内存与硬盘读写速度差几个数量级,会导致发生交换后的 Redis性能急剧下降

(1)排查方案:

  1. 查询Redis进程号:执行 redis-cli -p 6383 info server | grep process_id 命令
  2. 根据进程号查询内存交换信息:执行 cat /proc/process_id/smaps | grep Swap 

如果交换量都是0KB或者个别的是4KB,则是正常现象,说明Redis进程内存没有被交换。

(2)预防内存交换的方法有:
保证机器充足的可用内存。

确保所有Redis实例设置最大可用内存(maxmemory),防止极端情况下Redis内存不可控的增长。

降低系统使用 swap 优先级

3.网络问题

网络问题经常是引起 Redis 阻塞的问题点。常见的网络问题主要有:连接拒绝、网络延迟、网卡软中断等。

排查:

(1)网络闪断:通过 sar -n DEV 查看本机历史流量是否正常

(2)Redis连接拒绝:执行 redis-cli -p 6384 info stats | grep rejected_connections查看所有被拒绝的连接数量

(3)连接溢出:执行ulimit -n命令,检查操作系统对进程使用资源的限制;执行 netstat -s | grep overflowed命令,检查是否有持续增长的连接拒绝

(4)网络延迟:执行redis-cli -h {host} -p {port} --latency 命令,测量机器之间的网络延迟

解决方案:

(1)避免客户端与Redis之间异地跨机房调用

(2)客户端访问Redis时尽量采用NIO长连接或者连接池的方式

(3)对于支撑大量连接的Redis需要增大 ulimit 值,修改系统backlog值

(4)调整网络拓扑结构,同物理机>同机架>跨机架>同机房>同城机房>异地机房

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值