亚马逊AWS官方博客

重装上阵-Graviton2提升ElastiCache for Redis的性价比

1. 前言

从2020年10月开始,基于 AWS Graviton2 的缓存实例逐步推出,客户可以在使用 Amazon ElastiCache for Redis上使用这些实例。

Graviton2 处理器由 Amazon Web Services 使用 64 位 ARM Neoverse 内核定制,对第一代 AWS Graviton 处理器进行了多种性能优化。这包括 7 倍的性能、4 倍的计算核心数量、每个内核 2 倍的私有内存、5 倍的内存速度和每个核心 2 倍的浮点性能。此外,Graviton2 处理器还具有全天候运行的全加密 DDR4 内存功能,且每核加密性能提高 50%。这些性能提升使得装备了Graviton2 的实例成为缓存工作负载的上佳之选。

本文将向您展示Graviton2 R6g 缓存实例(测试实例类型cache.r6g,后续简称r6g或R6g)对R5缓存实例(cache.r5,后续简称r5或R5)的性能增强以及迁移到Graviton2 R6g 缓存实例的方法流程。

通过测试我们可以清楚地看到,无论是何种工作负载和并发条件,R6g实例比之同等资源配置的R5实例性能均有显著的提升,而且每小时单价却有下降,在这双重因素的叠加之下,选择新一代的r6g实例,具有更好的性能和性价比。

 

2. 环境准备

2.1 环境信息

 

测试客户端(新加坡区域,AZ3)

实例类型 vCPU 内存(GiB) 磁盘(GiB) 网络带宽
m5.8xlarge 32 128 500 10G

表格:测试客户端配置

测试服务端(新加坡区域,主用在AZ3)

Redis版本 实例类型 vCPU 内存(GiB) 集群模式
6.0.5 r6g.2xlarge 8 52.82 开启,3*3
6.0.5 r5.2xlarge 8 52.82 开启,3*3

表格:测试服务端配置

ElastiCache for Redis选择默认参数,开启了集群模式(Cluster),数据用3个分片(每个分片1主2从,合计9个节点,为了系统的高可用和管理需要,默认参数会设置25%的内存作为预留内存,所以读者在自己做性能测试时要留意别把内存耗光导致结果失真,这也是我们没有选择最低配置的实例做测试的原因之一)。

部署完毕后的集群地址:

类型 集群configuration endpoint入口地址
R5.2xlarge r5-2xlarge-elasticache-for-redis-cluster-endpoint:6379
R6g.2xlarge r6g-2xlarge-elasticache-for-redis-cluster-endpoint:6379

 

 

 

 

表格:测试的集群终端节点

我们把测试客户端和集群的主节点人工强行放到了同一个AZ以获取更直接的对比效果,同时选用的ElastiCache for Redis集群实例(3*3的2xlarge构建的集群)和测试客户端(8xlarge的EC2)均支持10G的带宽模式,读者在自己做测试时也要避免因网络带宽不足导致的测试结果失真。

可能很多读者会问,为什么测试的时候只选择这一个机型?细心的读者可能会发现,亚马逊云的机型是有一定规律的,例如4xlarge的配置刚好是2xlarge的两倍,而8xlarge的又刚好是4xlarge的两倍(以此类推,具体机型定义请参看 这里),所以此处我们用r5.2xlarge和r6g.2xlarge做个具有代表性的对比测试,就不用其他机型一一对比了。

2.2压测工具

此处我们使用两个不同的压测工具做针对性测试,一个是Redis自带的简单易用的redis-benchmark,一个是Redis Labs开源提供的在更高并发的场景使用的memtier_benchmark

2.2.1 redis-benchmark

redis-benchmark默认含在redis的分发里面,直接安装redis即可获得,在Amazon Linux 2操作系统上使用如下命令即可(这个安装在客户端上,后续迁移的时候也会用到这个客户端源)。

amazon-linux-extras install redis4.0 -y

其命令的常用参数选项如下:

