阿里云Redis实例慢查剖析

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis常见超时原因分析

Redis凭借着丰富的数据类型和高并发处理能力已经成为目前最受欢迎的内存数据库,很多用户对Redis的印象就是高并发,高吞吐,低时延,殊不知Redis的性能也很“脆弱”,使用不当很容易出现性能问题。

Redis原理

Redis是一个单进程单线程的模型,网络收发包、协议处理以及命令处理都是在一个线程中完成。对每一个用户连接来说,主线程会读一批数据放到QueryBuffer中,然后尝试协议解析,每解析出一个完整的Request,就先处理,然后把Reply放到OutputBuffer中等待发出,然后再尝试解析QueryBuffer中剩下的数据,直到QueryBuffer中没有数据或者没有一个完整的Request后,处理下一个连接。
image

Redis常见慢查问题

阿里云Redis正常情况下可以达到8~10W的QPS,这意味着平均一条命令处理时间基本在微妙级。Redis的快是建立在所有操作逻辑都很快速的基础上的,实际情况并非一直这么美好。

大包

如果一个Request几十MB甚至几百MB,网络IO、协议解析都必然花更长的时间。而在TCP网络层,一个Redis Request也会分成很多个packet进行传输,任何一个包发生了超时重传,意味着这整个请求的响应时间都会变慢。

O(N)命令

Redis有不少O(N)类命令,这些操作的响应时间是和数据有关的。比如说keys命令,需要遍历内存中所有key,这期间主线程不能处理任何请求。还有hgetall这类命令,耗时取决于哈希中有多少条field+value。

流控

网络流量一旦超过规格限制会触发流控,Redis会延迟接收和处理命令,对客户端来说就会发现响应变慢了。

持久化

Redis的持久化机制不管是AOF还是RDB,都会fork一个子进程。fork系统调用本身会随着Redis内存增大而消耗更长的时间。

pipeline

部分客户端使用异步模式或者批处理模式发送命令,与之相对应的是ping-pong模式。事实上Redis并不区分ping-pong还是pipeline,不管是什么模式,在多个客户端并发访问的情况下,Request/Response无非处于这几种状态:

  1. 客户端所在机器内核socket buffer中等待TCP发送
  2. 网络传输中
  3. Redis所在机器内核socket buffer中
  4. Redis的QueryBuffer中等待协议解析和处理(pipeline)
  5. 命令处理中
  6. Redis的output buffer中
  7. 内核socket buffer中 or 网络传输中
  8. 客户端所在机器内核socket buffer中 or 等待客户端处理
    一般业务测统计的Redis响应时间是从 1 -> 8 消耗的时间,Redis测统计的响应时间只包含了 4 -> 6。

由于Redis单线程的模型,一旦有一个命令慢了,意味着后面所有命令都会变慢,以1W QPS为例,有一个hgetall命令处理消耗了100ms,从客户端的角度来说,此时在在内核socket buffer以及以及读到用户态QueryBuffer中的命令都会变慢,不仅仅是这一个命令慢了,影响的可能是1000条命令。

客户端统计问题

上面提到了pipeline模式,如果客户端使用批量发送,需要特别注意客户端统计响应时间的方式。一般来说,客户端会在发送之前开始计时,在收到Response后停止计时。事实上,在批处理模式下,这种计时是很不准确的,仔细思考一下就明白,批量发送,最后一个Request的响应时间中绝大部分都是在等待前面请求处理。

命令 说明
keys, flushadb, flushall O(N),遍历所有Key
mget, mset, del, unlink, exists O(M),带的key不宜过多
smembers O(N),返回集合中所有member,避免集合过大(大key问题)
sinter, sinterstore O(N*M),避免集合过大(大key问题)
sunion sunionstore, sdiff, sdiffstore O(N),避免集合过大(大key问题)
zunionstore, zinterstore O(NK)+O(Mlog(M)),避免有序集合过大(大key问题)
hgetall, hkeys O(N),避免哈希过大(大key问题)
lrange, ltrim, lindex, linsert O(S+N),避免列表太大(大key问题)

Redis集群

阿里云Redis集群加了一层Proxy做转发,可以带来比较好的兼容性和扩展性。
Redis Proxy是集群的访问入口,挡住用户短连接。Redis Proxy和后端Redis之间使用长连接,可以最优的发挥Redis性能。
image

兼容性

