亚马逊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、MemoryDB 方案,最终考虑到 MemoryDB 方案可能需要进行一定架构上改动,最终选择了 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 Data tiering 有两种不同的迁移需求:全量迁移和增量迁移。
如果是从 ElastiCache for Redis 全量迁移,可以先对 ElastiCache for Redis 打快照,然后将备份文件恢复成 ElastiCache for Redis Data Tiering 的集群。可以参照文档手动备份以及将数据从备份还原到启用数据分层的集群。如果是从其他 Redis 集群全量迁移,也可以先生成 RDB 文件,上传到 S3,在创建 ElastiCache 集群时指定类型为“Cluster cache from backup”, 指定 RDB 对应 S3 文件地址,选择以 r6gd 系列的节点类型(例如 cache.r6gd.xlarge)。选择该节点类型将会自动启用数据分层功能。
增量迁移,可以利用一些开源工具,比如 RIOT-Redis 和 RedisShake 等。下面会介绍使用 RIOT-Redis 进行全量和增量 CDC 迁移的过程。
RIOT-Redis 迁移
在实时复制模式下,RIOT-Redis 使用键空间通知侦听源数据库上发生的更改。每次修改密钥时,RIOT-Redis 都会读取相应的值,并将该更改传播到目标数据库。
实时复制机制不保证数据一致性。Redis 通过 pub/sub 发送密钥空间通知,而 pub/sub 不提供有保证的交付。例如,RIOT-Redis 可能会在网络故障的情况下错过一些通知。
以下介绍 RIOT-Redis 使用步骤。
(1)准备迁移 EC2 机器,安装 JAVA 执行环境
RIOT-Redis 是一个 Java 可执行程序,EC2 机器建议使用 Amazon Linux2, 需要自行安装 Java 11 以上的环境。例如:
Java 环境也可以在用户目录配置环境变量。
(2)安装 RIOT-Redis
RIOT-Redis 是一个开源工具,可以直接 git clone 到本地,然后即可使用。
(3)开始迁移
- 修改集群参数组
需要把源集群使用的参数组中 notify-keyspace-events 参数的值修改为 AKE
,无需重启集群,详情参考:如何在 ElastiCache 中实施 Redis 密钥空间通知参考?
- 启动迁移命令,让其在后台一直执行。
日志中 Scaning 100% 表示已完成全量迁移,Listening 表示正在监听更改,表示具备了 CDC 的能力。
分层存储底层原理
在开启数据分层的集群上,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 |