亚马逊AWS官方博客

一箭双雕 – ElastiCache for Redis分层存储

背景

ElastiCache for Redis是亚马逊云科技推出的一款内存数据库,它与Redis接口兼容,支持Redis丰富的数据类型,支持各种Redis协议兼容的客户端访问。与此同时,它节约了运维人员人工操作Redis集群的精力,比如创建集群、扩展集群、备份恢复、升级集群等操作,得到用户的广泛使用。它也在不停进行创新来便利客户,比如通过Graviton2机型提供更高的性价比、通过自动扩展进一步减轻用户监控集群指标再手动扩展集群的负担等。

分层存储是ElastiCache for Redis在2021年11月份支持的一个新特性,它构建在新机型R6gd上,该机型基于Graviton2构建,额外增加了SSD盘。内存数据存满以后,ElastiCache会将相对不频繁访问的数据转移到SSD盘上,在后续需要访问的时侯再从SSD中取出,从而达到了数据自动分层的效果。数据存放在SSD中虽然比内存访问速度慢一些,但相较从后台更远的数据源比如关系数据库或者S3中去取数据,还是能达到更快的速度,因此我们也可以将存放在SSD中的数据定位为“温数据”。

ElastiCache分层存储可以为用户提供单节点更大容量的内存数据库,一方面能够帮助用户将更多的数据存在缓存中,另一方面每GB单位成本也会比普通的配置要低60%。它与Redis接口兼容,应用程序在使用ElastiCache分层存储时无需进行更改。本篇博客会从客户案例开始,介绍客户迁移到ElastiCache分层存储的场景、收益以及迁移过程,然后会对ElastiCache for Redis分层存储底层进行解密,阐述为什么它能帮助用户,最后会总结ElastiCache for Redis适用的场景。

场景

大宇无限在亚马逊云科技云平台上使用Elasticache Redis支持信息流视频推荐、频道推荐、广告推荐等业务高并发、低延迟的访问。

推荐业务通常需要非常高的缓存命中率来确保业务低延迟的访问,但不一定需要非常大并发访问量。通过运营监控显示,大宇无限存在一些Elasticache Redis集群,内存基本打满,但是CPU利用率却不足1%,为了提升计算资源利用率降低成本,需要对类似的缓存场景进行成本优化。总的来场景会有以下几个特点:

(1)需要很高的缓存命中率,从监控上体现就是集群的缓存空间基本被打满。

(2)对缓存的访问请求并要要求不是特别高,从监控上体现就是集群CPU利用率很低。

(3)对缓存的访问延迟没有苛刻的需求,比如少量访问延迟可以容忍到个位数毫秒级别。

针对大宇无限的需求,亚马逊云科技推荐了Elasticache Redis Data tiering方案。

收益

大宇无限目前已经完成从一个16*16分片(16个分片,每个分片1主1从,实例类型为cache.r6g.large)的集群迁移到2*2分片(2个分片,每个分片1主1从,实例类型为cache.r6gd.xlarge)的集群,业务已经平稳运行一段时间,集群CPU利用率最高提升到60%左右,成本降低50%左右。以下是Elasticache Redis Data tiering集群的CPU利用率提升图:

迁移到Elasticache Redis Data tiering集群后性能在可接受范围内,大部分命令还是在微秒级别,set命令和之前对比基本无差异,get命令有50%左右的延迟增加。以下为部分的性能监控图:

如何迁移到Elasticache Redis Data tiering

由于业务需求,从Elasticache Redis 迁移到Elasticache Redis Data tiering需要零停机在线迁移。经过调研可以通过RIOT-RedisRedisShake 两个工具进行全量和增量CDC迁移。以下分别介绍两个工具:

RIOT-Redis 迁移

在实时复制模式下,RIOT-Redis 使用键空间通知侦听源数据库上发生的更改。每次修改密钥时,RIOT-Redis 都会读取相应的值,并将该更改传播到目标数据库。

实时复制机制不保证数据一致性。Redis 通过 pub/sub 发送密钥空间通知,而 pub/sub 不提供有保证的交付。例如,RIOT-Redis可能会在网络故障的情况下错过一些通知。

由于RedisShake需要有申请流程开通psync命令支持,因此RIOT-Redis是一开始的首选方案。以下介绍RIOT-Redis使用步骤。

(1)准备迁移EC2机器,安装JAVA执行环境

RIOT-Redis是一个Java可执行程序,EC2机器建议使用Amazon Linux2, 需要自行安装Java 11以上的环境。例如:

sudo apt update 
java -version 
sudo apt install default-jre
java -version

Java环境也可以在用户目录配置环境变量。

(2)安装RIOT-Redis

RIOT-Redis是一个开源工具,可以直接git clone 到本地,然后即可使用。

git clone https://github.com/redis-developer/riot.git
cd riot/bin

(3)开始迁移

  • 修改集群参数组

需要把源集群使用的参数组中 notify-keyspace-events 参数的值修改为 AKE , 无需重启集群,详情参考:如何在 ElastiCache 中实施 Redis 密钥空间通知参考?

  • 启动迁移命令,让其在后台一直执行。
./riot-redis -h <source_EC_endpoint> -p 6379 -c replicate -h <Destination_EC_endpoint> -p 6379 -c --mode live \
> sync_live.log 2>&1 &

tail -f sync_live.log //实时查看日志

日志中 Scaning 100% 表示已完成全量迁移,Listening 表示正在监听更改,表示具备了CDC的能力。

(4)迁移性能

