1. 前言
Amazon ElastiCache 是一种 Web 服务,可让用户在云中轻松设置、管理和扩展分布式内存数据存储或缓存环境。它可以提供高性能、可扩展且具有成本效益的缓存解决方案。同时,它可以帮助消除与部署和管理分布式缓存环境相关的复杂性。
ElastiCache for Redis 集群是一个或多个缓存节点的集合,其中所有节点都运行 Redis 缓存引擎软件的实例。ElastiCache for Redis 启用集群模式比之禁用集群模式拥有更好的可扩展性尤其是写入可扩展性,更强的高可用性以及更高的资源上限,因而现在越来越多的客户选择 ElastiCache for Redis 启用集群模式。要使用 ElastiCache for Redis 集群(启用集群模式),您需要使用可以支持redis集群模式的客户端。
当您使用 Go 程序连接 ElastiCache 集群时,目前目前主流的SDK是 Go-Redis项目,本篇 Blog 将为您介绍如何使用 go-redis 连接和使用 ElastiCache for Redis 集群。
除此以外,我们还推出了一系列博客,展示了如何在不同语言中,使用不同的支持 ElastiCache 集群模式的客户端对 ElastiCache 集群进行连接和操作,欢迎大家阅读。
2. Go-Redis测试环境搭建
2.1 ElastiCache for Redis 集群搭建
在亚马逊云科技上搭建 ElastiCache for Redis 集群,可以参考本篇的系列 Blog,条条大路通罗马 —— 使用 Redisson 连接 Amazon ElastiCache for Redis 集群 的2.1章节,这里就不再赘述。(Redis Cluster,打开Auth + TLS模式)
2.2 构建Golang SDK 测试代码工程的目录结构
2.2 使用go-redis 最新的版本分支 v8版本 ,下图总结了初始化 cluster client 常用参数,PoolSize 和 MinIdleConns控制请求的连接池。go-redis 支持TLS 连接,本示例主要演示打开 TLS + Password 的 ElastiCache for Redis 集群如何接入,如下图所示,参数Password已设置,参数TLSConfig控制TLS开关已打开。如果您连接的 ElastiCache for Redis 集群没有开启 TLS 接入,只需要把 Password 参数置为空字符串,去除 TLSConfig 配置即可(TLSConfig 默认关闭)。
2.3 使用 go-redis SDK 初始化 cluster client,包括读请求的测试逻辑(源代码)
3. go-redis 读写分离控制测试
Redis cluster是有Master和Slave节点,go-redis 支持对Slave 节点的访问,通过配置 ReadOnly参数,控制Master和Slave节点的读写管理。下面我们通过不同的配置去做测试验证。
3.1 ReadOnly 配置规则说明
3.2 关闭ReadOnly配置测试
修改测试代码,关闭 ReadOnly配置(三个 ReadOnly 参数配置都置为 false),观察监控仍然是维持10个 conn,但是按照配置说明,服务不会从读节点读取数据
观察对应的连接数,连接数仍然保持在10个
调整测试代码,增大查询压力,观察GetTypeCmds监控指标,可以看到只有master节点上是所有的读请求,判断所有的读压力都是分布在所有的 master 节点上。
3.3 打开ReadOnly配置测试
修改测试代码,打开 ReadOnly配置(或者 RouteByLatency 和 RouteRandomly 任意一个),观察监控仍然是维持10个 conn,但是按照配置说明,服务是会从读节点读取数据,可以判断 go-redis 默认和所有的 Master/Slave 节点都有长连接。
参考 CloudWatch Metrics观察对应的连接数,连接数仍然保持,没有变化,和客户端连接数统计一致。
如果ReadOnly打开,在适当压力情况下,观察GetTypeCmds监控,可以看到Master 和 Slave 节点都均匀分布读请求,可以判断读的压力是均匀分配到Master + Slave 节点上
4. 多值查询测试
4.1 go-redis 可以支持在 Redis 非集群和集群模式下 Pipeline 命令正确执行,以下给出 Pipeline 的代码示例。
4.2 go-redis 不支持 Redis 集群模式下,对不在一个 Shard 的多个Key执行MGet / MSet 操作,如果有类似的使用场景,建议使用 Redis-Go-Cluster开源项目,源码链接:Redis-Go-Cluster,以下为相应的代码示例。
5. Failover测试
5.1 执行 go test 做测试,持续的做读请求
在 Idle 和 PoolSize 相等的配置下,可以观察到 Redis 客户端服务和 Master 和 Slave 都是建立 10 个连接
在go test 开始之前,cluster 的 avg 连接数
在 go test 执行开始,3个master 和 3 个 slave 都新增了 10 个 conn
5.2 测试对 redis cluster的第一个 shard 做主动的 failover
5.3 在命令行输出观察到压测代码发生中断
5.4 在 ElastiCache Dashboard Events 观察 Failover 过程
可以观察到 8:54:13 PM ~ 8:54:36 PM UTC+8 经过 23s完成 Failover,测试代码的时间戳是 12:54:16 ~ 12:54:26 UTC,实际服务中断只有 10s 时间
在 12:53 UTC 时刻,连接正常
在 12:54 UTC 时刻,故障节点断开连接
在 13:00 UTC 时刻,故障节点开始恢复连接,但是所有服务请求未受到影响
在 13:02 UTC 时刻,所有连接完全恢复
5.5 在 ReadOnly = False 时,做Failover 时
Failover 时,中断时间
可以观察到 11:04:28 PM ~ 11:05:03 PM UTC+8 经过 35s完成 Failover,测试代码的时间戳是 15:04:27 ~ 15:04:51 UTC,实际服务中断为 24s 时间
在 15:03 UTC 连接正常
在 15:04 UTC Failover 开始断开一个节点
在 15:11 UTC 开始恢复一个节点
在 15:13 UTC 完全恢复
6. 小结
本博客为大家展示了如何在 Golang 程序中通过 go-redis 连接和操作 ElastiCache 集群,从这个简单的Demo中我们可以看到 go-redis 能很好地支持 ElastiCache 集群开启 TLS 及 Auth 的功能,并自动完成读写分离,负载均衡,Failover 等工作。在第5小结的Failover的测试中观察到打开ReadOnly可以加速故障恢复,建议实际使用基于ReadOnly更好的提升服务读写 Redis Cluster的性能。通过 go-redis,我们可以便捷,高效地使用 ElastiCache 集群。
除了本博客以外,我们还推出了一系列博客,展示了如何在不同语言中使用不同的客户端对 ElastiCache 集群进行连接和操作,欢迎大家阅读。