选项 描述 默认值
-h 服务器地址 127.0.0.1
-p 服务器端口 6379
-s 服务器Socker,会覆盖-h和-p
-a 连接密码
-c 并发连接数 50
-n 总请求数 100000
-d GET/SET字节数大小(Byte) 3
-k 是否保持连接(1保持,0重连) 1
-r Key和value使用随机值
-P 是否使用管道(默认1等于没有使用) 1
-e 显示服务端错误
-q 静默模式,只显示结果
–csv 按csv格式输出
-l 循环测试,永不退出
-t 仅运行以逗号分隔的测试命令列表
-I 空闲模式,建立连接后啥都不干

表格:redis-benchmark的常用参数

2.2.2 memtier_benchmark

memtier_benchmark需要使用github上的源码进行编译才能使用,在Amazon Linux 2操作系统上可以使用如下方式:

yum install gcc git autoconf automake gcc-c++openssl-devel libevent-devel -y

 

mkdir /opt/memtier_benchmark

cd /opt/memtier_benchmark

 

git clone https://github.com/RedisLabs/memtier_benchmark.git

 

cd memtier_benchmark

autoreconf -ivf

 

./configure

make && make install

其命令的常用参数选项如下:

选项 描述 默认值
-s 服务器地址 localhost
-p 服务器端口 6379
-S 服务器Socker
-P 连接协议 redis
-a 连接方式和密码
-x 总迭代次数
-n 总请求数 10000
-d 测试使用的对象数据大小 32
-R 随机化的测试数据
-c 每个线程的测试客户端数 50
–treads 并发线程
–ratio 读写比例(SET/GET)
–test-time 测试时长(秒)
–select-db 选择测试使用DB
–data-size-range 数据大小随机(min-max)
–data-size-pattern S均匀分布,R随机分布
–key-minimum 测试键最小id 0
–key-maximum 测试键最大id 10000000
–key-pattern SET和GET的分布,G正态分布(高斯分布),R均匀随机,S连续访问,P并行 R:R
–key-stddev 正态分布标准差 1/6
–key-median=300 正态分布均值
-D 调试模式
-o 结果输出

表格:memtier_benchmark的常用参数

 

3. 测试过程

3.1 只读测试

注意:只读测试,我们只演示测试redis-benchmark工具。

测试R5.2xlarge机型的只读测试命令如下(压测200万次,并发1000,随机key和value,大小1k,不使用管道)

redis-benchmark -n 2000000 -c 1000 -t get -d 1024 -p 6379 -h r5-2xlarge-elasticache-for-redis-cluster-endpoint --csv

测试R6g.2xlarge机型的只读测试命令如下(压测200万次,并发1000,随机key和value,大小1k,不使用管道)

redis-benchmark -n 2000000 -c 1000 -t get -d 1024 -p 6379 -h r6g-2xlarge-elasticache-for-redis-cluster-endpoint --csv

结果如下(此处截图仅供参考,不参与后面的性能统计):

图例:对实例进行只读测试

3.2只写测试

注意:只写测试,我们只演示测试redis-benchmark工具。

测试R5.2xlarge机型的只写测试命令如下(压测200万次,并发1000,随机key和value,大小1k,不使用管道)

redis-benchmark -n 2000000 -c 1000 -t set,hset -d 1024 -p 6379 -h r5-2xlarge-elasticache-for-redis-cluster-endpoint --csv

测试R6g.2xlarge机型的只写测试命令如下(压测200万次,并发1000,随机key和value,大小1k,不使用管道)

redis-benchmark -n 2000000 -c 1000 -t set,hset -d 1024 -p 6379 -h r6g-2xlarge-elasticache-for-redis-cluster-endpoint --csv

结果如下(此处截图仅供参考,不参与后面的性能统计):

图例:对实例进行只写测试

3.3混合测试

3.3.1通过redis-benchmark测试

此处我们设定四个场景,分别是如下两种并发和键值(key/value)大小的组合:

  • 500并发,1k大小和4k大小;
  • 1000并发,1k大小和4k大小;

如下为对应的测试命令(包括常用的命令SET和GET,以及在实际业务中比较常用的HSET)。

