我們來確認一下Amazon ElastiCache for Redis的端點
太长不看
-
- Amazon ElastiCache for Redisにおいて利用すべきエンドポイントは、ノードの数やクラスターモードが有効かどうかで異なる
-
- シングルノードの場合
ノードのエンドポイント(Endpoint)を読み書きのオペレーションに使う
PrimaryEndpointでもいい気も
クラスター構成の場合
クラスターモードが有効の場合は、ConfigurationEndpointを使う
クラスターモードが無効の場合は、書き込みにはPrimaryEndpointを、読み込みにはReaderEndpointを使う
我阅读了一下Amazon ElastiCache for Redis的文档,但是不太清楚在什么情况下使用哪个终端节点,所以可能要仔细阅读一下。
所以,这篇文章的目的是整理这些信息。
Amazon ElastiCache for Redis的配置模式。
简而言之,在TL;DR中写道的“单节点情况”和“集群配置情况”,是从以下页面摘取的(表达方式可能不完全相同)。
搜索连接终端点
让我们确认一下术语,以免对“簇”这个词感到困惑。
Redis 的术语在 ElastiCache 中的使用
不管怎样,好像在所有的情况下都使用了”集群”这个词。
控制台对所有 Redis 用 ElastiCache 集群使用“集群”这个词。
阅读此描述时
如果集群是单节点 Redis 集群,即集群没有分片,也不支持复制。
如果集群是单一分片内的 Redis 集群(在 API 和 CLI 中称为节点组),支持复制,但禁用集群模式。
如果集群是在 1 到 90 个分片内支持复制的 Redis 集群(启用集群模式)。
只需一种选项即可:在以下内容中理解即可。
作为参考,您可以参考这些文档。
使用复制组以实现高可用性。
关于 Redis 复制的问题
Redis在非集群模式和集群模式下的复制功能比较。
这些都被称为”群集”,而且每种模式都有一个以上的分片。
原本的Redis数据存储集群(Redis Cluster)这个术语,仅指分片配置情况。
Redis集群教程
呃,有点复杂…。
亚马逊ElastiCache for Redis的连接终端
这次的讨论是关于选择哪种配置,从而改变使用的终节点。
顺便说一下,”エンドポイント” 是指
-
- アドレス
- ポート
似乎是由…组成的。
看到以下的文件,似乎可以分为四种类型的终端点。
搜索连接终点
在Redis中查找(不启用集群模式)集群终端点(控制台)。
Redis(启用集群模式)在集群中搜索端点(控制台)。
-
- (ノード単位の)Endpoint
-
- PrimaryEndpoint
-
- ReaderEndpoint
- ConfigurationEndpoint
用法大概就是这样的。
看到后续的确认结果,我觉得即使是在单节点上,也可以使用PrimaryEndpoint。
另外,实际上还有一个名为ReadEndpoint的东西,据说这是节点级别的读取端点。
听起来是这样,它会将这个操作在分片内的(多个)复制节点上进行负载均衡,这个操作被称为ReaderEndpoint。
在Amazon ElastiCache Redis中启动主节点端点。
配置 Amazon ElastiCache 以提高 Redis 的可用性。
在出现ReaderEndpoint之前,我们是管理着每个节点的终端点的对吧…。
在AWS文档中,出现了”配置端点”和”读取端点”这样的术语,我觉得意思不太清楚。这样的术语也很难与AWS CLI的结果关联起来。
一旦困惑,我决定查看英文版以了解情况。
那么,让我们这样来解释并实际试一下。我们将使用Terraform来构建验证环境。
环境
这次的环境是这里。
$ terraform version
Terraform v0.13.0
+ provider registry.terraform.io/hashicorp/aws v3.2.0
$ aws --version
aws-cli/2.0.40 Python/3.7.3 Linux/4.15.0-112-generic exe/x86_64.ubuntu.18
在中国本地化中,可以这样解释:AWS的凭据是通过环境变量进行设置的。
$ export AWS_ACCESS_KEY_ID=...
$ export AWS_SECRET_ACCESS_KEY=...
$ export AWS_DEFAULT_REGION=ap-northeast-1
接下来,我们将按照以下的结构逐一尝试。
-
- シングルノード構成
-
- レプリケーション構成
- シャーディング構成
Amazon ElastiCache for Redis的Redis版本将设为5.0.6。
我希望在与Amazon ElastiCache for Redis相同的子网上准备Amazon EC2,并通过redis-cli进行确认。
这个将在Amazon Linux 2上进行构建。
$ sudo amazon-linux-extras install epel
$ sudo yum install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
$ sudo yum search --showduplicates --enablerepo=remi search redis | grep '^redis-5'
redis-5.0.9-1.el7.remi.x86_64 : A persistent key-value database
$ sudo yum install --enablerepo=remi redis-5.0.9-1.el7.remi.x86_64
虽然版本稍微更新,但这次我们安装的是Redis 5.0.9,并且只使用redis-cli。
$ redis-cli -v
redis-cli 5.0.9
单节点结构
首先,从单节点结构开始。
我們可以使用 Terraform 來準備 aws_elasticache_replication_group、aws_elasticache_parameter_group 和 aws_elasticache_subnet_group。其他元素將在最後一起列出。
# Single Node
resource "aws_elasticache_replication_group" "redis" {
replication_group_description = "My ElastiCache for Redis Replication Group"
replication_group_id = "my-redis-replication-group"
engine = "redis"
engine_version = "5.0.6"
node_type = "cache.t3.medium"
port = 6379
parameter_group_name = aws_elasticache_parameter_group.redis_parameter_group.name
security_group_ids = [module.elasticache_for_redis_cluster_sg.this_security_group_id]
subnet_group_name = aws_elasticache_subnet_group.redis_subnet.name
automatic_failover_enabled = false
number_cache_clusters = 1 # Primary Only
}
resource "aws_elasticache_parameter_group" "redis_parameter_group" {
family = "redis5.0"
name = "my-elasticache-for-redis-parameter-group"
parameter {
name = "cluster-enabled"
value = "no"
}
}
resource "aws_elasticache_subnet_group" "redis_subnet" {
name = "my-elasticache-for-redis-subnet-group"
subnet_ids = module.vpc.private_subnets
}
复制组的id被命名为my-redis-replication-group。
顺便说一句,作为Terraform的aws_elasticache_replication_group的输出结果,可以得到一些有关端点和节点的信息,包括主要端点(PrimaryEndpoint)、配置端点(ConfigurationEndpoint),以及集群中的成员。
资源: aws_elasticache_replication_group / 属性参考
所以,暂时先设置为输出输出。
output "redis_elasticache_replication_group_primary_endpoint_address" {
value = aws_elasticache_replication_group.redis.primary_endpoint_address
}
output "redis_elasticache_replication_group_configuration_endpoint_address" {
value = aws_elasticache_replication_group.redis.configuration_endpoint_address
}
output "redis_elasticache_replication_group_member_clusters" {
value = aws_elasticache_replication_group.redis.member_clusters
}
我们得到的是这种感觉。
Outputs:
redis_elasticache_replication_group_member_clusters = [
"my-redis-replication-group-001",
]
redis_elasticache_replication_group_primary_endpoint_address = my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com
"outputs": {
"redis_elasticache_replication_group_member_clusters": {
"value": [
"my-redis-replication-group-001"
],
"type": [
"set",
"string"
]
},
"redis_elasticache_replication_group_primary_endpoint_address": {
"value": "my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com",
"type": "string"
}
},
似乎只有在启用了集群模式时,才能获得 ConfigurationEndpoint 这个选项。
配置端点地址 – 当启用集群模式时,复制组配置的端点地址。
相反地,据看起来,只有在群集模式禁用时才能获得PrimaryEndpoint。
主节点终端地址 – (仅适用于Redis)如果禁用了集群模式,该复制组中主节点的终端地址。
在这里返回的终端节点似乎只有地址(没有端口)。
AWS CLIでも確認してみましょう。
$ aws elasticache describe-replication-groups \
--replication-group-id my-redis-replication-group | \
jq '..|.NodeGroups?'
null
[
{
"NodeGroupId": "0001",
"Status": "available",
"PrimaryEndpoint": {
"Address": "my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"ReaderEndpoint": {
"Address": "my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"NodeGroupMembers": [
{
"CacheClusterId": "my-redis-replication-group-001",
"CacheNodeId": "0001",
"ReadEndpoint": {
"Address": "my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"PreferredAvailabilityZone": "ap-northeast-1c",
"CurrentRole": "primary"
}
]
}
]
PrimaryEndpoint、ReaderEndpoint、ReadEndpoint分别指代了不同的值呢。
这次看起来不管使用哪个都会返回相同的值。
$ dig +short my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com
my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com.
10.0.40.66
$ dig +short my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com
my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com.
10.0.40.66
$ dig +short my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com
10.0.40.66
无论连接到哪个地址,都可以进行读写操作。
$ redis-cli -h my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com
my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com:6379> set key1 value1
OK
my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com:6379> get key1
"value1"
my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com:6379>
$ redis-cli -h my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com
my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com:6379> set key2 value2
OK
my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com:6379> get key2
"value2"
$ redis-cli -h my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com
my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com:6379> set key3 value3
OK
my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com:6379> get key3
"value3"
我们也来看看副本的信息。虽然在节点级别的端点上执行,但使用其他端点结果是相同的。
复制
$ redis-cli -h my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com info replication
# Replication
role:master
connected_slaves:0
master_replid:5b13bc875ab08515dc6fbfde8060a9334ff6bd6d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
顺便说一下,如果用AWS CLI来查询新创建的集群的id,应该会是类似于my-redis-replication-group-001的形式。
$ aws elasticache describe-cache-clusters | \
jq '..|.CacheClusterId?'
null
"my-redis-replication-group-001"
让我们来看看节点单位的信息。
$ aws elasticache describe-cache-clusters \
--cache-cluster-id my-redis-replication-group-001 \
--show-cache-node-info | \
jq '..|.CacheNodes?'
null
[
{
"CacheNodeId": "0001",
"CacheNodeStatus": "available",
"CacheNodeCreateTime": "2020-08-14T13:38:43.098000+00:00",
"Endpoint": {
"Address": "my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"ParameterGroupStatus": "in-sync",
"CustomerAvailabilityZone": "ap-northeast-1c"
}
]
这是一个节点级别的终端点是吗?
顺便提一下,根据刚才的复制组信息,它指的是ReadEndpoint的相同值…。
# aws elasticache describe-replication-groups --replication-group-id my-redis-replication-group
"ReadEndpoint": {
"Address": "my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
# aws elasticache describe-cache-clusters --cache-cluster-id my-redis-replication-group-001 --show-cache-node-info
"Endpoint": {
"Address": "my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
在这种情况下,使用AWS CLI获取节点级别的终端节点可能是最好的选择。
看到这个复制配置的结果后,好像即使使用PrimaryEndpoint也没关系。
顺便提一句,好像用Terraform也无法获取ReaderEndpoint。
reader的端点在aws_elasticache_replication_group #10519中。
好的。
在这里,我们将一次性释放资源。
复制配置
接下来,我们尝试进行复制配置。
resource "aws_elasticache_replication_group" "redis" {
replication_group_description = "My ElastiCache for Redis Replication Group"
replication_group_id = "my-redis-replication-group"
engine = "redis"
engine_version = "5.0.6"
node_type = "cache.t3.medium"
port = 6379
parameter_group_name = aws_elasticache_parameter_group.redis_parameter_group.name
security_group_ids = [module.elasticache_for_redis_cluster_sg.this_security_group_id]
subnet_group_name = aws_elasticache_subnet_group.redis_subnet.name
automatic_failover_enabled = true
number_cache_clusters = 3 # Primary : Replica = 1 : 2
}
resource "aws_elasticache_parameter_group" "redis_parameter_group" {
family = "redis5.0"
name = "my-elasticache-for-redis-parameter-group"
parameter {
name = "cluster-enabled"
value = "no"
}
}
resource "aws_elasticache_subnet_group" "redis_subnet" {
name = "my-elasticache-for-redis-subnet-group"
subnet_ids = module.vpc.private_subnets
}
单节点时与之前几乎相同,但略有差别。
对于主节点,我们尝试设置两个副本节点。
number_cache_clusters = 3 # Primary : Replica = 1 : 2
另外,我有点儿随意地启用了自动故障转移。
automatic_failover_enabled = true
输出的结果是这样的。
Outputs:
redis_elasticache_replication_group_member_clusters = [
"my-redis-replication-group-001",
"my-redis-replication-group-002",
"my-redis-replication-group-003",
]
redis_elasticache_replication_group_primary_endpoint_address = my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com
"outputs": {
"redis_elasticache_replication_group_member_clusters": {
"value": [
"my-redis-replication-group-001",
"my-redis-replication-group-002",
"my-redis-replication-group-003"
],
"type": [
"set",
"string"
]
},
"redis_elasticache_replication_group_primary_endpoint_address": {
"value": "my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com",
"type": "string"
}
},
成员集群中的数量增加了,同时也得到了主要的终端地址,但配置终端地址仍然没有。
我会使用AWS CLI进行确认。
$ aws elasticache describe-replication-groups \
--replication-group-id my-redis-replication-group | \
jq '..|.NodeGroups?'
null
[
{
"NodeGroupId": "0001",
"Status": "available",
"PrimaryEndpoint": {
"Address": "my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"ReaderEndpoint": {
"Address": "my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"NodeGroupMembers": [
{
"CacheClusterId": "my-redis-replication-group-001",
"CacheNodeId": "0001",
"ReadEndpoint": {
"Address": "my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"PreferredAvailabilityZone": "ap-northeast-1c",
"CurrentRole": "primary"
},
{
"CacheClusterId": "my-redis-replication-group-002",
"CacheNodeId": "0001",
"ReadEndpoint": {
"Address": "my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"PreferredAvailabilityZone": "ap-northeast-1c",
"CurrentRole": "replica"
},
{
"CacheClusterId": "my-redis-replication-group-003",
"CacheNodeId": "0001",
"ReadEndpoint": {
"Address": "my-redis-replication-group-003.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"PreferredAvailabilityZone": "ap-northeast-1a",
"CurrentRole": "replica"
}
]
}
]
由于节点增加,本次架构中ReadEndpoint的数量也增加了。
从 EC2 实例内尝试通过 dig 进行确认。
# PrimaryEndpoint
$ dig +short my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com
my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com.
10.0.40.53
# ReaderEndpoint
$ dig +short my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com
my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com.
10.0.40.31
$ dig +short my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com
my-redis-replication-group-003.dl12u5.0001.apne1.cache.amazonaws.com.
10.0.30.200
# ノード単位のReadEndpoint
$ dig +short my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com
10.0.40.53
$ dig +short my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com
10.0.40.31
$ dig +short my-redis-replication-group-003.dl12u5.0001.apne1.cache.amazonaws.com
10.0.30.200
每个值似乎都指向实际节点的IP地址。另外,就”ReaderEndpoint”而言,似乎会返回每个副本的IP地址。
实际上,我指的是节点的ReadEndpoint…
$ dig my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com
...
;; ANSWER SECTION:
my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com. 15 IN CNAME my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com.
my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com. 15 IN A 10.0.40.53
$ dig my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com
...
;; ANSWER SECTION:
my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com. 1 IN CNAME my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com.
my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com. 11 IN A 10.0.40.31
让我们用 redis-cli 进行连接并进行确认。
# PrimaryEndpoint
$ redis-cli -h my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com
my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com:6379> set key1 value1
OK
my-redis-replication-group.dl12u5.ng.0001.apne1.cache.amazonaws.com:6379> get key1
"value1"
# ReaderEndpoint
$ redis-cli -h my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com
my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com:6379> set key2 value2
(error) READONLY You can't write against a read only replica.
my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com:6379> get key1
"value1"
# ノード単位のReadEndpoint
## Primary
$ redis-cli -h my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com
my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com:6379> set key2 value2
OK
my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com:6379> get key2
"value2"
## Replica
$ redis-cli -h my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com
my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com:6379> set key3 value3
(error) READONLY You can't write against a read only replica.
my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com:6379> get key1
"value1"
my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com:6379>
$ redis-cli -h my-redis-replication-group-003.dl12u5.0001.apne1.cache.amazonaws.com
my-redis-replication-group-003.dl12u5.0001.apne1.cache.amazonaws.com:6379> set key3 value3
(error) READONLY You can't write against a read only replica.
my-redis-replication-group-003.dl12u5.0001.apne1.cache.amazonaws.com:6379> get key1
"value1"
我也会查看复制的信息。
# PrimaryEndpoint
$ redis-cli -h my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.3.0.243,port=6379,state=online,offset=62865,lag=1
slave1:ip=10.3.2.218,port=6379,state=online,offset=62812,lag=1
master_replid:3acb819b47caa9b0b0d88a10565e5afd87707b75
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:62865
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:62865
# ReaderEndpoint
$ redis-cli -h my-redis-replication-group-ro.dl12u5.ng.0001.apne1.cache.amazonaws.com info replication
# Replication
role:slave
master_host:my-redis-replication-group.dl12u5.0001.internal.apne1.cache.amazonaws.com
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:65426
repl_sync_enabled:1
slave_read_reploff:65426
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:3acb819b47caa9b0b0d88a10565e5afd87707b75
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:65426
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1686
repl_backlog_histlen:63741
# ノード単位のReadEndpoint
## Primary
$ redis-cli -h my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.3.0.243,port=6379,state=online,offset=67496,lag=1
slave1:ip=10.3.2.218,port=6379,state=online,offset=67496,lag=1
master_replid:3acb819b47caa9b0b0d88a10565e5afd87707b75
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:67496
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:67496
## Replica
$ redis-cli -h my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com info replication
# Replication
role:slave
master_host:my-redis-replication-group.dl12u5.0001.internal.apne1.cache.amazonaws.com
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:68093
repl_sync_enabled:1
slave_read_reploff:68093
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:3acb819b47caa9b0b0d88a10565e5afd87707b75
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:68093
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1686
repl_backlog_histlen:66408
$ redis-cli -h my-redis-replication-group-003.dl12u5.0001.apne1.cache.amazonaws.com info replication
# Replication
role:slave
master_host:my-redis-replication-group.dl12u5.0001.internal.apne1.cache.amazonaws.com
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:68902
repl_sync_enabled:1
slave_read_reploff:68902
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:3acb819b47caa9b0b0d88a10565e5afd87707b75
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:68902
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1686
repl_backlog_histlen:67217
在这里,我们将尝试查找集群的ID。
$ aws elasticache describe-cache-clusters | \
jq '..|.CacheClusterId?'
null
"my-redis-replication-group-001"
null
null
null
"my-redis-replication-group-002"
null
null
null
"my-redis-replication-group-003"
有三个…。
让我们分别来看每个节点的终结点。
$ aws elasticache describe-cache-clusters \
--cache-cluster-id my-redis-replication-group-001 \
--show-cache-node-info | \
jq '..|.CacheNodes?'
null
[
{
"CacheNodeId": "0001",
"CacheNodeStatus": "available",
"CacheNodeCreateTime": "2020-08-14T15:03:02.292000+00:00",
"Endpoint": {
"Address": "my-redis-replication-group-001.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"ParameterGroupStatus": "in-sync",
"CustomerAvailabilityZone": "ap-northeast-1c"
}
]
$ aws elasticache describe-cache-clusters \
--cache-cluster-id my-redis-replication-group-002 \
--show-cache-node-info | \
jq '..|.CacheNodes?'
null
[
{
"CacheNodeId": "0001",
"CacheNodeStatus": "available",
"CacheNodeCreateTime": "2020-08-14T15:03:02.292000+00:00",
"Endpoint": {
"Address": "my-redis-replication-group-002.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"ParameterGroupStatus": "in-sync",
"CustomerAvailabilityZone": "ap-northeast-1c"
}
]
$ aws elasticache describe-cache-clusters \
--cache-cluster-id my-redis-replication-group-003 \
--show-cache-node-info | \
jq '..|.CacheNodes?'
null
[
{
"CacheNodeId": "0001",
"CacheNodeStatus": "available",
"CacheNodeCreateTime": "2020-08-14T15:03:02.292000+00:00",
"Endpoint": {
"Address": "my-redis-replication-group-003.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"ParameterGroupStatus": "in-sync",
"CustomerAvailabilityZone": "ap-northeast-1a"
}
]
就这个问题而言,与单节点时一样,节点级别的终端点指的是节点级别的读取终端点相同的值。
我明白了。
分片结构
最后是分片架构。
resource "aws_elasticache_replication_group" "redis" {
replication_group_description = "My ElastiCache for Redis Replication Group"
replication_group_id = "my-redis-replication-group"
engine = "redis"
engine_version = "5.0.6"
node_type = "cache.t3.medium"
port = 6379
parameter_group_name = aws_elasticache_parameter_group.redis_parameter_group.name
security_group_ids = [module.elasticache_for_redis_cluster_sg.this_security_group_id]
subnet_group_name = aws_elasticache_subnet_group.redis_subnet.name
automatic_failover_enabled = true
cluster_mode {
replicas_per_node_group = 2 # 2 Replica
num_node_groups = 3 # 3 Shard
}
}
resource "aws_elasticache_parameter_group" "redis_parameter_group" {
family = "redis5.0"
name = "my-elasticache-for-redis-parameter-group"
parameter {
name = "cluster-enabled"
value = "yes"
}
}
resource "aws_elasticache_subnet_group" "redis_subnet" {
name = "my-elasticache-for-redis-subnet-group"
subnet_ids = module.vpc.private_subnets
}
本次,将进行专门针对群集模式的设置。
cluster_mode {
replicas_per_node_group = 2 # 2 Replica
num_node_groups = 3 # 3 Shard
}
我们在3个分片中,每个分片内有2个副本的配置。
我们可以有总共9个节点。
另外,在参数组中,我明确地将cluster-enabled设置为yes。
resource "aws_elasticache_parameter_group" "redis_parameter_group" {
family = "redis5.0"
name = "my-elasticache-for-redis-parameter-group"
parameter {
name = "cluster-enabled"
value = "yes"
}
}
输出是这样的。
Outputs:
redis_elasticache_replication_group_configuration_endpoint_address = my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com
redis_elasticache_replication_group_member_clusters = [
"my-redis-replication-group-0001-001",
"my-redis-replication-group-0001-002",
"my-redis-replication-group-0001-003",
"my-redis-replication-group-0002-001",
"my-redis-replication-group-0002-002",
"my-redis-replication-group-0002-003",
"my-redis-replication-group-0003-001",
"my-redis-replication-group-0003-002",
"my-redis-replication-group-0003-003",
]
我有9个节点。
这次的配置端点地址发生了变化。相反地,主要端点地址已经消失了。
"outputs": {
"redis_elasticache_replication_group_configuration_endpoint_address": {
"value": "my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com",
"type": "string"
},
"redis_elasticache_replication_group_member_clusters": {
"value": [
"my-redis-replication-group-0001-001",
"my-redis-replication-group-0001-002",
"my-redis-replication-group-0001-003",
"my-redis-replication-group-0002-001",
"my-redis-replication-group-0002-002",
"my-redis-replication-group-0002-003",
"my-redis-replication-group-0003-001",
"my-redis-replication-group-0003-002",
"my-redis-replication-group-0003-003"
],
"type": [
"set",
"string"
]
}
},
我会通过AWS CLI进行查看。
$ aws elasticache describe-replication-groups \
--replication-group-id my-redis-replication-group | \
jq '..|.ConfigurationEndpoint?'
null
{
"Address": "my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com",
"Port": 6379
}
在本次配置中,将获得配置终端(ConfigurationEndpoint),而无法获取主要终端(PrimaryEndpoint)或读取终端(ReaderEndpoint)。
我们是否也应该查看节点的信息呢?
$ aws elasticache describe-replication-groups \
--replication-group-id my-redis-replication-group | \
jq '..|.NodeGroups?'
null
[
{
"NodeGroupId": "0001",
"Status": "available",
"Slots": "0-5461",
"NodeGroupMembers": [
{
"CacheClusterId": "my-redis-replication-group-0001-001",
"CacheNodeId": "0001",
"PreferredAvailabilityZone": "ap-northeast-1c"
},
{
"CacheClusterId": "my-redis-replication-group-0001-002",
"CacheNodeId": "0001",
"PreferredAvailabilityZone": "ap-northeast-1c"
},
{
"CacheClusterId": "my-redis-replication-group-0001-003",
"CacheNodeId": "0001",
"PreferredAvailabilityZone": "ap-northeast-1a"
}
]
},
{
"NodeGroupId": "0002",
"Status": "available",
"Slots": "5462-10922",
"NodeGroupMembers": [
{
"CacheClusterId": "my-redis-replication-group-0002-001",
"CacheNodeId": "0001",
"PreferredAvailabilityZone": "ap-northeast-1a"
},
{
"CacheClusterId": "my-redis-replication-group-0002-002",
"CacheNodeId": "0001",
"PreferredAvailabilityZone": "ap-northeast-1a"
},
{
"CacheClusterId": "my-redis-replication-group-0002-003",
"CacheNodeId": "0001",
"PreferredAvailabilityZone": "ap-northeast-1c"
}
]
},
{
"NodeGroupId": "0003",
"Status": "available",
"Slots": "10923-16383",
"NodeGroupMembers": [
{
"CacheClusterId": "my-redis-replication-group-0003-001",
"CacheNodeId": "0001",
"PreferredAvailabilityZone": "ap-northeast-1a"
},
{
"CacheClusterId": "my-redis-replication-group-0003-002",
"CacheNodeId": "0001",
"PreferredAvailabilityZone": "ap-northeast-1c"
},
{
"CacheClusterId": "my-redis-replication-group-0003-003",
"CacheNodeId": "0001",
"PreferredAvailabilityZone": "ap-northeast-1c"
}
]
}
]
他的Endpoint的信息,完全消失了吗…?
描述复制组/输出
ReadEndpoint -> (structure)
用于客户端程序连接到节点进行读取操作所需的信息。仅在禁用 Redis 集群模式的集群上适用读取端点。
确实,如果集群模式无效,就不会显示ReadEndpoint。
但是主要的终端点和阅读器终端点也消失了。
让我们使用dig来查看ConfigurationEndpoint。
$ dig my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com
...
;; ANSWER SECTION:
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com. 15 IN A 10.0.40.137
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com. 15 IN A 10.0.40.191
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com. 15 IN A 10.0.30.6
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com. 15 IN A 10.0.30.42
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com. 15 IN A 10.0.30.194
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com. 15 IN A 10.0.30.254
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com. 15 IN A 10.0.40.12
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com. 15 IN A 10.0.40.15
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com. 15 IN A 10.0.40.68
感觉好像在指着所有节点…。
让我们尝试使用redis-cli进行连接。
$ redis-cli -h my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com:6379> set key1 value1
(error) MOVED 9189 10.0.30.194:6379
当尝试登记数据时,发生了错误。
Redis 集群教程
玩聚类游戏
看起来它以Redis集群的方式运行,所以需要使用-c选项。
$ redis-cli -c -h my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com
my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com:6379> set key1 value1
-> Redirected to slot [9189] located at 10.0.30.194:6379
OK
10.0.30.194:6379> get key1
"value1"
10.0.30.194:6379> set key2 value2
-> Redirected to slot [4998] located at 10.0.40.15:6379
OK
10.0.40.15:6379> get key2
"value2"
10.0.40.15:6379> set key3 value3
OK
10.0.40.15:6379> get key3
"value3"
遵循重定向后,它成功运行了。
让我们查看一下集群的信息。
$ redis-cli -h my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com cluster nodes
89260a12e7bf9e0b9598c5897b51a0a2d7502939 10.0.30.6:6379@1122 myself,master - 0 1597420677000 0 connected 10923-16383
35547892f11e00fc59c940892d573fe03ac2788b 10.0.30.194:6379@1122 master - 0 1597420679000 3 connected 5462-10922
4e6acd4049362d8111c00a280625d207f0aac883 10.0.40.12:6379@1122 slave 89260a12e7bf9e0b9598c5897b51a0a2d7502939 0 1597420680967 0 connected
8a478b2499d0ac68ac78fbc40b286ca93354f401 10.0.30.254:6379@1122 slave 1b0582425b6597b194d8c334dc80af1dafa81d0a 0 1597420679000 1 connected
0a00719c18721972bcfd9f70edfc436ff8145a79 10.0.40.191:6379@1122 slave 35547892f11e00fc59c940892d573fe03ac2788b 0 1597420679000 3 connected
1b0582425b6597b194d8c334dc80af1dafa81d0a 10.0.40.15:6379@1122 master - 0 1597420681000 1 connected 0-5461
29dfadb6042b119bd11e03f8a76754a615709288 10.0.30.42:6379@1122 slave 35547892f11e00fc59c940892d573fe03ac2788b 0 1597420679000 3 connected
17196d689a040d3a03c89930065bd5d525b3760b 10.0.40.137:6379@1122 slave 89260a12e7bf9e0b9598c5897b51a0a2d7502939 0 1597420681000 0 connected
71279c2f1b7afed0cab5f8f1f1e9dc86f41fc702 10.0.40.68:6379@1122 slave 1b0582425b6597b194d8c334dc80af1dafa81d0a 0 1597420681970 1 connected
有三个主节点和六个从节点对吧。
顺便提一下,如果将复制的信息视为基准,就会变成这样。
$ redis-cli -h my-redis-replication-group.dl12u5.clustercfg.apne1.cache.amazonaws.com info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.3.2.215,port=6379,state=online,offset=54891,lag=0
slave1:ip=10.3.2.46,port=6379,state=online,offset=54824,lag=1
master_replid:87f1db07458e72bbfac1f59505a7fa20e0249acf
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:54891
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:54891
有两个从属服务器对吧,因为他们位于同一个分片内。
我来查看一下这个集群的ID。
$ aws elasticache describe-cache-clusters | \
jq '..|.CacheClusterId?'
null
"my-redis-replication-group-0001-001"
null
null
null
"my-redis-replication-group-0001-002"
null
null
null
"my-redis-replication-group-0001-003"
null
null
null
"my-redis-replication-group-0002-001"
null
null
null
"my-redis-replication-group-0002-002"
null
null
null
"my-redis-replication-group-0002-003"
null
null
null
"my-redis-replication-group-0003-001"
null
null
null
"my-redis-replication-group-0003-002"
null
null
null
"my-redis-replication-group-0003-003"
有九个呢…。
让我们也来挑选一些节点信息来看看。
$ aws elasticache describe-cache-clusters \
--cache-cluster-id my-redis-replication-group-0001-001 \
--show-cache-node-info | \
jq '..|.CacheNodes?'
null
[
{
"CacheNodeId": "0001",
"CacheNodeStatus": "available",
"CacheNodeCreateTime": "2020-08-14T15:49:54.669000+00:00",
"Endpoint": {
"Address": "my-redis-replication-group-0001-001.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"ParameterGroupStatus": "in-sync",
"CustomerAvailabilityZone": "ap-northeast-1c"
}
]
$ aws elasticache describe-cache-clusters \
--cache-cluster-id my-redis-replication-group-0001-002 \
--show-cache-node-info | \
jq '..|.CacheNodes?'
null
[
{
"CacheNodeId": "0001",
"CacheNodeStatus": "available",
"CacheNodeCreateTime": "2020-08-14T15:49:54.669000+00:00",
"Endpoint": {
"Address": "my-redis-replication-group-0001-002.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"ParameterGroupStatus": "in-sync",
"CustomerAvailabilityZone": "ap-northeast-1c"
}
]
$ aws elasticache describe-cache-clusters \
--cache-cluster-id my-redis-replication-group-0003-001 \
--show-cache-node-info | \
jq '..|.CacheNodes?'
null
[
{
"CacheNodeId": "0001",
"CacheNodeStatus": "available",
"CacheNodeCreateTime": "2020-08-14T15:49:54.669000+00:00",
"Endpoint": {
"Address": "my-redis-replication-group-0003-001.dl12u5.0001.apne1.cache.amazonaws.com",
"Port": 6379
},
"ParameterGroupStatus": "in-sync",
"CustomerAvailabilityZone": "ap-northeast-1a"
}
]
这样做,可以获取节点级别的终端。不过,在这种配置下,使用的是ConfigurationEndpoint,所以可能不会使用节点级别的终端信息吧。
暂时来说,我们已经确认了关于终端点的三种配置模式。
給予额外的奖品
这是已创建的Terraform配置文件的整体。
我們正在使用Terraform模組來處理Amazon VPC和安全群組。
分片配置、复制配置和独立配置是通过注释来切换的三种配置。
此外,我还利用自己的模块简便地在 EC2 上操作了 redis-cli(即我在最后一行提到的那个)。
主要.tf
terraform {
required_version = "0.13.0"
}
provider "aws" {
version = "3.2.0"
}
module "elasticache_for_redis_cluster_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "3.15.0"
name = "app-with-nginx-rp-service-sg"
vpc_id = module.vpc.vpc_id
ingress_with_cidr_blocks = [
{
from_port = 6379
to_port = 6379
protocol = "tcp"
description = "ElastiCache for Redis Cluster inbound ports"
cidr_blocks = "10.0.30.0/24"
},
{
from_port = 6379
to_port = 6379
protocol = "tcp"
description = "ElastiCache for Redis Cluster inbound ports"
cidr_blocks = "10.0.40.0/24"
}
]
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "2.47.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
azs = ["ap-northeast-1a", "ap-northeast-1c"]
public_subnets = ["10.0.10.0/24", "10.0.20.0/24"]
private_subnets = ["10.0.30.0/24", "10.0.40.0/24"]
map_public_ip_on_launch = true
enable_nat_gateway = true
single_nat_gateway = false
one_nat_gateway_per_az = true
}
# Cluster
resource "aws_elasticache_replication_group" "redis" {
replication_group_description = "My ElastiCache for Redis Replication Group"
replication_group_id = "my-redis-replication-group"
engine = "redis"
engine_version = "5.0.6"
node_type = "cache.t3.medium"
port = 6379
parameter_group_name = aws_elasticache_parameter_group.redis_parameter_group.name
security_group_ids = [module.elasticache_for_redis_cluster_sg.this_security_group_id]
subnet_group_name = aws_elasticache_subnet_group.redis_subnet.name
automatic_failover_enabled = true
cluster_mode {
replicas_per_node_group = 2 # 2 Replica
num_node_groups = 3 # 3 Shard
}
}
resource "aws_elasticache_parameter_group" "redis_parameter_group" {
family = "redis5.0"
name = "my-elasticache-for-redis-parameter-group"
parameter {
name = "cluster-enabled"
value = "yes"
}
}
# Replication
/*
resource "aws_elasticache_replication_group" "redis" {
replication_group_description = "My ElastiCache for Redis Replication Group"
replication_group_id = "my-redis-replication-group"
engine = "redis"
engine_version = "5.0.6"
node_type = "cache.t3.medium"
port = 6379
parameter_group_name = aws_elasticache_parameter_group.redis_parameter_group.name
security_group_ids = [module.elasticache_for_redis_cluster_sg.this_security_group_id]
subnet_group_name = aws_elasticache_subnet_group.redis_subnet.name
automatic_failover_enabled = true
number_cache_clusters = 3 # Primary : Replica = 1 : 2
}
resource "aws_elasticache_parameter_group" "redis_parameter_group" {
family = "redis5.0"
name = "my-elasticache-for-redis-parameter-group"
parameter {
name = "cluster-enabled"
value = "no"
}
}
*/
# Single Node
/*
resource "aws_elasticache_replication_group" "redis" {
replication_group_description = "My ElastiCache for Redis Replication Group"
replication_group_id = "my-redis-replication-group"
engine = "redis"
engine_version = "5.0.6"
node_type = "cache.t3.medium"
port = 6379
parameter_group_name = aws_elasticache_parameter_group.redis_parameter_group.name
security_group_ids = [module.elasticache_for_redis_cluster_sg.this_security_group_id]
subnet_group_name = aws_elasticache_subnet_group.redis_subnet.name
automatic_failover_enabled = false
number_cache_clusters = 1 # Primary Only
}
resource "aws_elasticache_parameter_group" "redis_parameter_group" {
family = "redis5.0"
name = "my-elasticache-for-redis-parameter-group"
parameter {
name = "cluster-enabled"
value = "no"
}
}
*/
resource "aws_elasticache_subnet_group" "redis_subnet" {
name = "my-elasticache-for-redis-subnet-group"
subnet_ids = module.vpc.private_subnets
}
output "redis_elasticache_replication_group_primary_endpoint_address" {
value = aws_elasticache_replication_group.redis.primary_endpoint_address
}
output "redis_elasticache_replication_group_configuration_endpoint_address" {
value = aws_elasticache_replication_group.redis.configuration_endpoint_address
}
output "redis_elasticache_replication_group_member_clusters" {
value = aws_elasticache_replication_group.redis.member_clusters
}
module "client_instance" {
source = "github.com/charon-r13b/ssh-key-less-ec2-instance"
vpc_id = module.vpc.vpc_id
subnet_id = module.vpc.private_subnets[0]
module_creation_iam_role_name = "MyElastiCacheSshKeyLessEc2Role"
module_creation_iam_instance_profile_name = "MyElastiCacheSshKeyLessEc2InstanceProfile"
}