如何应对变慢的 Redis
基线性能:一个系统在低压力、无干扰下的基本性能,只由当前的软硬件配置决定。
./redis-cli --intrinsic-latency <测试时长>
该命令会打印 <测试时长> 秒内监测到的最大延迟。
运行时延迟的时长 2 倍于基准时长,则是 redis 变慢了。
如果想测试 Redis 客户端道网络端的影响,可以用 工具。iPerf
影响 Redis 性能的三大要素:Redis 自身的操作特性、文件系统和操作系统。
Redis 自身的操作特性
1.慢查询命令:
命令的慢操作和操作的复杂度相关。
操作度复杂度查询:https://redis.io/commands/
当你发现 Redis 性能变慢时,可以通过 Redis 日志,或者是 latency monitor 工具,查询变慢的请求,根据请求对应的具体命令以及官方文档,确认下是否采用了复杂度高的慢查询命令。
如果的确有大量的慢查询命令,有两种处理方式:用其他高效命令代替。
- 当需要返回一个 SET 中的所有成员时,不要使用 SMEMBERS 命令,而是要使用 SSCAN 多次迭代返回,避免一次返回大量数据,造成线程阻塞。
- 需要执行排序、交集、并集操作时,可以在客户端完成,而不要用 SORT、SUNION、SINTER 这些命令,以免拖慢 Redis 实例。
KEYS 命令需要遍历存储的键值对,所以操作延时高。KEYS 命令一般不被建议用于生产环境中。
2. 过期 key 操作
Redis 会自动删除过期 key,回收内存空间,本身会引起 Redis 变慢。
默认情况下,Redis 每 100 ms 会删除一些过期 key,算法如下:
- 采样固定个数的 key,并将其中过期的 key 全部删除;(固定个数:ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP,默认 20)
- 如果超过 25% 的 key 过期了,则重复删除的过程,直到过期 key 的比例降至 25% 以下。
第一条的算法,如果每秒钟删除 200 个过期 key,并不会对 Redis 造成太大影响。
如果触发了第二条算法,可以在 EXPIREAT 和 EXPIRE 命令的过期时间参数上,加上一个一定大小范围内的随机数,这样,既保证了 key 在一个邻近时间范围内被删除,又避免了同时过期造成的压力。