服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Redis - 浅谈Redis常见延迟问题定位与分析

浅谈Redis常见延迟问题定位与分析

2022-10-21 16:24知知之之 Redis

大部分时候,redis延迟很低,但是在某些时刻,有些redis实例会出现很高的响应延时,本文主要介绍了浅谈Redis常见延迟问题定位与分析,具有一定的参考价值,感兴趣的可以了解一下

使用复杂度高的命令

如果在使用Redis时,发现访问延迟突然增大,如何进行排查?

首先,第一步,建议你去查看一下Redis的慢日志。Redis提供了慢日志命令的统计功能,我们通过以下设置,就可以查看有哪些命令在执行时延迟比较大。

首先设置Redis的慢日志阈值,只有超过阈值的命令才会被记录,这里的单位是微妙,例如设置慢日志的阈值为5毫秒,同时设置只保留最近1000条慢日志记录:

?
1
2
3
4
# 命令执行超过5毫秒记录慢日志
CONFIG SET slowlog-log-slower-than 5000
# 只保留最近1000条慢日志
CONFIG SET slowlog-max-len 1000

设置完成之后,所有执行的命令如果延迟大于5毫秒,都会被Redis记录下来,我们执行SLOWLOG get 5查询最近5条慢日志:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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、keys、scan,或者在执行O(N)命令时操作的数据量比较大,这些情况下Redis处理数据时就会很耗时。

如果你的服务请求量并不大,但Redis实例的CPU使用率很高,很有可能是使用了复杂度高的命令导致的。

解决方案就是,不使用这些复杂度较高的命令,并且一次不要获取太多的数据,每次尽量操作少量的数据,让Redis可以及时处理返回。

存储bigkey

如果查询慢日志发现,并不是复杂度较高的命令导致的,例如都是SET、DELETE操作出现在慢日志记录中,那么你就要怀疑是否存在Redis写入了bigkey的情况。

Redis在写入数据时,需要为新的数据分配内存,当从Redis中删除数据时,它会释放对应的内存空间。

如果一个key写入的数据非常大,Redis在分配内存时也会比较耗时。同样的,当删除这个key的数据时,释放内存也会耗时比较久。

你需要检查你的业务代码,是否存在写入bigkey的情况,需要评估写入数据量的大小,业务层应该避免一个key存入过大的数据量。

针对bigkey的问题,Redis官方在4.0版本推出了lazy-free的机制,用于异步释放bigkey的内存,降低对Redis性能的影响。即使这样,我们也不建议使用bigkey,bigkey在集群的迁移过程中,也会影响到迁移的性能,这个后面在介绍集群相关的文章时,会再详细介绍到。

集中过期

有时你会发现,平时在使用Redis时没有延时比较大的情况,但在某个时间点突然出现一波延时,而且报慢的时间点很有规律,例如某个整点,或者间隔多久就会发生一次。

如果出现这种情况,就需要考虑是否存在大量key集中过期的情况。

如果有大量的key在某个固定时间点集中过期,在这个时间点访问Redis时,就有可能导致延迟增加。

Redis的过期策略采用定期删除+惰性删除两种策略;

注意,Redis的定期删除的定时任务,也是在Redis主线程中执行的,也就是说如果在执行主动过期的过程中,出现了需要大量删除过期key的情况,那么在业务访问时,必须等这个过期任务执行结束,才可以处理业务请求。此时就会出现,业务访问延时增大的问题,最大延迟为25毫秒。

而且这个访问延迟的情况,不会记录在慢日志里。慢日志中只记录真正执行某个命令的耗时,Redis主动过期策略执行在操作命令之前,如果操作命令耗时达不到慢日志阈值,它是不会计算在慢日志统计中的,但我们的业务却感到了延迟增大。

解决方案是,在集中过期时增加一个随机时间,把这些需要过期的key的时间打散即可。

实例内存达到上限

有时我们把Redis当做纯缓存使用,就会给实例设置一个内存上限maxmemory,然后开启LRU淘汰策略。

当实例的内存达到了maxmemory后,你会发现之后的每次写入新的数据,有可能变慢了。

导致变慢的原因是,当Redis内存达到maxmemory后,每次写入新的数据之前,必须先踢出一部分数据,让内存维持在maxmemory之下。

这个踢出旧数据的逻辑也是需要消耗时间的,而具体耗时的长短,要取决于配置的淘汰策略

fork耗时严重

如果你的Redis开启了自动生成RDB和AOF重写功能,那么有可能在后台生成RDB和AOF重写时导致Redis的访问延迟增大,而等这些任务执行完毕后,延迟情况消失。

