0%

redis性能调优

[toc]

Q: 你怎么确认你的redis变慢了或者有问题呢?#

A:
用”相同规格“(CPU、内存)的其他redis(基准性能机器)做对比
用–latency-history 命令获取最近一段时间内各命令的响应延迟
如果比基准时间大了2倍以上,那就是变慢了。


Q: 使用什么样的redis命令可能导致性能下降?#

A:
O(N) 以上复杂度的命令,例如 SORT、SUNION、ZUNIONSTORE 等需要大量数据做聚合的命令
*注意, 对于数据的聚合操作,放在客户端做


Q: 频繁写入或者删除一个很大的字符串有什么问题?#

A:
如果一个 key 写入的 value 非常大,那么 Redis 在分配内存时就会比较耗时。
同样的,当删除这个 key 时(过期、淘汰),释放内存也会比较耗时,这种类型的 key 我们一般称之为 bigkey。
还有备份机制中,如果有bigkey,也会导致备份过程的写时复制很慢,导致性能下降。

  • 除了后台释放的方案外, 尽可能不要写bigkey!

Q: 如何找到redis中是否有这种bigkey?#

A:
”–bigkeys -i 频率”命令 可以获取各种类型的key大小分布情况
本质上就是调用了scan,拿到所有key后统计大小和个数。


Q: 有一个和scan类似的命令叫keys命令, 有什么区别?#

A:

  • redis的单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复
  • scan指令可以无阻塞的提取出指定模式的key列表,用的是额外线程。


Q: redis 4.0 lazy-free机制有了解么?#

A:
执行下面的命令,开启lazy-expire模式
#释放过期 key 的内存,放到后台线程执行
lazyfree-lazy-expire yes
涉及删除、过期造成的主线程延迟问题,都可改成lazy-free,在另外的线程中去释放。


Q: 大量key集中过期也会导致某一时刻性能大量下降,除了加随机过期时间外,还能如何避免?#

A:
通过运维手段处理

  • 在 Redis 上执行 INFO 命令就可以拿到这个实例所有的运行状态数据。
  • 重点关注 expired_keys 这一项,它代表整个实例到目前为止,累计删除过期 key 的数量。
  • 当这个指标在很短时间内出现了突增,需要及时报警出来,并进行这类key超时时间的调整和处理

Q: 如何我的redis内存配置的小了,会如何对性能造成影响?#

A:

  • Redis 内存达到 maxmemory 后,每次写入新的数据之前,Redis 必须先从实例中踢出一部分数据,让整个实例的内存维持在 maxmemory 之下,然后才能把新数据写进来。

    这个过程就是数据淘汰过程。 如果过小,频繁淘汰删除,肯定会影响性能。

  • 机器内存太小,导致频繁做系统的swap磁盘-内存页交换。


Q:Redis 实例内存越大越好吗?太大的话可能有什么问题?#

A:

  • 当 Redis 开启了后台 RDB 和 AOF rewrite 后,在执行时,它们都需要主进程fork出一个子进程进行数据的持久化
  • 这个 fork 过程会消耗大量的 CPU 资源,在完成 fork 之前,整个 Redis 实例会被阻塞住,无法处理任何客户端请求。
  • 执行 fork 的耗时与redis实例大小有关,实例越大,耗时越久。

注意,fork和部署类型也有关,如果部署在虚拟机上,fork所用的时间会更久。


Q: linux的内存大页有了解么? 开启后对redis的性能是提升还是下降?#

A:

  • Linux 内核从 2.6.38 开始,支持了内存大页机制,该机制允许应用程序以 2MB 大小为单位,向操作系统申请内存。
  • 这会导致申请内存的时间变大。
  • 当进行AOF或者RDB备份时,会进行写时复制,如果申请页过大,会导致及时只改20B的数据,也会用2MB单位申请,减慢主线程的请求响应速度。

建议关闭redis部署机器上的内存大页。


Q: AOF需要主线程做同步写, 我配置成 appendfsync everysec (写内存,每秒写磁盘), 是不是就不会阻塞主线程,造成性能下降了?为什么?#

A:
rewrite重写过慢
或者其他应用占用磁盘IO,导致写增量AOF文件过慢
这会导致主线吃还没同步写完,就收到了新的写请求,这时候新的写请求就会阻塞。


Q: 如何解决AOF的写磁盘阻塞问题?#

A:
如果是rewrite, 可以调整配置,让rewrite的时候不要做appendfsync写磁盘。

1
2
3
# AOF rewrite 期间,AOF 后台子线程不进行刷盘操作
# 相当于在这期间,临时把 appendfsync 设置为了 none
no-appendfsync-on-rewrite yes

提升磁盘性能,更换为SSD固态硬盘。


Q: redis大量的内存碎片也会导致性能下降,如何优化redis的碎片?#

A:
redis具有开启碎片整理的功能。
相关配置参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 开启自动内存碎片整理(总开关)
activedefrag yes

# 内存使用 100MB 以下,不进行碎片整理
active-defrag-ignore-bytes 100mb

# 内存碎片率超过 10%,开始碎片整理
active-defrag-threshold-lower 10
# 内存碎片率超过 100%,尽最大努力碎片整理
active-defrag-threshold-upper 100

# 内存碎片整理占用 CPU 资源最小百分比
active-defrag-cycle-min 1
# 内存碎片整理占用 CPU 资源最大百分比
active-defrag-cycle-max 25

# 碎片整理期间,对于 List/Set/Hash/ZSet 类型元素一次 Scan 的数量
active-defrag-max-scan-fields 1000