ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Redis变慢原因排查

2021-08-10 11:33:39  阅读:261  来源: 互联网

标签:samples 变慢 max Redis 排查 key -- 过期 avg


1、查看redis慢日志

----------------------1、使用复杂度过高的命令-----------------------------------
# 查看基准性能
# 60 秒内的最大响应延迟
docker exec -it redis redis-cli  --intrinsic-latency 60
Max latency so far: 1 microseconds.
Max latency so far: 7 microseconds.
Max latency so far: 8 microseconds.
Max latency so far: 5806 microseconds.
Max latency so far: 200755 microseconds.
Max latency so far: 209539 microseconds.
Max latency so far: 220647 microseconds.
Max latency so far: 340514 microseconds.
Max latency so far: 385149 microseconds.
这 60 秒内的最大响应延迟为 385149 微秒(385毫秒)。
# 查看一段时间内 Redis 的最小、最大、平均访问延迟:
docker exec -it redis redis-cli --latency-history -i 1
min: 0, max: 1, avg: 0.18 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.16 (97 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.16 (97 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.15 (97 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.12 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.18 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.19 (97 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.16 (97 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.21 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.18 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.15 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.20 (97 samples) -- 1.00 seconds range
min: 0, max: 1, avg: 0.17 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.15 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.15 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.13 (98 samples) -- 1.01 seconds range
min: 0, max: 1, avg: 0.18 (98 samples) -- 1.01 seconds range
每间隔 1 秒,采样 Redis 的平均操作耗时,其结果分布在 0.15 ~ 0.25 毫秒之间。

如果你观察到,这个实例的运行延迟是正常 Redis 基准性能的 2 倍以上,即可认为这个 Redis 实例确实变慢了

# 命令执行耗时超过 5 毫秒,记录慢日志
CONFIG SET slowlog-log-slower-than 5000

# 只保留最近 500 条慢日志
CONFIG SET slowlog-max-len 500

slowlog get 【分页数】 # 获取全部的慢指令
slowlog get 5

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"
     
#######################################
# 变慢原因
## 命令方面
# 1、使用时间复杂度过高的指令
# 2、返回数据过多

--------------------------1、操作bigkey-------------------------
# 查看bigkey指令
docker exec -it redis redis-cli --bigkeys -i 0.01
Sampled 829675 keys in the keyspace!
Total key length in bytes is 10059825 (avg len 12.13)

Biggest string found 'key:291880' has 10 bytes
Biggest   list found 'mylist:004' has 40 items
Biggest    set found 'myset:2386' has 38 members
Biggest   hash found 'myhash:3574' has 37 fields
Biggest   zset found 'myzset:2704' has 42 members

36313 strings with 363130 bytes (04.38% of keys, avg size 10.00)
787393 lists with 896540 items (94.90% of keys, avg size 1.14)
1994 sets with 40052 members (00.24% of keys, avg size 20.09)
1990 hashs with 39632 fields (00.24% of keys, avg size 19.92)
1985 zsets with 39750 members (00.24% of keys, avg size 20.03)

------------------------3、集中过期----------------------
Redis 的过期数据采用被动过期 + 主动过期两种策略:

1. 被动过期:只有当访问某个 key 时,才判断这个 key 是否已过期,如果已过期,则从实例中删除

2. 主动过期:Redis 内部维护了一个定时任务,默认每隔 100 毫秒(1秒10次)就会从全局的过期哈希表中随机取出 20 个 key,然后删除其中过期的 key,如果过期 key 的比例超过了 25%,则继续重复此过程,直到过期 key 的比例下降到 25% 以下,或者这次任务的执行耗时超过了 25 毫秒,才会退出循环.

   **这个主动过期 key 的定时任务,是在 Redis 主线程中执行的**

   如果在执行主动过期的过程中,出现了需要大量删除过期 key 的情况,那么此时应用程序在访问 Redis 时,必须要等待这个过期任务执行结束,Redis 才可以服务这个客户端请求。

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

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

allkeys-lru:不管 key 是否设置了过期,淘汰最近最少访问的 key
volatile-lru:只淘汰最近最少访问、并设置了过期时间的 key
allkeys-random:不管 key 是否设置了过期,随机淘汰 key
volatile-random:只随机淘汰设置了过期时间的 key
allkeys-ttl:不管 key 是否设置了过期,淘汰即将过期的 key
noeviction:不淘汰任何 key,实例内存达到 maxmeory 后,再写入新数据直接返回错误
allkeys-lfu:不管 key 是否设置了过期,淘汰访问频率最低的 key(4.0+版本支持)
volatile-lfu:只淘汰访问频率最低、并设置了过期时间 key(4.0+版本支持)

  • 使用复杂度过高的命令
    • 尽量不使用 O(N) 以上复杂度过高的命令,对于数据的聚合操作,放在客户端做
    • 执行 O(N) 命令,保证 N 尽量的小(推荐 N <= 300),每次获取尽量少的数据,让 Redis 可以及时处理返回
  • 操作bigkey
    • 业务应用尽量避免写入 bigkey
    • Redis 是 4.0 以上版本,用 UNLINK 命令替代 DEL,此命令可以把释放 key 内存的操作,放到后台线程中去执行
    • Redis 是 6.0 以上版本,可以开启 lazy-free 机制(lazyfree-lazy-user-del = yes),在执行 DEL 命令时,释放内存也会放到后台线程中执行
  • 集中过期
    • 集中过期 key 增加一个随机过期时间,把集中过期的时间打散,降低 Redis 清理过期 key 的压力
    • 可以开启 lazy-free 机制,当删除过期 key 时,把释放内存的操作放到后台线程中执行,避免阻塞主线程
  • 实例内存达到上限
    • 避免存储 bigkey,降低释放内存的耗时
    • 淘汰策略改为随机淘汰,随机淘汰比 LRU 要快很多(视业务情况调整)
    • 拆分实例,把淘汰 key 的压力分摊到多个实例上
    • 如果使用的是 Redis 4.0 以上版本,开启 layz-free 机制,把淘汰 key 释放内存的操作放到后台线程中执行(配置 lazyfree-lazy-eviction = yes)
  • fork耗时严重
  • 开启内存大页
  • 开启AOF
  • 绑定CPU
  • 使用Swap
  • 碎片整理
  • 网络带宽过载
  • 其他原因

标签:samples,变慢,max,Redis,排查,key,--,过期,avg
来源: https://www.cnblogs.com/mainwoods/p/15122888.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有