遇到这种情况,一般就是执行生成RDB和AOF重写任务导致的。

生成RDB和AOF都需要父进程fork出一个子进程进行数据的持久化,在fork执行过程中,父进程需要拷贝内存页表给子进程,如果整个实例内存占用很大,那么需要拷贝的内存页表会比较耗时,此过程会消耗大量的CPU资源,在完成fork之前,整个实例会被阻塞住,无法处理任何请求,如果此时CPU资源紧张,那么fork的时间会更长,甚至达到秒级。这会严重影响Redis的性能。

绑定CPU

很多时候,我们在部署服务时,为了提高性能,降低程序在使用多个CPU时上下文切换的性能损耗,一般会采用进程绑定CPU的操作。

但在使用Redis时,我们不建议这么干,原因如下。

绑定CPU的Redis,在进行数据持久化时,fork出的子进程,子进程会继承父进程的CPU使用偏好,而此时子进程会消耗大量的CPU资源进行数据持久化,子进程会与主进程发生CPU争抢,这也会导致主进程的CPU资源不足访问延迟增大。

所以在部署Redis进程时,如果需要开启RDB和AOF重写机制,一定不能进行CPU绑定操作

使用Swap

如果你发现Redis突然变得非常慢,每次访问的耗时都达到了几百毫秒甚至秒级,那此时就检查Redis是否使用到了Swap,这种情况下Redis基本上已经无法提供高性能的服务。

我们知道,操作系统提供了Swap机制,目的是为了当内存不足时,可以把一部分内存中的数据换到磁盘上,以达到对内存使用的缓冲。

但当内存中的数据被换到磁盘上后,访问这些数据就需要从磁盘中读取,这个速度要比内存慢太多!

尤其是针对Redis这种高性能的内存数据库来说,如果Redis中的内存被换到磁盘上,对于Redis这种性能极其敏感的数据库,这个操作时间是无法接受的。可以临时关闭操作系统Swap

网卡负载过高

特点就是从某个时间点之后就开始变慢,并且一直持续。这时你需要检查一下机器的网卡流量,是否存在网卡流量被跑满的情况。

网卡负载过高,在网络层和TCP层就会出现数据发送延迟、数据丢包等情况。Redis的高性能除了内存之外,就在于网络IO,请求量突增会导致网卡负载变高。

如果出现这种情况,你需要排查这个机器上的哪个Redis实例的流量过大占满了网络带宽,然后确认流量突增是否属于业务正常情况,如果属于那就需要及时扩容或迁移实例,避免这个机器的其他实例受到影响。

到此这篇关于浅谈Redis常见延迟问题定位与分析的文章就介绍到这了,更多相关Redis 延迟问题内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_35973945/article/details/124198769

延伸 · 阅读

精彩推荐
  • Redis详解Redis用链表实现消息队列

    详解Redis用链表实现消息队列

    Redis有两种方式实现消息队列,一种是用Redis自带的链表数据结构,另一种是用Redis发布/订阅模式实现,这篇文章先介绍链表实现消息队列,有需要的朋友们...

    daisy3322019-10-30
  • Redis关于redis Key淘汰策略的实现方法

    关于redis Key淘汰策略的实现方法

    下面小编就为大家带来一篇关于redis Key淘汰策略的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 ...

    jingxian3152019-11-05
  • Redisredis事务常用操作详解

    redis事务常用操作详解

    在本篇文章里小编给大家分享了关于redis事务常用操作的相关知识点内容,有兴趣的朋友们可以跟着学习参考下。 ...

    夏夜的雨不停下3802019-11-26
  • RedisRedis Cluster集群主从切换的踩坑与填坑

    Redis Cluster集群主从切换的踩坑与填坑

    这篇文章主要介绍了Redis Cluster集群主从切换的踩坑与填坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    weixin_3433545812342021-07-31
  • RedisRedisson 主从一致性问题详解

    Redisson 主从一致性问题详解

    这篇文章主要为大家介绍了Redisson 主从一致性问题详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    ruochen3682022-08-26
  • Redisredis配置文件中常用配置详解

    redis配置文件中常用配置详解

    这篇文章主要介绍了redis配置文件中常用配置详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下...

    一路向北6112021-08-01
  • Redisphpredis提高消息队列的实时性方法(推荐)

    phpredis提高消息队列的实时性方法(推荐)

    下面小编就为大家带来一篇phpredis提高消息队列的实时性方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    jingxian3462019-11-01
  • Redis使用lua+redis解决发多张券的并发问题

    使用lua+redis解决发多张券的并发问题

    这篇文章主要介绍了使用lua+redis解决发多张券的并发问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考...

    gistmap7652021-02-26