当前位置: 首页 > news >正文

ECS上自建Redis服务压测报告

背景说明

最近处理的企业大客户问题中,出现好几例都是客户通过购买ECS进行自建Redis服务,并且在使用过程中碰到一些因云环境的内部限制等原因导致客户使用中碰到服务异常或者产品性能上无法满足业务需求的情况。每次处理过程都费时费力,TAM同学一直不辞辛苦的跟进,也拉动了ECS/Redis 研发,网络,存储等同学进去排查,又是抓包又是电话会议,最终可能排查下来都是因为场景使用上的不合理,导致客户在该过程用的不爽,我们支持得也累。

这里根据目前客户通常采用的Redis主备Sentinel架构模式,在ECS 上构建Redis环境进行性能压测,提炼出一些客户自建Redis可能潜在的一些注意事项。原则上我们建议客户都采用阿里云KVStore服务,但客户非要通过自建Redis服务,我们则需要把一些注意事项说明清楚,也尽量让客户去规避这些问题。
后面我再专门写一篇文章,综合对比阿里云KVStore围绕性能、价格、维护成本、可靠性几方面进行“性价比”,以便更好践行“客户第一”。

压测主机规格情况

| ECS 实例 | 主机IP | 规格名称 | CPU | 内存 | 磁盘 | 区域 |
| ---- |-----| ----| ----| ----| ----| ----|
| i-2ze29lbqp06cfaxebxur | 192.168.1.130 | ecs.i1.xlarge | 4核 | 16 GB | 高I/O型本地盘  104GB | 华北 2 可用区 A |
| i-2ze7ut58w9lsgtn5icbm | 192.168.1.123 | ecs.gn4-c4g1.xlarge | 4核 | 30 GB | SSD云盘  20GB | 华北 2 可用区 A |
| i-2ze7ut58w9lsgtn5icbn | 192.168.1.125 | ecs.gn4-c4g1.xlarge | 4核 | 30 GB | SSD云盘  20GB | 华北 2 可用区 A |

Redis主备Sentinel集群架构

image.png

关于Sentinel 在Redis 高可用的实现上可以参阅:https://redis.io/topics/sentinel

Redis读写性能压测方法

Redis自带了可一个时间点模拟大量客户发起大量读写请求的工具
redis-benchmark(类似于Apache的ab Tool),下面为此次压测过程使用到的执行参数:

./redis-benchmark [-h <hostname>] [-a <passwrod>]  [-t <tests>] [-c <clients>] [-d <size>] [-n <requests>] [-P <numreq>]
 
-h <hostname>      Server hostname (default 127.0.0.1)
-p <port>          Server port (default 6379)
-a <password>      Password for Redis Auth
-t <tests>         Only run the comma separated list of tests. The test
                          names are the same as the ones produced as output.  
-c <clients>       Number of parallel connections (default 50)
-d <size>          Data size of SET/GET value in bytes (default 2)
-n <requests>      Total number of requests (default 100000)
-r <keyspacelen>   Use random keys for SET/GET/INCR, random values for SADD
                                  Using this option the benchmark will expand the string __rand_int__
                                   inside an argument with a 12 digits number in the specified range
                                   from 0 to keyspacelen-1. The substitution changes every time a command
                                   is executed. Default tests use this to hit random keys in the
                                   specified range.
 -P <numreq>        Pipeline <numreq> requests. Default 1 (no pipeline).

e.g:
./redis-benchmark -h 192.168.1.123 -a Redis123 -t set -c 100 -d 1024 -n 1000000 -P 100

压测结果分析

开启pipeline对QPS性能的影响

image.png

从上图可看出不同规格主机在写入value size只有一字节的情况下,不会出现Asynchronous AOF fsync is taking too long这样慢盘的情况。这种场景下,我们可暂时忽略ECS 存储盘性能影响。

在不开启Pipeline的情况下,本地盘SSD和云盘SSD都在小value读写下QPS相差无几,并且CPU、内存使用率都不高。但是在开启Pipeline的情况下,本地盘SSD比云盘SSD的读写性能要高出很多。
从Redis官网的介绍来看,Pipeline即对request做队列化,Redis Server 也对相应结果做队列化后再response,详细介绍可以参阅文档里头介绍的一个Request/Response Demo:
https://redis.io/topics/pipelining

哨兵sentinel down-after-milliseconds 参数设置对大value读写影响

image.png

image.png

从上面2个图对比可看出无论是本地盘SSD和云盘SSD,在redis写入value大于1024字节的情况下都会出现Disk Slow的情况,并且在哨兵配置sentinel down-after-milliseconds 计时5秒的情况下,写入value大于2048字节情况下会触发主备切换。
在发生主备切换的时候,主机CPU和内存利用率都不算高,因此在自建redis并且写入value过大的场景下,慢盘看起来貌似是一个无法规避的问题(这一块还在调研中,还在咨询存储的专家,可能因系统参数设置不合理导致?!)。

