关系经济人类预测化学自然
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产

Redis有哪些慢操作?

3月15日 孤小单投稿
  Redis是否变慢了?
  从业务服务器到Redis服务器这条调用链路中变慢的原因可能有2个业务服务器到Redis服务器之间出现了网络问题,例如网络丢包,延迟比较严重Redis本身的执行出现问题,此时我们就需要排查Redis的问题
  但是大多数情况下都是Redis服务的问题。但是应该如何衡量Redis变慢了呢?命令执行时间大于1s,大于2s?这其实并没有一个固定的标准。
  例如在一个配置较高的服务器中,0。5毫秒就认为Redis变慢了,在一个配置较低的服务器中,3毫秒才认为Redis变慢了。所以我们要针对自己的机器做基准测试,看平常情况下Redis处理命令的时间是多长?
  我们可以使用如下命令来监测和统计测试期间的最大延迟(以微秒为单位)redisclilatencyhhostpport
  比如执行如下命令〔rootVM014centossrc〕。redisclih127。0。0。1p6379intrinsiclatency60Maxlatencysofar:1microseconds。Maxlatencysofar:12microseconds。Maxlatencysofar:55microseconds。Maxlatencysofar:124microseconds。Maxlatencysofar:133microseconds。Maxlatencysofar:142microseconds。Maxlatencysofar:982microseconds。Maxlatencysofar:1049microseconds。Maxlatencysofar:2366microseconds。Maxlatencysofar:3725microseconds。52881684totalruns(avglatency:1。1346microseconds1134。61nanosecondsperrun)。Worstruntook3283xlongerthantheaveragelatency。
  参数中的60是测试执行的秒数,可以看到最大延迟为3725微秒(3毫秒左右),如果命令的执行远超3毫秒,此时Redis就有可能很慢了!
  那么Redis有哪些慢操作呢?Redis有哪些慢操作?
  Redis的各种命令是在一个线程中依次执行的,如果一个命令在Redis中执行的时间过长,就会影响整体的性能,因为后面的请求要等到前面的请求被处理完才能被处理,这些耗时的操作有如下几个部分
  Redis可以通过日志记录那些耗时长的命令,使用如下配置即可命令执行耗时超过5毫秒,记录慢ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志aCONFIGSETslowloglogslowerthan5000只保留最近500条慢ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志aCONFIGSETslowlogmaxlen500
  执行如下命令,就可以查询到最近记录的慢日志127。0。0。1:6379SLOWLOGget51)1)(integer)32693慢ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志aID2)(integer)1593763337执行时间戳3)(integer)5299执行耗时(微秒)4)1)LRANGE具体执行的命令和参数2)userlist:20003)04)12)1)(integer)326922)(integer)15937633373)(integer)50444)1)GET2)userinfo: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的字典结构如下setbookN
  我们可以用keys命令来查询Redis中特定的key,如下所示查询所有的keykeys查询以book为前缀的keykeysbook
  keys命令的复杂度是O(n),它会遍历这个dict中的所有key,如果Redis中存的key非常多,所有读写Redis的指令都会被延迟等待,所以千万不用在生产环境用这个命令(如果你已经准备离职的话,祝你玩的开心)。
  既然不让你用keys,肯定有替代品,那就是scan
  scan是通过游标逐步遍历的,因此不会长时间阻塞Redis
  用用zscan遍历zset,hscan遍历hash,sscan遍历set的原理和scan命令类似,因为hash,set,zset的底层实现的数据结构中都有dict。操作bigkey
  如果一个key对应的value非常大,那么这个key就被称为bigkey。写入bigkey在分配内存时需要消耗更长的时间。同样,删除bigkey释放内存也需要消耗更长的时间
  如果在慢日志中发现了SETDEL这种复杂度不高的命令,此时你就应该排查一下是否是由于写入bigkey导致的。
  如何定位bigkey?
  Redis提供了扫描bigkey的命令redisclih127。0。0。1p6379bigkeysi0。01。。。summarySampled829675keysinthekeyspace!Totalkeylengthinbytesis10059825(avglen12。13)Biggeststringfoundkey:291880has10bytesBiggestlistfoundmylist:004has40itemsBiggestsetfoundmyset:2386has38membersBiggesthashfoundmyhash:3574has37fieldsBiggestzsetfoundmyzset:2704has42members36313stringswith363130bytes(04。38ofkeys,avgsize10。00)787393listswith896540items(94。90ofkeys,avgsize1。14)1994setswith40052members(00。24ofkeys,avgsize20。09)1990hashswith39632fields(00。24ofkeys,avgsize19。92)1985zsetswith39750members(00。24ofkeys,avgsize20。03)
  可以看到命令的输入有如下3个部分内存中key的数量,已经占用的总内存,每个key占用的平均内存每种类型占用的最大内存,已经key的名字每种数据类型的占比,以及平均大小
  这个命令的原理就是redis在内部执行了scan命令,遍历实例中所有的key,然后正对key的类型,分别执行strlen,llen,hlen,scard,zcard命令,来获取string类型的长度,容器类型(list,hash,set,zset)的元素个数
  使用这个命令需要注意如下两个问题对线上实例进行bigkey扫描时,为避免ops(operationpersecond每秒操作次数)突增,可以通过i增加一个休眠参数,上面的含义为,每隔100条scan指令就会休眠0。01s对于容器类型(list,hash,set,zset),扫描出的是元素最多的key,但一个key的元素数量多,不一定代表占用的内存多
  如何解决bigkey带来的性能问题?尽量避免写入bigkey如果使用的是redis4。0以上版本,可以用unlink命令代替del,此命令可以把释放key内存的操作,放到后台线程中去执行如果使用的是redis6。0以上版本,可以开启lazyfree机制(lazyfreelazyuserdelyes),执行del命令的时候,也会放到后台线程中去执行大量key集中过期
  我们可以给Redis中的key设置过期时间,那么当key过期了,它在什么时候会被删除呢?
  如果让我们写Redis过期策略,我们会想到如下三种方案定时删除,在设置键的过期时间的同时,创建一个定时器。当键的过期时间来临时,立即执行对键的删除操作惰性删除,每次获取键的时候,判断键是否过期,如果过期的话,就删除该键,如果没有过期,则返回该键定期删除,每隔一段时间,对键进行一次检查,删除里面的过期键定时删除策略对CPU不友好,当过期键比较多的时候,Redis线程用来删除过期键,会影响正常请求的响应
  定时删除策略对CPU不友好,当过期键比较多的时候,Redis线程用来删除过期键,会影响正常请求的响应
  惰性删除读CPU是比较有好的,但是会浪费大量的内存。如果一个key设置过期时间放到内存中,但是没有被访问到,那么它会一直存在内存中
  定期删除策略则对CPU和内存都比较友好
  redis过期key的删除策略选择了如下两种惰性删除定期删除
  惰性删除客户端在访问key的时候,对key的过期时间进行校验,如果过期了就立即删除
  定期删除Redis会将设置了过期时间的key放在一个独立的字典中,定时遍历这个字典来删除过期的key,遍历策略如下每秒进行10次过期扫描,每次从过期字典中随机选出20个key删除20个key中已经过期的key如果过期key的比例超过14,则进行步骤一每次扫描时间的上限默认不超过25ms,避免线程卡死
  因为Redis中过期的key是由主线程删除的,为了不阻塞用户的请求,所以删除过期key的时候是少量多次。源码可以参考expire。c中的activeExpireCycle方法
  为了避免主线程一直在删除key,我们可以采用如下两种方案给同时过期的key增加一个随机数,打散过期时间,降低清除key的压力如果你使用的是redis4。0版本以上的redis,可以开启lazyfree机制(lazyfreelazyexpireyes),当删除过期key时,把释放内存的操作放到后台线程中执行内存达到上限,触发淘汰策略
  Redis是一个内存数据库,当Redis使用的内存超过物理内存的限制后,内存数据会和磁盘产生频繁的交换,交换会导致Redis性能急剧下降。所以在生产环境中我们通过配置参数maxmemoey来限制使用的内存大小。
  当实际使用的内存超过maxmemoey后,Redis提供了如下几种可选策略。
  Redis的淘汰策略也是在主线程中执行的。但内存超过Redis上限后,每次写入都需要淘汰一些key,导致请求时间变长
  可以通过如下几个方式进行改善增加内存或者将数据放到多个实例中淘汰策略改为随机淘汰,一般来说随机淘汰比lru快很多避免存储bigkey,降低释放内存的耗时写AOF日志的方式为always
  Redis的持久化机制有RDB快照和AOF日志,每次写命令之后后,Redis提供了如下三种刷盘机制
  当aof的刷盘机制为always,redis每处理一次写命令,都会把写命令刷到磁盘中才返回,整个过程是在Redis主线程中进行的,势必会拖慢redis的性能
  当aof的刷盘机制为everysec,redis写完内存后就返回,刷盘操作是放到后台线程中去执行的,后台线程每隔1秒把内存中的数据刷到磁盘中
  当aof的刷盘机制为no,宕机后可能会造成部分数据丢失,一般不采用。
  一般情况下,aof刷盘机制配置为everysec即可fork耗时过长
  在持久化一节中,我们已经提到Redis生成rdb文件和aof日志重写,都是通过主线程fork子进程的方式,让子进程来执行的,主线程的内存越大,阻塞时间越长。
  可以通过如下方式优化控制Redis实例的内存大小,尽量控制到10g以内,因为内存越大,阻塞时间越长配置合理的持久化策略,如在slave节点生成rdb快照使用swap分区
  当机器的内存不够时,操作系统会将部分内存的数据置换到磁盘上,这块磁盘区域就是Swap分区,当应用程序再次访问这些数据的时候,就需要从磁盘上读取,导致性能严重下降
  当Redis性能急剧下降时就有可能是数据被换到Swap分区,我们该如何排查Redis数据是否被换到Swap分区呢?先找到redisserver的进程idpsefgrepredisserver查看redisswap的使用情况catprocpidsmapsegrep(SwapSize)〔rootVM014centos〕catproc2370smapsegrep(SwapSize)Size:1568kBSwap:0kBSize:8kBSwap:0kBSize:24kBSwap:0kBSize:2200kBSwap:0kB
  每一行Size表示Redis所用的一块内存大小,Size下面的Swap表示这块大小的内存,有多少已经被换到磁盘上了,如果这2个值相等,说明这块内存的数据都已经被换到磁盘上了
  我们可以通过如下方式来解决增加机器内存整理内存碎片
  最后我们总结一下Redis的慢操作
