导读
Redis 大部分应用场景是纯缓存服务,请求后端有Primary Storage的组件,如:MySQL,HBase。一旦 Redis 请求延迟增加,轻则影响服务性能,严重可能就会导致业务系统“雪崩”。
单台 Redis 的并发连接数最大可设置为1W,MySQL连接数通常不超过1k,试想,如果 Redis 性能出现问题,导致大量的流量没了 Redis 的缓存响应,直接打到了 MySQL,大概率会导致数据库宕机了,最终导致一系列服务的雪崩,这是非常严重的事故。
可以发现,一旦 Redis 延迟过高,会引发各种问题。
正文
一、如何定位
性能优化的前提是,我们需要定位到何时何地需要优化何种 Redis,对吧?那么,如何定义 Redis 慢了呢?
最大延迟是客户端发出命令到客户端收到命令的响应的时间,以其最为衡量依据,正常情况下 Redis 处理的时间极短,在微秒级别。当 Redis 出现性能波动的时候,比如:达到几秒到十几秒,这个很明显我们可以认定 Redis 性能变慢了。
当然,由于硬件配置的不同,Redis 性能差异也会很大。有的硬件配置比较高,当延迟 0.6ms,我们可能就认定变慢了;硬件比较差的可能 3 ms 我们才认为出现问题。
所以,需要对当前环境的 Redis 基线性能做测量,也就是在一个系统在低压力、无干扰情况下的基本性能。当你发现 Redis 运行时时的延迟是基线性能的 2 倍以上,就可以判定 Redis 性能变慢了。
下面提供几种测量方法,以供参考:
1.1 延迟基线测量
redis-cli 命令提供了–intrinsic-latency
选项,用来监测和统计测试期间内的最大延迟(以毫秒为单位),这个延迟可以作为 Redis 的基线性能。
redis-cli --latency -h `host` -p `port`
比如执行如下指令:
redis-cli --intrinsic-latency 100
Max latency so far: 4 microseconds.
Max latency so far: 18 microseconds.
Max latency so far: 41 microseconds.
Max latency so far: 57 microseconds.
Max latency so far: 78 microseconds.
Max latency so far: 170 microseconds.
Max latency so far: 342 microseconds.
Max latency so far: 3079 microseconds.
45026981 total runs (avg latency: 2.2209 microseconds / 2220.89 nanoseconds per run).
Worst run took 1386x longer than the average latency.
注意:参数
100
是测试将执行的秒数。我们运行测试的时间越长,我们就越有可能发现延迟峰值。通常运行 100 秒通常是合适的,足以发现延迟问题了,当然我们可以选择不同时间运行几次,避免误差。
运行的最大延迟是 3079 微秒,所以基线性能是 3079 (3 毫秒)微秒。
需要注意的是,我们要在 Redis 的服务端运行,而不是客户端。这样,可以避免网络对基线性能的影响。
可以通过 “-h host -p port
” 来连接服务端,如果想监测网络对 Redis 的性能影响,可以使用 Iperf 测量客户端到服务端的网络延迟。 如果网络延迟几百毫秒,说明网络可能有其他大流量的程序在运行导致网络拥塞,需要找运维协调网络的流量分配。
1.2 慢指令监控
- 如何判断是否是慢指令呢?
看操作复杂度是否是
O(N)
。官方文档对每个命令的复杂度都有介绍,尽可能使用O(1) 和 O(log N)
命令。涉及到集合操作的复杂度一般为
O(N)
,比如:集合全量查询HGETALL、SMEMBERS
,以及集合的聚合操作:SORT、LREM、 SUNION等,这些都需要格外留意。
- 有监控数据可以观测