Redis性能问题诊断以及scan命令耗时分析

redis,性能,问题,诊断,以及,scan,命令,耗时,分析 · 浏览次数 : 484

小编点评

** scan 0 match zhaobsh* count 1000000** * **时间复杂度:O(n)** * **分析:** 对所有键值对进行一次遍历,并将结果存储在内存中。 * **速度:10.15秒** **总结:** scan 0 match zhaobsh* count 1000000 在扫描所有键值对的情况下,时间复杂度为 O(n),但由于服务器只有一个核心线程,因此实际性能可能低于理论值。 **其他建议:** * 可以使用不同的线程数量来优化性能。 * 可以使用不同的数据结构来存储结果。 * 如果可能,可以将 scan 0 改为使用内存中的数据结构进行操作。

正文

Redis性能问题诊断以及scan命令耗时分析


摘要

最近公司有项目反馈卡顿.
卡顿一小时后自己被拉入群聊. 
同事已经基本上定位到问题原因.
我这边想使用朴素的性能观点进行一下性能问题的拆解
为了提高自己. 

用到的一些脚本

echo "info" |redis-cli -p 6379 -a Yourpassword >`date +%Y%m%d%H%M`.txt
# 获取信息并且保存
echo "slowlog get 100 " |redis-cli -p 6379 -a Yourpassword >`date +%Y%m%d%H%M`.txt
# 获取较慢的命令
redis-cli -a password -p port --bigkeys >`date +%Y%m%d%H%M`_bigkeys.txt
redis-cli -a password -p port --hotkeys >`date +%Y%m%d%H%M`_hotkeys.txt
# 注意大key基本上可以查到
# hotkeys需要有memory_policy. 需要注意.

scan耗时统计与分析-先说结论

scan 命令 时间复杂度为 O(n)
理论上这个O(n) 很多的是靠 count来进行指定. 
并且理论上一个键值对的消耗时间为 1 微秒左右. 

虽然他可以在 count 值的微秒数之内返回, 但是如果要遍历所有的键值对, 并且多个client同时遍历
那么时间损耗是非常恐怖的. 

又因为redis是单线程io复用的模型. 所以他会导致其他的核心业务卡断. 

如果非必要建议不要使用scan命令, 在高并发,大量key的场景下性能表现并不好. 

scan耗时统计与分析-预制数据

scan 命令说明
scan 其实是对redis所有的键值对进行一次遍历
他的时时间复杂度是 O(n) 当然了他的时间复杂度可以通过 count 进行控制.
但是我们的场景是 多台服务器同事连接, 如果都进行 scan的话 对主线程的影响就比较恶劣了. 

所以计划做一个测试. 首先命令为:
scan 0 match zhaobsh* count 1000000
命令说明
scan 
第一个0 表示游标开始
第二个 match zhaobsh* 便于对符合此类的进行查询
第三个 count 1000000 表示一次性查询所少个key

因为我是测试环境, 键值对不多, 所以想着能够一次性多查询一下以便验证时间

测试数据创建
创建三个脚本,分别是10万,100万,1000万个键值对.
time for i in {1..100000} ; do  echo set key${i} value${i} >>/root/100000set.txt ; done
time for i in {1..1000000} ; do  echo set key${i} value${i} >>/root/1000000set.txt ; done
time for i in {1..10000000} ; do  echo set key${i} value${i} >>/root/10000000set.txt ; done
执行导入:
time cat /root/1000000set.txt |redis-cli -a xxxxx --pipe

注意之前总结过 -pipe 可以快速预祝数据. 
1000万预制数据大约耗时: 20秒

scan耗时统计与分析-统计方法

分别插入三次数据量的数据. 然后都执行这个命令
scan 0 match zhaobsh* count 1000000
然后通过
slowlog get 1 后去最慢的命令 . 的出结论为
不同keys量情况下的速度

scan耗时统计与分析-部分结论

keys值数量 slowlog耗时
10万 40毫秒
100万 440毫秒
1000万 1008毫秒

scan 算法分析

自己进行了一下验证, 如果直接一次scan 一千万的记录
耗时为: 10.15秒. 
理论上scan 一个键值对的时间为 1微秒左右.  

如果redis里面有 1000万个key的话  60台服务器如果同时进行一次所有的scan
那么搞不好至少会有在 运行期间内产生总计 600S 的延迟时间. 

测试结果

127.0.0.1:6379> scan 0 match zhaobsh* count  10000000
1) "14680063"
2) (empty array)
(10.15s)
127.0.0.1:6379> slowlog get 1
1) 1) (integer) 13
   2) (integer) 1681104753
   3) (integer) 10147528
   4) 1) "scan"
      2) "0"
      3) "match"
      4) "zhaobsh*"
      5) "count"
      6) "10000000"
   5) "127.0.0.1:27925"
   6) ""
127.0.0.1:6379> dbsize
(integer) 10000001
127.0.0.1:6379> 

redis-benchmark同步验证

测试命令:
./redis-benchmark -a xxxx  -r 10000 -n 100 -c 8000 scan 0 match zhaobsh* count  10000
10000个随机key, 测试100次, 使用 80000个client进行测试验证.
被测试的命令为: scan 0 match zhaobsh* count  10000

一万个key时count 一万时:
Summary:
  throughput summary: 99.11 requests per second
  latency summary (msec):
          avg       min       p50       p95       p99       max
      993.304    17.472  1004.543  1005.055  1005.055  1005.055

