当前位置:首页 > 问答 > 正文

Redis读写速度忽上忽下,搞得人心慌意乱到底啥原因

朋友,你这问题可算问对人了,Redis读写速度像坐过山车,一会儿快如闪电,一会儿慢如蜗牛,这事儿搁谁身上都心慌,别急,咱们今天就掰开了揉碎了,用大白话聊聊这背后最常见的几个“捣蛋鬼”,这可不是我瞎说,很多都是踩过坑的老司机们(比如知乎上的技术分享、一些云服务商的故障排查文档)血与泪的总结。

Redis读写速度忽上忽下,搞得人心慌意乱到底啥原因

第一个大头,八成出在内存上。 Redis这伙计,数据全放在内存里,所以内存就是它的命根子,你想啊,内存就那么大,如果你不停地往里塞数据,眼看就要塞满了,Redis就得启动“清理门户”大法,这个清理过程,专业点叫“内存淘汰”,它会根据你设定的规则(比如删掉最近最少用的数据)来腾地方,这个清理动作本身是要消耗CPU和时间的,尤其是在数据量巨大的时候,就好像你在一个堆满杂物的房间里找东西,肯定比在空房间里慢得多,这时候,你的读写操作就可能被“卡”一下,速度自然就掉下来了,更狠的是,如果内存真的被你彻底塞满,一点不剩,Redis可能干脆就拒绝写入了,那速度直接降为零,可不是忽上忽下,而是直接“趴窝”了。

Redis读写速度忽上忽下,搞得人心慌意乱到底啥原因

第二个常见的“罪魁祸首”,是持久化操作。 Redis为了数据不丢,提供了两种把内存数据写到硬盘上的方式,相当于给它买个保险,一种是RDB,可以理解为在某个时间点给所有数据拍个快照;另一种是AOF,像是记流水账,把每一个写命令都记录下来,问题就出在“拍照”和“记账”的时候,当Redis决定要拍个快照(比如你设置了每分钟拍一次),它可能会fork出一个“子进程”来干这个活,fork这个过程,在数据量大的时候,本身就可能引起短暂的停顿,感觉就像车子换挡顿挫了一下,如果用的是AOF模式,并且设置了每次写操作都立刻同步到硬盘(最安全但最慢的模式),那么每次写入都像是在等硬盘“点头”,硬盘稍微忙一点,你的写速度就得等着,很多技术博客都提到,这是导致写入延迟波动的一个典型原因。

Redis读写速度忽上忽下,搞得人心慌意乱到底啥原因

第三个嫌疑犯,可能躲在你看不见的网络和操作系统里。 Redis性能极高,有时候瓶颈反而不在它自己,而在运输数据的“路”上,你的应用服务器和Redis服务器之间的网络连接不稳定,偶尔抽风,丢个包或者延迟突然增高,那你感觉到的就是Redis变慢了,再比如,你和Redis服务器不在同一个机房,物理距离远了,网络延迟本身就会高一些,波动也会更明显,还有操作系统,如果Redis服务器的CPU被其他“邻居”(比如同一台机器上运行的其他程序)抢走了很多,或者服务器本身内存不足,触发了系统的交换分区(把内存里不常用的数据挪到硬盘上),那Redis的性能肯定会受到牵连,表现就是时好时坏,这就像一条高速公路,Redis是跑车,但路上车多了,或者路面不平,跑车也飙不起来。

第四个可能性,是你自己的操作方式有问题。 Redis最喜欢简单快速的命令,比如set一个键,get一个值,但如果你冷不丁扔给它一个“大宝贝”,问题就来了,什么叫“大宝贝”?一个List或者Hash里面塞了几万几十万个元素,你一下子用个hgetall命令把整个Hash都取出来,这个操作会占用Redis主线程很长时间,因为它要组装所有数据并发送给你,在这段时间里,其他所有命令都得排队等着,整个Redis就跟“卡住”了一样,这种操作偶尔来一下,你就会明显感觉到速度“咚”地掉下去,等你这个“大宝贝”处理完,速度又“嗖”地恢复正常,很多开发者在论坛里分享案例时,最后发现就是某个不常调用的接口里藏了这么一个耗时命令。

别忘了还有“邻居”的干扰。 如果你的Redis是和其他服务共用一台服务器,那么当那个服务突然忙起来,大量消耗CPU、内存或者磁盘I/O时,Redis能分到的资源就少了,速度自然会下降,这就好比你在家看书,突然室友开始用吸尘器,你的阅读效率难免会受影响。

所以你看,导致Redis速度不稳的原因五花八门,从它自身的内存管理、数据持久化,到外部的网络状况、系统资源,再到你的使用习惯,都可能是“元凶”,排查起来,就像破案一样,得一步步来,下次再心慌的时候,不妨先看看监控,内存用了多少?有没有执行慢查询?CPU是不是突然高了?网络连接稳不稳定?把这些可能性一个个排除掉,大概率就能找到那个让Redis performance“跳舞”的真正原因了。