测试场景1-1:500并发,1k大小,200万次请求

redis-benchmark -n 2000000 -c 500 -t set,get,hset -d 1024 -p 6379 -h r5-2xlarge-elasticache-for-redis-cluster-endpoint --csv

redis-benchmark -n 2000000 -c 500 -t set,get,hset -d 1024 -p 6379 -h r6g-2xlarge-elasticache-for-redis-cluster-endpoint --csv

测试场景1-2:500并发,4k大小,200万次请求

redis-benchmark -n 2000000 -c 500 -t set,get,hset -d 4096 -p 6379 -h r5-2xlarge-elasticache-for-redis-cluster-endpoint --csv

redis-benchmark -n 2000000 -c 500 -t set,get,hset -d 4096 -p 6379 -h r6g-2xlarge-elasticache-for-redis-cluster-endpoint --csv

测试场景1-3:1000并发,1k大小,200万次请求

redis-benchmark -n 2000000 -c 1000 -t set,get,hset -d 1024 -p 6379 -h r5-2xlarge-elasticache-for-redis-cluster-endpoint --csv

redis-benchmark -n 2000000 -c 1000 -t set,get,hset -d 1024 -p 6379 -h r6g-2xlarge-elasticache-for-redis-cluster-endpoint --csv

测试场景1-4:1000并发,4k大小,200万次请求

redis-benchmark -n 2000000 -c 1000 -t set,get,hset -d 4096 -p 6379 -h r5-2xlarge-elasticache-for-redis-cluster-endpoint --csv

redis-benchmark -n 2000000 -c 1000 -t set,get,hset -d 4096 -p 6379 -h r6g-2xlarge-elasticache-for-redis-cluster-endpoint --csv

每种场景测试5次以上,然后取如下图所示的SET、GET和HSET的值并计算均值作为结果(因为redis-benchmark的单进程特性,在并发和模拟实际客户端场景层面难以完全覆盖,我们测试发现请求数在约10万/秒左右即达到上限,即使修改并发和数据大小也无法突破,所以这部分留给读者自己去做操作和测试验证,本文测试数据收集不考虑此工具,防止数据出现偏差)。

图例:对实例进行混合测试(SET/GET/HSET)

 

3.3.2通过memtier_benchmark测试

此处我们同样设定四个场景,为如下条件的组合:

  • 随机测试:分别测试500和1000并发,键值1k到4k大小随机,测试时间180秒,SET和GET的比例为1:4;
  • 正态分布(高斯分布)测试:分别测试500和1000并发,键值1k到4k大小随机,测试时间180秒,SET和GET的比例为1:4;

我们没有设置更高的并发或更大的键值测试,因为在测试的过程中,我们发现系统运行比较稳定,调高并发或键值会导致本文的测试客户端m5.8xlarge的带宽使用率直接打满10G(如果要测试集群的极限,建议采用多客户端的分布式测试方式,本文暂不涉及),我们的测试命令只包括SET和GET,且为了更好的模拟实际生产环境中的读写比例,所以此处读写比例设置为1:4(模拟20%写)。

测试场景2-1:随机测试,500并发,键值1k-4k随机大小,测试时间180秒,SET和GET比例为1:4

memtier_benchmark -R --data-size-range=1024-4096 --data-size-pattern=S --test-time 180 -t 10 -c 50 --cluster-mode --ratio=1:4 -p 6379 -s r5-2xlarge-elasticache-for-redis-cluster-endpoint

memtier_benchmark -R --data-size-range=1024-4096 --data-size-pattern=S --test-time 180 -t 10 -c 50 --cluster-mode --ratio=1:4 -p 6379 -s r6g-2xlarge-elasticache-for-redis-cluster-endpoint

测试场景2-2:随机测试,1000并发,键值1k-4k随机大小,测试时间180秒,SET和GET比例为1:4

memtier_benchmark -R --data-size-range=1024-4096 --data-size-pattern=S --test-time 180 -t 20 -c 50 --cluster-mode --ratio=1:4 -p 6379 -s r5-2xlarge-elasticache-for-redis-cluster-endpoint

