如果在使用 Redis 时,发现访问延迟增大,该如何进行排查?首先,建议你去查看一下 Redis 的慢日志。Redis 提供了慢日志命令的统计功能,我们通过以下设置,就可以查看有哪些命令在执行时延迟比较大。
首先设置 Redis 的慢日志阈值,只有超过阈值的命令才会被记录,这里的单位是微妙,例如设置慢日志的阈值为 5 毫秒,同时设置只保留最近 1000 条慢日志记录:
# 命令执行超过5毫秒记录慢日志
CONFIG SET slowlog-log-slower-than 5000
# 只保留最近1000条慢日志
CONFIG SET slowlog-max-len 1000
设置完成之后,所有执行的命令如果延迟大于 5 毫秒,都会被 Redis 记录下来,我们执行 SLOWLOG get 5 查询最近5条慢日志:
127.0.0.1:6379> SLOWLOG get 5
1)
1) (integer) 32693 # 慢日志ID
2) (integer) 1593763337 # 执行时间
3) (integer) 5299 # 执行耗时(微妙)
4)
1) "LRANGE" # 具体执行的命令和参数
2) "user_list_2000"
3) "0"
4) "-1"
2)
1) (integer) 32692
2) (integer) 1593763337
3) (integer) 5044
4)
1) "GET"
2) "book_price_1000"
通过查看慢日志记录,我们就可以知道在什么时间执行哪些命令比较耗时,如果你的业务经常使用 O(N) 以上复杂度的命令,例如 sort、sunion、zunionstore,或者在执行 O(N) 命令时操作的数据量比较大,这些情况下 Redis 处理数据时就会很耗时。
如果你的服务请求量并不大,但 Redis 实例的 CPU 使用率很高,很有可能是使用了复杂度高的命令导致的。
解决方案就是,不使用这些复杂度较高的命令,并且一次不要获取太多的数据,每次尽量操作少量的数据,让 Redis 可以及时处理返回。
存储bigkey
如果查询慢日志发现,并不是复杂度较高的命令导致的,例如都是 SET、 DELETE 操作出现在慢日志记录中,那么你就要怀疑是否存在 Redis 写入了 bigkey 的情况。
Redis 在写入数据时,需要为新的数据分配内存,当从 Redis 中删除数据时,它会释放对应的内存空间。如果一个 key 写入的数据非常大,Redis 在分配内存时也会比较耗时。同样的,当删除这个 key 的数据时,释放内存也会耗时比较久。
你需要检查你的业务代码,是否存在写入 bigkey 的情况,需要评估写入数据量的大小,业务层应该避免一个 key 存入过大的数据量。那么有没有什么办法可以扫描现在 Redis 中是否存在 bigkey 的数据吗?Redis 也提供了扫描 bigkey 的方法:
redis-cli -h $host -p $port --bigkeys -i 0.01
使用上面的命令就可以扫描出整个实例 key 大小的分布情况,它是以类型维度来展示的。
需要注意的是