假设上面的问题无法规避,因此这里down-after-milliseconds 参数设置就很关键,如果设置时间过长,会导致写入失败切换时间过长,这中间相当于服务不可用。如果设置时间过短,会导致主备切换后节点状态不一致,可能造成频繁做主备切换,甚至导致整个集群不可用。
Redis官方建议的配置时间为30秒,如果并发写入量较高,建议该时间可适当设置长一点。

同等规格写入的value大小和读写QPS的关系

image.png

上图我把down-after-milliseconds 参数设置为官方建议的等待30秒,我们可以看到虽然触发了多次哨兵的aof_depayed_fsync计数,但是并未触发Sentinel主备切换,那么实际应用中则需要通过应用端的重试机制保证写入成功率。
我们再看看本地盘写入流量和IO情况:
image.png

image.png

可以看到写入量BPS峰值达到87Mbit/s,峰值写IOPS达到181Count/s
而今年首推的高I/O型本地盘在512KB顺序读写应用,可提供高达300MB/s的吞吐量能力,16KB随机读写应用,可提供高达12000的随机IOPS能力;可见对磁盘压测上远远还达不到上限。

排除磁盘性能影响,可见伴随写入value的增长,相对来说读的QPS差别不是很大,但是写入的QPS会有所下降。那高I/O型本地盘怎么发挥最大性能呢?答案上面已经说了,开启pipeline。

本地连接与远程连接的QPS性能差异

image.png

上图可以看出在同等规格写入大小一致value以及不开启pipeline的情况下,通过本地压测和远程压测的读写QPS性能差异很大,明显本地压测效果会更好点,那么远程压测的性能瓶颈在哪呢?
从访问途径上差异基本可以定位是虚拟网络的限制,其中主要关注虚拟网络内网的带宽限制和收发包数限制,我们查询了下这个规格ecs.i1.xlarge对应的限制,发现该规格的限制:
内网带宽(bit/s)为0.8G,内网收发包(PPS)为10万
因此在不开pipeline,写入value为512字节的远程写入情况下,收发包已经达到上限,故QPS就上不去了。
如果开启pipeline做队列化读写,可以大幅提供读写QPS,但内网带宽达到上限,如QPS依旧达不到本地写入的效果。
但是在实际使用场景中,基本上客户自建Redis都是通过远程写入,所以我们建议客户开启pipeline并且合理控制好虚拟内网带宽和收发包数量的限制(配置云监控),已获取一个较高的读写性能。

其他所有实例规格限制官方文档查询:
https://help.aliyun.com/document_detail/25378.html?spm=5176.doc52559.2.1.rZvgXZ#MN4

总结

客户购买ECS自建Redis Sentinel集群的情况下,推荐客户购买的ECS单独挂载使用高I/O型本地数据盘,并且对于高并发大量写入的情况下,建议设置哨兵down-after-milliseconds 大于15秒;如果写入value过大,需要留意ECS 实例规格对内网带宽和内网收发包数量的限制,建议开启pipeline实现更高的读写性能。

相关文章:

  • linux-grep、find、ps命令
  • (转载)OpenStack Hacker养成指南
  • 利用Logstash插件进行Elasticsearch与Mysql的数据
  • fastjson快速上手(4)
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • Python Configparser模块读取、写入配置文件
  • Oracle JET mobile cordove navigator.app对象
  • TFS 报错解决方案:tf400324
  • 欧洲某领先银行利用大数据实现创新转型
  • Nginx多层代理配置
  • 嗜血法医第八季/全集Dexter 8迅雷下载
  • 太一星晨:负载均衡啃不动的骨头交给应用交付
  • Android之通过HttpURLConnection.getResponseCode状态码抛出异常的问题以及解决方法
  • Dropcam摄像头:透过我的眼睛辨出你是谁
  • webservice fail protected mode
  • Angular 响应式表单之下拉框
  • CSS中外联样式表代表的含义
  • C语言笔记(第一章:C语言编程)
  • ECS应用管理最佳实践
  • express.js的介绍及使用
  • js学习笔记
  • mysql 数据库四种事务隔离级别
  • Protobuf3语言指南
  • scala基础语法(二)
  • SQL 难点解决:记录的引用
  • 番外篇1:在Windows环境下安装JDK
  • 解析带emoji和链接的聊天系统消息
  • 浏览器缓存机制分析
  • 漂亮刷新控件-iOS
  • 悄悄地说一个bug
  • 算法-插入排序
  • 怎样选择前端框架
  • RDS-Mysql 物理备份恢复到本地数据库上
  • ​flutter 代码混淆
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • ​比特币大跌的 2 个原因
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • $refs 、$nextTic、动态组件、name的使用
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (poj1.3.2)1791(构造法模拟)
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (简单) HDU 2612 Find a way,BFS。
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (原創) 物件導向與老子思想 (OO)
  • (转)Oracle存储过程编写经验和优化措施
  • .gitignore
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 表达式计算:Expression Evaluator
  • .net 调用php,php 调用.net com组件 --
  • .NET成年了,然后呢?
  • .net经典笔试题
  • .NET开发不可不知、不可不用的辅助类(一)
  • /3GB和/USERVA开关