投诉 评论 转载

2023年春晚主持人任鲁豫从地方台出身,为何能站到央视C位呢2023年央视春晚主持人已经公布,包括撒贝宁在内的6位主持阵容,将相约在除夕晚上迎接兔年的到来。这一次名单中有任鲁豫,撒贝宁,尼格买提,龙洋,马凡舒以及王嘉宁。可以说这一……抢滩智能门锁的内卷之争眼下,随着物联网、人工智能等新兴技术的发展,智能化开始上升为国家发展战略,也成为推动经济社会高质量发展和人民生活水平提升的重要动力。在此背景之下,智能家居场景也不断得到丰……成也靠嘴败也靠嘴,从火遍全国到无人问津,大兵究竟做了什么?说起相声演员,除了我们如今熟知的郭德纲、岳云鹏等人外,上世纪七八十年代的人们最熟悉的当属相声演员大兵,当年他与奇志的奇志大兵组合可谓是家喻户晓的存在,大兵的名……亚洲杯第6日赛程黎巴嫩静候中国,伊日榜首大战,新西兰争第二男篮亚洲杯进入第6比赛日,A组和B组的前三名已经诞生,今天的4场比赛将决定C组和D组的小组排位。黎巴嫩战胜新西兰排第一最早开始的一场比赛是黎巴嫩男篮PK印度男篮(1……线下怀旧零食店为啥都傍着景点开?喔喔奶糖、牛羊配、冰梅棒、大大泡泡糖、跳跳糖、咪咪虾条、陈皮丹这些早已淡出视线,曾是70后、80后儿时味道的食品,如今伴随着怀旧风潮再度成为了网红。北京青年报记者了解到,北京销……2023年春节换新,我有这些生活家电推荐荣事达家用冰柜160A228D最近很多地方快递、外卖运力不足,如果家里有个冰柜就方便很多。家里需要冰柜的朋友,可以看看荣事达的这款冰柜了,长81。5cm、宽52。2cm、……开学了,不管你多忙,也要常给孩子吃此鱼,聪明健康,记忆好开学了,不管你多忙,也要常给孩子吃这鱼,聪明健康,记忆好。此鱼叫黑鳕鱼,俗称,深海鱼中的奶油,刺少肉多,味道鲜美,制作也非常简单,每个家长都会做。只需要把鱼肉放入锅煎熟、或者烤……米尔传说2韩版传奇开荒记飞天城堡我边走边打怪,一路往北不知过了多久,我终于看到了亮光了,走近一看,原来是两名弓箭护卫。站在护城河的石桥上,想当年人兽大战时,如果不是护城河的阻拦,人类会牺牲更多的勇……骁龙888与骁龙870该怎么选?小米11给出答案,关键看外围不少朋友选备用机时犯了难,不知道哪款机型更适合自己,例如骁龙888与骁龙870机型价格相当,口碑与外围规格却成反比,应该怎么选呢?骁龙888与骁龙870都在2021年大量……去西藏,哪条线路最美最安全,你们知道吗?去西藏到底走哪一条线路最美最安全?首先难度最低最舒服的就是我们常说的川藏线,也就是从成都出发,全程2000公里,你预算八到十天的玩是最舒服的。川藏线有什么特点呢?第一,这条路从……Redis有哪些慢操作?Redis是否变慢了?从业务服务器到Redis服务器这条调用链路中变慢的原因可能有2个业务服务器到Redis服务器之间出现了网络问题,例如网络丢包,延迟比较严重Redis……总投资超20亿元!全球特种化学品公司科莱恩深耕大亚湾在大亚湾石化区里,各类项目开工建设,建设者卯足干劲,争分夺秒抢工期。在科莱恩化工(惠州)有限公司(下称科莱恩惠州),科莱恩高性能无卤阻燃剂新材料项目(一期)正在进行设备安装、调……
结婚为难新郎的游戏胤祺也很有实力为何不参与夺嫡充耳不闻造句用充耳不闻造句大全表现出来造句用表现出来造句大全防晒指数是什么意思防晒指数怎么看多少合适表弟来了浅谈课余体育锻炼对技校学生健康的促进作用增加用户的个绝密技巧妇产造句用妇产造句大全36氪首发短视频一站式创作交易平台神马工场完成1000万元P轻度砷中毒该如何治疗过敏性鼻炎久治不愈?不过是肺气虚了!中医一方扫净,经验请体会
妈妈如何预防新生儿窒息国有企业职工思想政治工作常见问题及对策神舟疯了?一场发布会竟然有这么多款电脑郭守敬主持修订了授时历与现在所使用的日历基本一致安徽实现乡镇区域5G网络全覆盖参观赌王儿子何猷君的家,坐在大钢琴上弹吉他,吃饭也要自己下厨老人如何预防老花眼老人吃什么对眼睛好配方揭秘!椰蓉大面包的做法,软蓬蓬,热乎乎,一出炉就忍不住了人民科学家叶培建为国担责再立新功关于儿童烫伤的处理预防您知道多少?本周热点丨微信可直接购买淘宝商品,海伦斯门店突破800家导师问答总是压抑自己怎么办

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找菏泽德阳山西湖州宝鸡上海茂名内江三亚信阳长春北海西安安徽黄石烟台沧州湛江肇庆鹤壁六安韶关成都钦州