memtier_benchmark -R --data-size-range=1024-4096 --data-size-pattern=S --test-time 180 -t 20 -c 50 --cluster-mode --ratio=1:4 -p 6379 -s r6g-2xlarge-elasticache-for-redis-cluster-endpoint

测试场景2-3:正态分布(高斯分布)测试,500并发,键值1k-4k随机大小,测试时间180秒,SET和GET比例为1:4

memtier_benchmark -R --data-size-range=1024-4096 --data-size-pattern=S --test-time 180 -t 10 -c 50 --cluster-mode --key-pattern=G:G -p 6379 -s r5-2xlarge-elasticache-for-redis-cluster-endpoint

memtier_benchmark -R --data-size-range=1024-4096 --data-size-pattern=S --test-time 180 -t 10 -c 50 --cluster-mode --key-pattern=G:G -p 6379 -s r6g-2xlarge-elasticache-for-redis-cluster-endpoint

测试场景2-4:正态分布(高斯分布)测试,1000并发,键值1k-4k随机大小,测试时间180秒,SET和GET比例为1:4

memtier_benchmark -R --data-size-range=1024-4096 --data-size-pattern=S --test-time 180 -t 20 -c 50 --cluster-mode --key-pattern=G:G -p 6379 -s r5-2xlarge-elasticache-for-redis-cluster-endpoint

memtier_benchmark -R --data-size-range=1024-4096 --data-size-pattern=S --test-time 180 -t 20 -c 50 --cluster-mode --key-pattern=G:G -p 6379 -s r6g-2xlarge-elasticache-for-redis-cluster-endpoint

在测试过程中,我们发现系统运行非常稳定,所以每种场景测试了6次,然后取如下图所示的Sets、Gets和Waits的p99均值(其中1000并发我们没有取p99的均值,而是取了总体的均值,因为我们发现在R5机型的集群中,1000并发的情况下,p99均值的波动和方差太大,而R6g的机型没有这个问题,为了方便对比,就没有取并发1000的延时p99均值)。

图例:对实例进行混合测试(本文测试数据集来自此测试模式)

3.4监控

在测试的过程中,我们可以在CloudWatch控制台查看ElastiCache的Cluster端的对应数据,类似如下(主要防止因为资源耗尽的原因导致结果异常,如CPU,带宽等):

图例:CloudWatch的监控数据

在测试客户端,每一次使用memtier_benchmark测试都会输出对应的网络流量,记得别超过实例的最高值即可,否则请使用多个实例的分布式并发测试(例如想压测出ElastiCache for Redis的集群的性能极限)或者使用更高规格的实例(对应网络带宽会更大)。

 

4. 对比分析

针对之前的混合读写测试场景,我们针对memtier_benchmark工具的4个不同场景各做了6轮测试(每次重新开始测试前使用“flushdb/flushall”清理集群中的3个主分片,我们发现测试的结果非常的接近,表示服务器端运行稳定),获取到的原始数据如下:

表格:测试获取到的原始数据

4.1性能对比

注意:在计算比例时,以结果优的为基数(分母)。

4.1.1写入性能对比

在场景2-1中,r6g对比r5,其SET的每秒请求数提升了40%;

在场景2-2中,r6g对比r5,其SET的每秒请求数提升了37%;

在场景2-3中,r6g对比r5,其SET的每秒请求数提升了37%;

在场景2-4中,r6g对比r5,其SET的每秒请求数提升了34%。

对比结果如下图所示(数值越大越好):

图例:SET写入场景性能对比

4.1.2读取性能对比

在场景2-1中,r6g对比r5,其GET的每秒请求数提升了40%;

在场景2-2中,r6g对比r5,其GET的每秒请求数提升了37%;

在场景2-3中,r6g对比r5,其GET的每秒请求数提升了37%;

在场景2-4中,r6g对比r5,其GET的每秒请求数提升了34%。

对比结果如下图所示(数值越大越好):

图例:GET读取场景性能对比

4.1.3响应延时对比

在场景2-1中,r6g对比r5,其p99(99%)的响应延时降低了36%;

