Redis性能篇(三)Redis关键系统配置:如何应对Redis变慢

Redis被普遍使用的一个很重要的缘由是它的高性能。所以咱们必要要重视全部可能影响Redis性能的因素、机制以及应对方案。影响Redis性能的五大方面的潜在因素,分别是:html

在前面的2讲中,学习了会致使Redis变慢的潜在阻塞点以及相应的解决方案,即异步线程机制和CPU绑核。除此以外,还有一些因素会致使Redis变慢。redis

这一讲,介绍如何系统性应对Redis变慢这个问题。从问题认定、系统性排查和应对方案这3个方面来说解。服务器

判断Redis是否变慢?

最直接的方法,查看Redis的响应延迟。经过绝对值来判断,好比执行时间忽然增加到几秒。网络

可是这个方法在不一样配置的机器上的偏差比较大。第二个方法是基于当前环境下的Redis基线性能作判断。架构

基线性能指一个系统在低压力、无干扰下的基本性能。app

怎么肯定基线性能?从2.8.7版本开始,redis-cli命令提供了-intrinsic-latency选项,能够用来监测和统计测试期间内的最大延迟,这个延迟能够做为Redis的基线性能。其中,测试时长能够用-intrinsic-latency选项的参数来指定。异步

通常来讲,运行时延和基线性能对比,若是运行时延是基线性能的2倍及以上时,就能够认定Redis变慢了。为了不网络对基线性能的影响,直接在服务器端运行。工具

如何应对Redis变慢?

影响Redis的关键因素有三个:Redis自身的操做特性、文件系统和操做系统。性能

Redis自身操做特性的影响

Redis有两个操做会对性能形成较大影响,分别是慢查询命令和过时key操做。学习

慢查询命令

慢查询命令,就是指在Redis中执行速度慢的命令,这会致使Redis延迟增长。

排查:经过Redis日志、或者是latency monitor工具。

解决方法

  • 用其余高效命令代替。好比不要使用SMEMBERS命令,而是用SSCAN屡次迭代返回;
  • 当须要执行排序、交集、并集操做时,能够在客户端完成,而不要用SORT、SUNION、SINTER这些命令

还有一个比较容易遗漏的慢查询命令是KEYS命令,它用于返回和输入模式的全部key。由于KEYS命令须要遍历存储的键值对,因此操做延时高。KEYS命令通常不被建议用于生产环境中

过时key操做

过时key的自动删除机制,它是Redis用来回收内存空间的经常使用机制,自己会引发Redis操做阻塞,致使性能变慢。

排查:检查业务代码在使用EXPIREAT命令设置key过时时间时,是否使用了相同的UNIX时间戳。由于这会形成大量key在同一时间过时,致使性能变慢。

解决方法

  • 根据实际业务需求来决定EXPIREAT和EXPIRE的过时时间参数。
  • 若是一批key的确是同时过时,能够在EXPIREAT和EXPIRE的过时时间参数上,加上一个必定大小范围内的随机参数

文件系统的影响

在基础篇讲过,为了保证数据可靠性,Redis会采用AOF日志或者RDB快照。其中,AOF日志提供了三种日志写回策略:no、everysec、always。这三种写回策略依赖文件系统的两个系统调用完成:write和fsync。

  • write只要把日志记录写到内核缓冲区便可;
  • fsync须要把日志记录写回磁盘,时间较长。

image

排查

  • 首先,检查Redis配置文件中的appendfsync配置项;
  • 其次,确认业务对数据可靠性的要求是否须要每一秒或每个操做都记日志。

解决方法

若是业务应用对延迟很是敏感,但同时容许必定量的数据丢失,把配置项no-appendfsync-on-rewrite设置为yes:

no-appendfsync-on-rewrite yes

若是的确须要高性能,同时也须要高可靠数据保证,考虑采用高速的固态硬盘做为AOF日志的写入设备。

操做系统的影响

swap

一个潜在的瓶颈:操做系统的内存swap。

内存swap是操做系统里将内存数据在内存和磁盘间来回换入和换出的机制,涉及到磁盘的读写。

Redis一旦swap被触发,Redis的请求操做须要等到磁盘数据读写完成。而且swap触发后影响的是Redis主IO线程,这会极大地增长Redis的响应时间。

一般触发swap的缘由主要是物理机器内存不足

排查

首先,查找Redis的进程号:

$ redis-cli info | grep process_id process_id: 5332

其次,进入Redis所在机器的/proc目录下的该进程目录中:

$ cd /proc/5332

最后,运行下面命令,查看Redis进程的使用状况:

$cat smaps | egrep '^(Swap|Size)'
Size: 584 kB
Swap: 0 kB
Size: 4 kB
Swap: 4 kB
Size: 4 kB
Swap: 0 kB
Size: 462044 kB
Swap: 462008 kB
Size: 21392 kB
Swap: 0 kB

解决方法:增长机器的内存或者使用Redis集群。

内存大页

还有一个和内存相关的因素,即内存大页机制(Transparent Huge Page,THP),也会影响Redis性能。

排查

首先,在Redis实例运行的机器上执行:

cat /sys/kernel/mm/transparent_hugepage/enabled

若是,执行结果是always,表示内存大页机制启动了;若是是never,表示禁止了。

解决方法:关闭内存大页。

echo never /sys/kernel/mm/transparent_hugepage/enabled

总结

总结一份关于Redis变慢的Checklist:

  1. 获取Redis实例在当前环境下的基线性能。
  2. 是否用了慢查询命令?若是是的话,就使用其余命令替代慢查询命令,或者把聚合计算命令放在客户端作。
  3. 是否对过时key设置了相同的过时时间?对于批量删除的key,能够在每一个key的过时时间上加一个随机数,避免同时删除。
  4. 是否存在bigkey? 对于bigkey的删除操做,若是你的Redis是4.0及以上的版本,能够直接利用异步线程机制减小主线程阻塞;若是是Redis 4.0之前的版本,可使用SCAN命令迭代删除;对于bigkey的集合查询和聚合操做,可使用SCAN命令在客户端完成。
  5. Redis AOF配置级别是什么?业务层面是否的确须要这一可靠性级别?若是咱们须要高性能,同时也容许数据丢失,能够将配置项no-appendfsync-on-rewrite设置为yes,避免AOF重写和fsync竞争磁盘IO资源,致使Redis延迟增长。固然, 若是既须要高性能又须要高可靠性,最好使用高速固态盘做为AOF日志的写入盘。
  6. Redis实例的内存使用是否过大?发生swap了吗?若是是的话,就增长机器内存,或者是使用Redis集群,分摊单机Redis的键值对数量和内存压力。同时,要避免出现Redis和其余内存需求大的应用共享机器的状况。
  7. 在Redis实例的运行环境中,是否启用了透明大页机制?若是是的话,直接关闭内存大页机制就好了。
  8. 是否运行了Redis主从集群?若是是的话,把主库实例的数据量大小控制在2~4GB,以避免主从复制时,从库因加载大的RDB文件而阻塞。
  9. 是否使用了多核CPU或NUMA架构的机器运行Redis实例?使用多核CPU时,能够给Redis实例绑定物理核;使用NUMA架构时,注意把Redis实例和网络中断处理程序运行在同一个CPU Socket上。

参考资料

相关文章
相关标签/搜索