Redis是单线程架构,在高并发的场景下,如果出现阻塞,会有严重后果,以下就是对阻塞问题的分析排查和解决

 

内在原因

API 或 数据结构 使用不合理

排查:

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

解决:

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

CPU饱和

排查

  1. 查看CPU使用率:执行 top 命令
  2. 查询Redis并发量:执行 redis-cli -h {ip} -p {port} --stat 命令

解决:

  1. 集群化水平拓展分摊OPS压力
  2. 检查是否有过度的内存优化

持久化阻塞

排查

  1. 检查最近fork操作耗时:执行 info status 获取到 latest_fork_usec 指标
  2. 检查AOF刷盘最近成功时间:查看日志

解决:

  1. 若fork操作耗时超过1秒,避免使用过大的内存实例和规避fork缓慢的操作系统
  2. 若AOF刷盘fsync成功操作超过2秒,降低其他进程对硬盘的压力

 
 

外在原因

CPU竞争

排查:执行 topsar 命令

解决:

  • 不建议和其他多核CPU密集型服务部署在一起,会影响Redis吞吐量
  • 把Redis进程绑定到CPU上,可降低CPU上下文切换开销
  • 开启了持久化或参与复制的主节点不建议绑定CPU,因为子进程会占用90%竞争

内存交换

排查:

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

解决:

  1. 保证机器充足的可用内存
  2. 确保所有Redis实例设置最大可用内存,防止Redis不可控增长
  3. 降低系统使用swap优先级

网络问题

排查:

  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. 调整网络拓扑结构,同物理机>同机架>跨机架>同机房>同城机房>异地机房