在场景2-2中,r6g对比r5,其平均响应延时降低了37%;

在场景2-3中,r6g对比r5,其p99(99%)的响应延时降低了50%;

在场景2-4中,r6g对比r5,其平均响应延时降低了36%;

对比结果如下图所示(数值越小越好):

图例:请求延时对比

4.2性价比对比

我们从Amazon Web Services的 官网列表价 查询到如下的ElastiCache for Redis实例每小时的价格(价格根据不同区域,不同时间会有差异,此处以2021-04-29的新加坡区域为例,最新和最终价格以官网页面为准):

实例类型 列表价(按需类型,不计算企业折扣) 说明
cache.r5.2xlarge $1.035/小时
cache.r6g.2xlarge $0.985/小时 便宜5.07%

Amazon Web Services也提供一个云上的成本计算器,针对上述两种机型,我给大家做了一个成本 计算的例子 供大家分享。

4.3结论

同样条件下的性能测试和延时,R6g机型(基于Graviton 第2代的ARM架构)均大幅领先原有基于通用CPU的R5机型。通过测试我们可以清楚地看到,无论是何种工作负载和并发条件,R6g实例比之同等资源配置的R5实例性能均有显著的提升,而每小时单价却有下降,因而R6g实例对客户来说,有更好的性价比。

综上所述,结合性能优势和价格优势,新发布的R6g机型将是客户在使用ElastiCache for Redis服务时的更优选择。

注意:当您按本文步骤进行测试的时候,随着环境,测试步骤的不同,可能需要对命令参数进行微调,测试结果也会有相应变化,但测试的思路以及测试结果变化的客观规律却是共通的。

 

5.实例的迁移

相对于ElastiCache for Redis管理服务,部分客户也喜欢自建Redis平台,但是相对平台服务而言,有如下比较明显的缺点和难题需要解决:

  • 难以管理:管理服务器配置、软件补丁、安装、配置与备份
  • 难以实现高可用:需要快速执行错误检测与修复
  • 难以扩展:在线扩展可能引发错误,且需要监控副本性能
  • 成本高昂:人员、流程、硬件与软件需要占用大量资金

除了前面章节对比测试的性能和延时,以及成本优势外,使用ElastiCache for Redis的管理服务还有如下优势可以让客户直接开箱即用:

  • 极致性能:提供小于1ms的响应时间;当前最大支持500个节点,340TB存储的最大Redis集群;最大支持3250万连接数,满足极致场景的巅峰性能;
  • 全托管:Amazon Web Services管理所有的硬件以及软件的配置和监控;
  • 易伸缩:通过副本提供读操作的弹性伸缩,通过分片提供写操作非中断的弹性伸缩;支持横向和纵向的弹性伸缩;
  • 可靠性保障:多可用区(免跨AZ流量费)支持,深度和详细的监控和告警,自动故障转移(10-20s内实现Fail Over);
  • 安全和合规:通过Amazon VPC实现网络隔离和管理,符合HIPAA,PCI和FedRAMP等安全和合规要求,存储和传输中支持进行加密和身份认证;
  • 兼容性:兼容多个Redis版本和客户端,支持导入导出,支持快照和恢复等;

5.1纯手工迁移

比较传统的方式是把运行在EC2(或者容器)里面的Redis数据做个备份导出(通过在reids-cli中使用阻塞式的save命令或者后台方式的bgsave命令),然后把导出文件存到S3(当前只支持从S3导入),然后在ElastiCache控制台创建集群时选择导入位于S3的备份文件,在这种操作方式下,如果源还在继续使用可能会导致两边的数据不完全同步,如果源不操作等新集群可用户再切换的话,则会有一定的服务中断时间。

具体操作见从备份还原的 指引文档 ,本文不做额外的演示和说明。

5.2使用redis-migration-tool进行迁移

Redis-migration-tool是github上开源的一个Redis迁移工具,使用它可以在不同的Redis环境(如单机,集群等)实现同步和复制。

在Amazon Linux 2操作系统上可以使用如下方式使用redis-migration-tool:

