一、简介
二、造成堵塞内在原因
1.API 或 数据结构 使用不合理
排查:
(1)发现慢查询:执行 slowlog get {n}
(2)发现大对象:执行 redis-cli -h {ip} -p {port} --bigkeys
解决:
(1)解决慢查询:调整命令为低算法度命令
(2)调整大对象:把大对象拆分为多个小对象,防止一次命令操作过多数据
2.CPU饱和
top
命令
(2)查询Redis并发量:执行 redis-cli -h {ip} -p {port} --stat
命令
解决:
(1)集群化水平拓展分摊OPS压力
(2)检查是否有过度的内存优化
3.持久化堵塞
(1)fork堵塞
fork操作发生在RDB和AOF重写时,Redis主线程调用fork操作产生共享 内存的子进程,由子进程完成持久化文件重写工作。如果fork操作本身耗时 过长,必然会导致主线程的阻塞
排查:
检查最近fork操作耗时:执行 info status
获取到 latest_fork_usec 指标,若fork操作耗时超过1秒,避免使用过大的内存实例和规避fork缓慢的操作系统
(2)AOF刷盘堵塞
当我们开启AOF持久化功能时,文件刷盘的方式一般采用每秒一次,后 台线程每秒对AOF文件做fsync操作。当硬盘压力过大时,fsync操作需要等 待,直到写入完成。
排查:
如果主线程发现距离上一次的fsync成功超过2秒,为了 数据安全性它会阻塞直到后台线程执行fsync操作完成。这种阻塞行为主要 是硬盘压力引起
(3)HugePage写操作阻塞
三、外在原因
1.CPU竞争
2.内存交换
(1)排查方案:
- 查询Redis进程号:执行
redis-cli -p 6383 info server | grep process_id
命令 - 根据进程号查询内存交换信息:执行
cat /proc/process_id/smaps | grep Swap
如果交换量都是0KB或者个别的是4KB,则是正常现象,说明Redis进程内存没有被交换。
(2)预防内存交换的方法有:
保证机器充足的可用内存。
确保所有Redis实例设置最大可用内存(maxmemory),防止极端情况下Redis内存不可控的增长。
3.网络问题
排查:
(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)调整网络拓扑结构,同物理机>同机架>跨机架>同机房>同城机房>异地机房