十万个key时 count 十万时
Summary:
  throughput summary: 11.54 requests per second
  latency summary (msec):
          avg       min       p50       p95       p99       max
     2970.660   135.680  3000.319  3000.319  3000.319  3000.319
五十万个key时 count 五十万时
Summary:
  throughput summary: 3.46 requests per second
  latency summary (msec):
          avg       min       p50       p95       p99       max
     2972.532   322.816  3000.319  3000.319  3000.319  3000.319

测试时CPU的情况

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND 
 72489 root      20   0 2148060   1.4g   1504 R 99.9  0.1  80:22.77 redis-server 
 72490 root      20   0 2148060   1.4g   1504 S  0.0  0.1   0:00.00 bio_close_file 
 72491 root      20   0 2148060   1.4g   1504 S  0.0  0.1   0:00.00 bio_aof_fsync  
 72492 root      20   0 2148060   1.4g   1504 S  0.0  0.1   0:00.00  bio_lazy_free 
 72493 root      20   0 2148060   1.4g   1504 S  0.0  0.1   1:00.51 jemalloc_bg_th

与Redis性能问题诊断以及scan命令耗时分析相似的内容:

Redis性能问题诊断以及scan命令耗时分析

Redis性能问题诊断以及scan命令耗时分析 摘要 最近公司有项目反馈卡顿. 卡顿一小时后自己被拉入群聊. 同事已经基本上定位到问题原因. 我这边想使用朴素的性能观点进行一下性能问题的拆解 为了提高自己. 用到的一些脚本 echo "info" |redis-cli -p 6379 -a Your

[转帖]Redis检索性能不足,改造rsbeat解决历史慢日志跟踪

https://www.sohu.com/a/313061840_411876 作者介绍 刘宇,甜橙金融创新中心基础技术架构师,拥有9年IT从业经验、9年数据库开发运维经验、4次大型营销活动经验。目前关注容器、分布式数据库技术等基础技术。 在线上排查redis性能问题时,从redis中找进行优化是一

Windows 和 linux 下面 Redis 性能比较

# Windows 和 linux 下面 Redis 性能比较 ## 问题来源 ``` 公司里面有一些环境还是使用Windows来跑 对应的. Redis和nginx 也是跑在Windows上面 但是微软官网自从 3.2.100 之后就再也没有编译过Windows版本的redis 网上能找到的基本上

[转帖]Day742.Redis阻塞主线程的问题 -Redis 核心技术与实战

Redis阻塞主线程的问题 Hi,我是阿昌,今天学习记录的内容是Redis阻塞主线程的问题。 Redis 之所以被广泛应用,很重要的一个原因就是它支持高性能访问。 也正因为这样,我们必须要重视所有可能影响 Redis 性能的因素(例如命令操作、系统配置、关键机制、硬件配置等),不仅要知道具体的机制,

【Azure Redis 缓存】Azure Redis 遇见的连接不上问题和数据丢失的情况解答

问题描述 PHP应用再连接Azure Redis服务时,出现Connection Timed out。当通过升级提高Azure Redis的性能时候,发现之前的数据丢失了。 问题解答 当Redis服务出现Timeout的情况时,可以从Redis服务的指标(Metrics)开始查看,如果出现负载(Se

太坑了吧!一次某某云上的redis读超时排查经历

一次排查某某云上的redis读超时经历 性能排查,服务监控方面的知识往往涉及量广且比较零散,如何较为系统化的分析和解决问题,建立其对性能排查,性能优化的思路,我将在这个系列里给出我的答案。 问题背景 最近一两天线上老是偶现的redis读超时报警,并且是业务低峰期间,甚是不解,于是开始着手排查。 以下

.NET性能优化-使用内存+磁盘混合缓存

我们回顾一下上一篇文章中的内容,有一个朋友问我这样一个问题: > 我的业务依赖一些数据,因为数据库访问慢,我把它放在Redis里面,不过还是太慢了,有什么其它的方案吗? 其实这个问题比较简单的是吧?Redis其实属于网络存储,我对照下面的这个表格,可以很容易的得出结论,既然网络存储的速度慢,那我们就

缓存面试解析:穿透、击穿、雪崩,一致性、分布式锁、Redis过期,海量数据查找

本文提供了一些保证数据一致性和设计分布式锁的策略。这些策略可以在实际应用中帮助开发人员解决相关的问题,确保系统的数据一致性和并发访问的正确性。同时,通过合理地使用缓存和分布式锁,可以提高系统的性能和可靠性。希望对你在面对Redis相关面试题时有所帮助!

[转帖]Redis性能调优万字总结,面试必问!

https://zhuanlan.zhihu.com/p/541745804 于哥你好,最近面试挺多的,尤其是在问到java面试题,Redis被问的特别多,比如 Redis的内存模型? Redis的底层数据结构是怎么的? Redis的多线程模型 Redis的集群原理 Redis的雪崩,击穿,穿透怎么

一次系统延迟性优化案例

一次系统延迟性优化案例 服务监控系列文章 服务监控系列视频 延迟的本质 本质是cpu没有及时的运行程序代码。 进程内部 网络io,磁盘io,cpu调度 达到瓶颈 第三方系统 调用的第三方系统慢,mysql,redis等基础组件调度慢, 第三方应用系统调用慢 问题背景 线上隔三差五晚上10点左右总会有