mkdir /opt/redis-migration-tool && cd /opt/redis-migration-tool

git clone https://github.com/vipshop/redis-migrate-tool.git

因为这个工具有段时间没更新了,我们使用的是比较新的Redis 6.0.5版本,所以需要修改一下源码中关于RDB文件版本的定义。

修改“/opt/redis-migration-tool/redis-migrate-tool/src/rmt_redis.c”,把原来的 “#define REDIS_RDB_VERSION 7” 修改成 “#define REDIS_RDB_VERSION 10”,然后再编译:

cd /opt/redis-migration-tool/redis-migrate-tool

autoreconf -fvi

./configure

make

 

#编译好的文件位于src/redis-migrate-tool

接着编辑对应的配置文件“/opt/redis-migration-tool/redis-migrate-tool/rmt.conf”,内容如下(记得修改对应的集群endpoint):

[source]

type: single

servers :

- 127.0.0.1:6379

 

[target]

type: redis cluster

servers:

- r6g-2xlarge-elasticache-for-redis-cluster-endpoint:6379

 

[common]

listen: 0.0.0.0:8888

同时,我们此处使用之前的测试机(那个m5.8xlarge的EC2)的机器当做源,然后通过脚本往里面压数据,命令如下(模拟一个并发,一个客户端,持续180秒的写入随机数据):

memtier_benchmark -R --data-size-range=1024-4096 --data-size-pattern=S --test-time 180 -t 1 -c 1 -p 6379 -s 127.0.0.1

5.2.1准备

原来在准备redis-benchmark工具的时候已经安装了redis服务,此处我们把服务启动,并确认数据内容,同时手工写入一个key做测试,如下:

systemctl enable redis

systemctl start redis

 

redis-cli

# keys *

# set owner "WeiqiongChen"

源如下所示(没有其他数据,只有我们手工写入的key):

图例:准备位于EC2的源Redis(单机版)

目标如下所示(没有其他数据,也没有我们手工写入的key,因为还没开始同步):

图例:清理目标ElastiCache for Redis集群环境

5.2.1迁移和同步

在源通过如下命令开始生成数据

memtier_benchmark -R --data-size-range=1024-4096 --data-size-pattern=S --test-time 180 -t 1 -c 1 -p 6379 -s 127.0.0.1

如下:

图例:启动源

然后再启动同步(特意晚启动同步模拟客户真实的迁移场景)

cd /opt/redis-migration-tool/redis-migrate-tool

./src/redis-migrate-tool -c ./rmt.conf -o log &

如下所示:

图例:启动源到目的的同步

5.2.1验证

我们统计源注入的数据量,如下(此处为473563个key):

图例:查看源的数据量

对比查看目标库同步的数据量(因为目标卡集群分成三个片了,所以要统计三个分片的总数),如下(此处合并总数依然是473563个key):

图例:查看目标的数据量

注意:读者们可以在源多做几轮测试,验证同步结果是否符合预期(如果没有数据同步或者有异常,可以查看redis-migration-tool目录的log文件查看异常信息)。

 

扩展阅读

Amazon ElastiCache用户指南》: https://docs.aws.amazon.com/zh_cn/AmazonElastiCache/latest/red-ug/GettingStarted.html

Amazon ElastiCache 最佳实践》:https://docs.aws.amazon.com/zh_cn/AmazonElastiCache/latest/red-ug/BestPractices.html

使用CloudWatch监控Amazon ElastiCache 的最佳实践》:https://aws.amazon.com/cn/blogs/database/monitoring-best-practices-with-amazon-elasticache-for-redis-using-amazon-cloudwatch/

五个用来评估Amazon ElastiCache容量的工作负载指标》:https://aws.amazon.com/cn/blogs/database/five-workload-characteristics-to-consider-when-right-sizing-amazon-elasticache-redis-clusters/

 

本篇作者

陈卫琼

亚马逊云科技资深解决方案架构师,负责协助客户业务系统上云的解决方案架构设计和咨询,现致力于大数据和IoT相关领域的研究。