在验证的时候把源集群的notify-keyspace-events 参数值修改为AKE 后延时增加到了上百毫秒,极端的会到2s,影响正常业务。关闭参数后可以很快恢复正常。下图是某一个节点开启参数后性能情况。

由于会影响到业务,RIOT-Redis的迁移方案无法继续进行,继而选择了RedisShake方案。

RedisShake 迁移

Redis-shake是开源Redis数据传输工具,支持对Redis数据进行解析(decode)、恢复(restore)、备份(dump)和同步(sync或rump),易于部署,灵活高效。由于提供良好的托管服务体验, Elasticache Redis限制了某些Redis引擎的命令访问权限,具体参考:受限 Redis 命令。因此,如果需要开通psync 需要和亚马逊云科技技术支持团队进行申请和沟通。以下介绍使用RedisShake 工具迁移的步骤:

(1)申请开通psync 命令,需要提Case给亚马逊云科技技术支持团队进行申请。申请成功后得到的命令结果如下:

xxxxxxx-0-001  xxxxpsync

xxxxxxx-0-001 表示某一个节点/分片的名称,xxxxpsync 表示节点/分片对应的pync命令。Elasticache Redis和社区Redis 的不同在于Elasticache Redis每个节点/分片的pync命令是不一致的,一般加了一个前缀,比如 分片1,可能是一个前缀:abcdef,要同步分片1的命令就会是 abcdefpsync

  • RedisShake 安装

由于社区版本develop不支持自定义psync命令,因此根据开源版本定制了一个版本(当前最新版已支持自定义)。

git clone https://github.com/hillday/RedisShake-Self-psync.git
cd RedisShake-Self-psync
sh build.sh
  • 修改配置文件
cd  conf
vim redis-shake.conf
conf.version = 1
id = redis-shake
# 日志路径
log.file = /var/redis-shake.log
# info、debug、error按需设置
log.level = info
# 同步并行度,执行迁移的并发线程数,适当调大该值可提高同步性能
parallel = 8
# 源集群模式
source.type = standalone
# 源集群地址
source.address = xx.x.x.xxx:6379
# 用户名:密码
source.password_raw = username:password
source.auth_type = auth
# 目标集群模式
target.type = cluster
# elasticacheredis地址和端口
target.address = xx.xx.x.x:6379;xx.xx.x.x:6379;xx.xx.x.x:6379
# 用户名:密码
target.password_raw = 
target.auth_type = auth
# 是否迁移到同一个db中去
target.db = -1 
key_exists = rewrite
# 自定义psync ip0:port0#xx0psync;ip1:port1#xx1psync
self_defined_psync = xx.x.x.xxx:6379#xxxxpsync 
  • 执行迁移

./bin/redis-shake.linux -type=sync -conf=./conf/redis-shake.conf

(2)迁移效果

RedisShake 先进行全量同步,再进行增量同步,当在日志中看到DbSyncer时表示,已经在进行增量同步。最终使用RedisShake完成了本次迁移,在使用其迁移过程中,不会对业务造成明显的读写延迟和影响正常业务使用。

分层存储底层原理

在开启数据分层的集群上,ElastiCache会监控它存放的每个item的最后一次访问时间。当内存(DRAM)用满时,ElastiCache会自动将最少访问的Item自动从内存移到SSD盘上。如果SSD盘上的数据后续被访问,它会先将数据移至内存,然后返回给用户。通过SSD读取回来的数据,ElastiCache会自动做CRC32 checksum校验,来验证数据的完整性。

 

ElastiCache分层存储也提供了相应的指标,来显示内存和SSD中分别占用了多少资源,包括BytesUsedForCache和CurrItems,分表代表在字节数和Item数目。此外,提供了BytesReadFromDisk/BytesWrittenToDisk以及NumItemsReadFromDisk/NumItemsWrittenToDisk,来帮助用户衡量有多少数据/Item是从SSD盘中读取或者写入的。

分层存储使用的场景总结

ElastiCache的分层存储,能够提供相对于非分层存储单位定价更低的产品。它所适用的场景有两个方面:

(1)希望有更多的数据在内存中存放,从而可以减少缓存击穿的发生;

(2)希望能够节约成本,从下表我们可以看出,使用分层存储的机型,能够带来多达60%的成本节约。用户如果经常访问的数据占用到全部数据20%的情况时,分层存储的延迟和普通配置的延迟是可以相比的,都是在1ms以下,用户可以考虑进行相关优化。

R6g.xlarge R6gd.xlarge
vCPU 4 4
RAM (GiB) 26.32 26.32
SSD (GiB) 0 99.33
总容量(GiB) 26.32 125.65
每小时每节点单价(us-east-1) $0.41 $0.78
每小时每GiB单价 $0.02 $0.01

本篇作者

翟文秀(Shelly)

大宇无限 SRE 工程师,擅长中间件等各种云资源系统运维、规划、建设,对高并发、高流量的系统运营有深刻的洞见和运营经验,对云服务运维、成本优化、性能优化有丰富经验。

钱春海

亚马逊云科技解决方案架构师,负责基于AWS云平台的解决方案咨询和设计。拥有十余年ERP系统、大数据、VR/AR领域经验。在系统架构、大数据、应用研发领域有丰富的研发和实践经验。

马丽丽

亚马逊云科技数据库解决方案架构师,十余年数据库行业经验,先后涉猎NoSQL 数据库Hadoop/Hive、企业级数据库DB2、分布式数仓Greenplum/Apache HAWQ以及亚马逊云原生数据库的开发和研究。