redis阻塞问题
发现阻塞
生产环境需要异常监控,在连接函数捕获异常,打印ip和port,使用监控系统监控多个关键指标,如命令耗时、慢查询、持久化阻塞、拒绝连接、CPU内存网络磁盘使用过载等。
内在原因
redis数据结构使用不合理
- 通过slow log 获取慢查询,改成低复杂度算法或将大对象拆分(如一个大集合按某个维度拆分成多个小集合)
- 通过--bigkeys(内部对历史扫描过的大对象分段scan)获取大对象的key
CPU饱和
- 通过--stat统计内存、处理命令数等(当60000+/s的请求命令垂直难以优化,需要集群化水平扩展分摊OPS压力)
- 只有几百或几千OPS的cpu饱和不正常,可能有高复杂的命令;通过info commandstats统计命令开销,分析不正常的开销,(如hset耗时135us,由于配置追求低内存导致了操作更慢和更消耗cpu)
持久化阻塞
- fork
发生RDB和AOF重写时,如果fork操作耗时超过1s,需要避免使用过大的内存实例和规避某些操作系统。 - AOF刷盘阻塞
当硬盘压力大时,AOF的fsync操作会阻塞。 - HugePage写操作阻塞
开启Transparent HugePages的linux写操作会延长执行时间。
外在原因
cpu竞争
不和其他多核cpu密集型服务部署在一起、将redis进程绑定到cpu上(fork子进程会争用cpu,开启了持久化或参与复制的主节点不绑定cpu)
内存交换
- 查询redis进程号
- 根据进程号查询内存交换信息
防止swap导致硬盘读写速度慢
网络问题
- 连接拒绝
网络闪断、超过maxclients连接数(当分布式节点大量访问且生命周期较短的场景下设置tcp-keepalive和timeout参数主动检查并关闭连接)、连接溢出(操作系统限制文件数、端口tcp连接backlog数量溢出) - 网络延迟
- 网卡软中断
网卡队列只能用一个cpu