Redis Proxy可以把多key命令拆分后转发到各个Redis节点上。比如说mget key1 key2 key3,key1和key3在Redis1上,key2在Redis2上,Redis Proxy会拆分成mget key1 key3和mget key2两个命令分别转发到Redis1和Redis2上。
Redis Proxy同时支持select命令。

扩展性

Redis Proxy承担了三次握手建连接、认证的过程,同时Redis Proxy可以做到无状态,方便扩展。

Redis集群常见慢查问题

排队

Redis Proxy内核为每个user connection维护了一个Session,Session中有一个队列,按照FIFO顺序记录了所有已经收到但还没有给客户端返回的Request。
所有Request按照Key映射到各个Redis分片上,类似上图所展示的,不同Redis分片上的Request并发处理,就有快有慢,而Response必须按照FIFO的顺序给客户端返回。假如Request1比Request2慢,这也就意味着在Session中Request1必须等待Request2处理完以后一起给客户端返回。如果Request1是一个耗时100ms的hgetall命令,那么Request2也会在Session中排队等待,客户端观察到的响应时间最少也是100ms。和上面Redis类似,一个慢会影响到其他大量的Request跟着慢。
image

多key命令

上面提到过,多key命令会拆分转发到多个Redis节点,拆分的所有子命令都返回聚合以后给客户端回复,这意味着任何一个子命令波动(Redis节点有慢查,网络抖动),这个请求的命令就会变慢,这个请求变慢意味着会有其他请求在排队,都会变慢。
mget k1 k2 k3被拆分分别转发到两个Redis节点上,mget k1 k3很快处理完,mget k2因为网络抖动,或者前面有一个hgetall正在执行,100ms以后才返回,这意味着Request2, 3也都必须等待mget k2。
多key命令因为会涉及多个节点,所以更容易受到影响。
image

Redis Proxy的slowlog

上面提到Redis的Slowlog只包含了命令的实际CPU处理时间,并没有包含网络IO, 协议编解码的时间。在集群模式下,Redis Proxy的slowlog从收到并解析出用户的Request开始计算,直到给用户返回Response截止,包含了与后端Redis的网络传输,Redis的协议处理,命令处理等所有环节。

Max RT & Avg RT

阿里云Redis Proxy上会统计Avg RT和Max RT(RT就是上面提到的从收到Request到给客户端回复Reponse的时间),Avg RT就是统计周期内所有Request的sum(RT) / Request数量,Max RT则是统计周期内RT最大的那个Request。
可以看到有很多原因可能导致Redis出现慢查,如果Max RT经常飙高可以根据控制台上的各项监控排查一下是否有上面提到的问题。如果只是偶发的Max RT毛刺,在排除本身有O(N)命令导致的情况下,可以结合QPS看下发生频率,假如一个Redis集群有100W QPS,一个小时出现一次Max RT的毛刺,算下来平均10亿个请求才会出现一个,基本上在网络抖动允许范围内。

慢查定位

