Redis阅读笔记 阻塞
在基础讲完之后,本篇主要是谈论阻塞问题的发现以及解决方案
阻塞发现
当阻塞发生的时候, 线上服务应该会最早意识到。 (服务和redis对接的地方要加入监控)
值得一提的是,当使用Redis集群的时候,日志里记录出问题的Redis的IP和port是很重要的, 可以帮助我们快速定位到出问题的Redis节点。
内在原因
具体到节点异常之后,首先应该排查自身问题:
- API使用不合理
- CPU饱和
- 持久化相关阻塞
API使用不合理
发生这种情况的原因是,针对大量元素的数据结构使用了O(n)的操作,比如hgetall
可以使用Redis的慢查询功能追踪,由于慢查询只统计运行时间(不统计网络I/O等等),所以一般超过1ms的语句都要关注。
解决方案:
- 使用时间复杂度低的语句
- 调整大对象,类似关系数据库拆表,横拆或者纵拆都是解决方案
命令
redis-cli-h{ip}-p{port}bigkeys
可以查询到大对象
CPU饱和
由于Redis是单进程,运行的时候只使用一个CPU,如果该CPU被Redis占满,那就意味着Redis节点不能处理更多访问了。
top查看CPU使用率
使用
redis-cli-h{ip}-p{port}stat
获取访问,查看connect参数,这里可能有好几种情况
-
OPS > 一万, 那可能就是访问太多了,只能集群化降低负载
-
OPS在几百几千,但是CPU占用还是满的
-
高复杂度算法
-
内存压缩,重点查看hash,如果hset和hget耗时很长,说明redis为了压缩内存使用ziplist存了太多元素。 需要给redis分配更多内存
-
持久化阻塞
-
fork
发生原因: 持久化中fork操作时间过长。 可以使用
info stats查看。 主要原因就是redis占用内存太大,fork一旦触发写时复制,时间就会很长
-
AOF刷盘阻塞
AOF的every sec策略每秒刷一次盘。 如果磁盘压力过大,fsync就要等待,而如果redis发现上一次fsync超过两秒,就会阻塞。
可以从日志里发现
-
HugePage复制阻塞
Linux对于大内存可能使用2MB而非4KB的大page,复制的时候更花时间。
外在阻塞
CPU竞争
当Redis和其他CPU密集型应用部署在一起的时候可能会发生
-
绑定CPU
Redis是单线程,理论上可以绑定CPU,实际上当开启持久化的时候,持久化fork出来的子进程会和父进程抢夺CPU,造成抖动从而大幅度影响效率。集群中的主节点也因为要复制而有这个问题。
内存交换 swap
如果os把redis交换出去,对redis的效率会造成极大影响。
可以查询进程号,通过进程号查看swap情况
网络问题
- 网络闪断
- redis达到最大连接,因而拒绝连接
连接溢出
-
OS限制,因为OS有打开的最大文件限制,而TCP处理的时候又是按照文件句柄处理,所以会有redis还可以连接,但是OS认为redis打开太多文件的情况。
-
网络延迟