首页 > 数据库 >Redis性能问题诊断以及scan命令耗时分析

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

时间:2023-04-10 14:11:06浏览次数:25  
标签:count scan 0.1 Redis redis 耗时 key root

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

标签:count,scan,0.1,Redis,redis,耗时,key,root
From: https://www.cnblogs.com/jinanxiaolaohu/p/17302734.html

相关文章

  • 三天吃透Redis八股文
    Redis连环40问,绝对够全!Redis是什么?Redis(RemoteDictionaryServer)是一个使用C语言编写的,高性能非关系型的键值对数据库。与传统数据库不同的是,Redis的数据是存在内存中的,所以读写速度非常快,被广泛应用于缓存方向。Redis可以将数据写入磁盘中,保证了数据的安全不丢失,而且Redis......
  • @Cacheable和@CachePut存入redis的数据使用redisTemplate取出时为null的解决
    当使用@Cacheable和@CachePut注解存数据到redis中时如果使用spring默认的rediskey序列化方式时,使用redisTemplate取数据为null@CacheConfig(cacheNames="users")存入redisusers目录下取数据时的key为users::usernamepublicinterfaceUserRepositoryextendsJpaRepos......
  • Redis随笔
    Redis简介Redis是一个开源的key-value存储系统。存储在内存中。相比于Memcached,value类型相对更多,string、list、set、zset、hash。Redis操作都是原子性的,单线程多路IO复用Redis支持各种不同方式的排序。 keys*查看当前库所有keyexistskey判断某个key是否存在typek......
  • MongoDB、Redis、HBase、Cassandra、Elasticsearch、ClickHouse等NoSQL数据库简介及优
    MongoDBMongoDB是一个基于文档的NoSQL数据库,它使用BSON(二进制JSON)格式存储数据。MongoDB支持动态查询,可以轻松地处理非结构化数据。它还支持水平扩展,可以在多个节点上分布数据。优点:灵活性高,支持非结构化数据存储。支持水平扩展,可以在多个节点上分布数据。支持动态查询,可......
  • Linux安装Redis
    1.下载下载地址:https://redis.io/download  本人选择的是5.0.14版本  上传服务器。本人上传至usr/local目录下。2.解压  将解压后的redis-5.0.14文件夹改名为redis3.编译cd到/usr/local/redis目录,输入命令make执行编译命令,接下来控制台会输出各种编译过程中输......
  • 爬虫最后一天,爬取到的数据存到mysql中,爬虫和下载中间件、加代理、cookie、header、se
    爬到的数据存到mysql中classFirstscrapyMySqlPipeline:defopen_spider(self,spider):print('我开了')self.conn=pymysql.connect(user='root',password="",host='127.0.0.1......
  • Redis之父萨尔瓦多·桑菲利波又名安蒂雷斯
    萨尔瓦多·桑菲利波又名安蒂雷斯个人博客连接嗨,我是萨尔瓦多·桑菲利波,也被称为安提雷斯,一位居住在卡塔尼亚的意大利计算机程序员。我于7年1977月2020日出生在坎波贝洛迪利卡塔。2022年,我停止编写代码,开始全职写小说。现在,从<>年底开始,我再次编码,交替写作和编码。萨尔瓦......
  • java中操作redis
             ......
  • redis常用命令
               ......
  • mysql与redis如何保证数据一致性
    1.先更新MySQL数据库,再删除缓存,再从数据库查询到的最新的数据同步到redis。采用最终一致性性策略。缺点:相较于mq的方式,这种方式由于要查数据库并将最新数据写到redis,可能会造成接口响应速度变慢。2.更新mysql数据库,再采用mq异步的方式,将数据同步到redis中。缺点:数据同步延时......