Redis有哪些慢操作?


Redis有哪些慢操作?

文章插图
 
redis是否变慢了?【Redis有哪些慢操作?】从业务服务器到Redis服务器这条调用链路中变慢的原因可能有2个
  1. 业务服务器到Redis服务器之间出现了网络问题,例如网络丢包,延迟比较严重
  2. Redis本身的执行出现问题,此时我们就需要排查Redis的问题
但是大多数情况下都是Redis服务的问题 。但是应该如何衡量Redis变慢了呢?命令执行时间大于1s,大于2s?这其实并没有一个固定的标准 。
例如在一个配置较高的服务器中,0.5毫秒就认为Redis变慢了,在一个配置较低的服务器中,3毫秒才认为Redis变慢了 。所以我们要针对自己的机器做基准测试,看平常情况下Redis处理命令的时间是多长?
我们可以使用如下命令来监测和统计测试期间的最大延迟(以微秒为单位)
redis-cli --latency -h `host` -p `port`比如执行如下命令
[root@VM-0-14-centos src]# ./redis-cli -h 127.0.0.1 -p 6379 --intrinsic-latency 60Max latency so far: 1 microseconds.Max latency so far: 12 microseconds.Max latency so far: 55 microseconds.Max latency so far: 124 microseconds.Max latency so far: 133 microseconds.Max latency so far: 142 microseconds.Max latency so far: 982 microseconds.Max latency so far: 1049 microseconds.Max latency so far: 2366 microseconds.Max latency so far: 3725 microseconds.52881684 total runs (avg latency: 1.1346 microseconds / 1134.61 nanoseconds per run).Worst run took 3283x longer than the average latency.参数中的60是测试执行的秒数,可以看到最大延迟为3725微秒(3毫秒左右),如果命令的执行远超3毫秒,此时Redis就有可能很慢了!
那么Redis有哪些慢操作呢?
Redis有哪些慢操作?
Redis有哪些慢操作?

文章插图
 
Redis的各种命令是在一个线程中依次执行的,如果一个命令在Redis中执行的时间过长,就会影响整体的性能,因为后面的请求要等到前面的请求被处理完才能被处理,这些耗时的操作有如下几个部分
Redis可以通过日志记录那些耗时长的命令,使用如下配置即可
# 命令执行耗时超过 5 毫秒,记录慢日志CONFIG SET slowlog-log-slower-than 5000# 只保留最近 500 条慢日志CONFIG SET slowlog-max-len 500执行如下命令,就可以查询到最近记录的慢日志
127.0.0.1:6379> SLOWLOG get 51) 1) (integer) 32693# 慢日志ID2) (integer) 1593763337# 执行时间戳3) (integer) 5299# 执行耗时(微秒)4) 1) "LRANGE"# 具体执行的命令和参数2) "user_list:2000"3) "0"4) "-1"2) 1) (integer) 326922) (integer) 15937633373) (integer) 50444) 1) "GET"2) "user_info:1000"...使用复杂度过高的命令之前的文章我们已经介绍了Redis的底层数据结构,它们的时间复杂度如下表所示
名称 时间复杂度 dict(字典) O(1) ziplist (压缩列表) O(n) zskiplist (跳表) O(logN) quicklist(快速列表) O(n) intset(整数集合) O(n)
「单元素操作」:对集合中的元素进行增删改查操作和底层数据结构相关,如对字典进行增删改查时间复杂度为O(1),对跳表进行增删查时间复杂为O(logN)
「范围操作」:对集合进行遍历操作,比如Hash类型的HGETALL,Set类型的SMEMBERS,List类型的LRANGE,ZSet类型的ZRANGE,时间复杂度为O(n),避免使用,用SCAN系列命令代替 。(hash用hscan,set用sscan,zset用zscan)
「聚合操作」:这类操作的时间复杂度通常大于O(n),比如SORT、SUNION、ZUNIONSTORE
「统计操作」:当想获取集合中的元素个数时,如LLEN或者SCARD,时间复杂度为O(1),因为它们的底层数据结构如quicklist,dict,intset保存了元素的个数
「边界操作」:list底层是用quicklist实现的,quicklist保存了链表的头尾节点,因此对链表的头尾节点进行操作,时间复杂度为O(1),如LPOP、RPOP、LPUSH、RPUSH
「当想获取Redis中的key时,避免使用keys *」 ,Redis中保存的键值对是保存在一个字典中的(和JAVA中的HashMap类似,也是通过数组+链表的方式实现的),key的类型都是string,value的类型可以是string,set,list等
例如当我们执行如下命令后,redis的字典结构如下
set bookName redis;rpush fruits banana Apple;
Redis有哪些慢操作?

文章插图
 
我们可以用keys命令来查询Redis中特定的key,如下所示


推荐阅读