控制台上查看Redis服务监控,包括流量、QPS、CPU、Avg Rt、Max RT等,如果监控数据比较正常,而业务感知到和Redis监控不一致的超时,可以看下ECS测是否存在干扰、客户端统计是否合理。也可以直接在ECS层直接抓包确定是否有网络重传或者其他原因。
如果发现监控数据不符合预期,可以继续在监控上看是否有比较耗时的命令,同时也可以控制台的“日志管理”中查看慢日志,对集群来来说,慢日志包括Redis Proxy层采集的和Redis采集的,找到罪魁祸首。
如果只是频率很小的Max RT抖动,只要业务没有影响,可以忽略,如果抖动较大可以提工单排查。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
存储 分布式计算 网络协议
阿里云服务器内存型r7、r8a、r8y实例区别参考
在阿里云目前的活动中,属于内存型实例规格的云服务器有内存型r7、内存型r8a、内存型r8y这几个实例规格,相比于活动内的经济型e、通用算力型u1实例来说,这些实例规格等性能更强,与计算型和通用型相比,它的内存更大,因此这些内存型实例规格主要适用于数据库、中间件和数据分析与挖掘,Hadoop、Spark集群等场景,本文为大家介绍内存型r7、r8a、r8y实例区别及最新活动价格,以供参考。
阿里云服务器内存型r7、r8a、r8y实例区别参考
|
1月前
|
NoSQL 关系型数据库 Redis
DMS产品常见问题之dms登录redis实例时报错如何解决
DMS(数据管理服务,Data Management Service)是阿里云提供的一种数据库管理和维护工具,它支持数据的查询、编辑、分析及安全管控;本汇总集中了DMS产品在实际使用中用户常遇到的问题及其相应的解答,目的是为使用者提供快速参考,帮助他们有效地解决在数据管理过程中所面临的挑战。
|
1月前
|
存储 弹性计算 安全
创建阿里云ECS实例
创建阿里云ECS实例
174 4
|
27天前
|
缓存 编解码 弹性计算
阿里云服务器e/u1/c7/c7a/c8a/c8y/g7/g7a/g8a/g8ae实例适用场景汇总
目前阿里云活动购买云服务器时,除了轻量应用服务器之外,活动内的云服务器实例规格主要以e/u1/c7/c7a/c8a/c8y/g7/g7a/g8a/g8ae这几种为主,本文主要为大家介绍了阿里云服务器的实例规格是什么,有什么用?并汇总了阿里云轻量应用服务器和阿里云服务器e/u1/c7/c7a/c8a/c8y/g7/g7a/g8a/g8ae实例规格适用场景,以供大家了解和选择适合自己的需求的实例规格。
阿里云服务器e/u1/c7/c7a/c8a/c8y/g7/g7a/g8a/g8ae实例适用场景汇总
|
1月前
|
存储 编解码 缓存
购买阿里云服务器如何选择实例?根据业务场景与细分场景选择实例规格
对于很多初次购买阿里云服务器的用户来说,面对众多可选择的云服务器实例规格,往往不知道如何选择,不同实例规格适用于不同的业务场景,本文为大家汇总了不同业务场景和细分场景下应该选择的主要实例规格,以及这些实例规格的主要性能和适用场景,如果你不知道如何选择阿里云服务器的实例规格,不妨根据自己的场景参考本文所推荐的主要实例规格来选择。
购买阿里云服务器如何选择实例?根据业务场景与细分场景选择实例规格
|
存储 弹性计算 网络协议
阿里云服务器经济型e、通用算力型u1与c7/g7/r7/c8y/g8y/r8y实例区别及选择参考
在阿里云目前的各个活动中,除了轻量应用服务器之外,活动内的云服务器实例规格主要以经济型e、通用算力型u1、计算型c7/c8y、通用型g7/g8y、内存型r7/r8y这几个实例规格为主,c7/c8y属于计算型实例,g7/g8y属于通用型实例,c7/r8y属于内存型实例,c7/g7/r7属于最新第七代云服务器实例,c8y/g8y/r8y属于倚天云服务器实例,不同的云服务器实例规格在性能、特点及适用场景上有所不同,本文大家介绍一下阿里云服务器经济型e、通用算力型u1与c7/g7/r7/c8y/g8y/r8y的区别,以供参考。
阿里云服务器经济型e、通用算力型u1与c7/g7/r7/c8y/g8y/r8y实例区别及选择参考
|
4天前
|
存储 运维 NoSQL
通过OOS实现定时备份Redis实例转储到OSS
基于阿里云 Redis 备份功能,现结合 OOS 推出自动转储至 OSS 的新方案,解决了数据安全风险、运维繁琐、成本增加和效率低下等问题。新方案亮点包括: 1. 数据安全性提高:备份文件自动上传至OSS,利用OSS的数据冗余存储,保证数据在硬件故障时的持久性和可用性。 2. 完全自动化:设置好定时规则后,备份和转储过程无需人工干预。 3. 多实例多地域集中管理:支持一次选择多个实例和跨区域备份,简化管理。 4. 灵活的备份策略和成本控制:自定义备份频率,并通过OSS生命周期管理策略控制成本。 5. 监控和告警:集成OSS和云监控,实时掌握备份状态,及时处理异常。
33 0
|
13天前
|
弹性计算 安全
电子好书发您分享《阿里云第八代企业级ECS实例,为企业提供更安全的云上防护》
阿里云第八代ECS实例,搭载第五代英特尔至强处理器与飞天+CIPU架构,提升企业云服务安全与算力。[阅读详情](https://developer.aliyun.com/ebook/8303/116162?spm=a2c6h.26392459.ebook-detail.5.76bf7e5al1Zn4U) ![image](https://ucc.alicdn.com/pic/developer-ecology/cok6a6su42rzm_f422f7cb775444bbbfc3e61ad86800c2.png)
35 14
|
15天前
|
NoSQL Redis 数据库
通过migrate命令实现两个redis实例之间的数据迁移
通过migrate命令实现两个redis实例之间的数据迁移
|
15天前
|
NoSQL Shell Redis
批量迁移redis实例的key
批量迁移redis实例的key

热门文章

最新文章