我們來確認一下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 集群(启用集群模式)。

只需一种选项即可:在以下内容中理解即可。

構成シャード数プライマリノード数レプリカノード数クラスターモードシングルノード構成110無効レプリケーション構成11N(1〜5)無効シャーディング構成S(1〜90)SS × N(0〜5)有効

作为参考,您可以参考这些文档。

使用复制组以实现高可用性。

关于 Redis 复制的问题

Redis在非集群模式和集群模式下的复制功能比较。

这些都被称为”群集”,而且每种模式都有一个以上的分片。

原本的Redis数据存储集群(Redis Cluster)这个术语,仅指分片配置情况。

Redis集群教程

呃,有点复杂…。

亚马逊ElastiCache for Redis的连接终端

这次的讨论是关于选择哪种配置,从而改变使用的终节点。

顺便说一下,”エンドポイント” 是指

    • アドレス

 

    ポート

似乎是由…组成的。

看到以下的文件,似乎可以分为四种类型的终端点。

搜索连接终点

在Redis中查找(不启用集群模式)集群终端点(控制台)。

Redis(启用集群模式)在集群中搜索端点(控制台)。

    • (ノード単位の)Endpoint

 

    • PrimaryEndpoint

 

    • ReaderEndpoint

 

    ConfigurationEndpoint

用法大概就是这样的。

エンドポイントの種類意味用途使う構成クラスターモード(ノード単位の)EndpointRedisノード単位のエンドポイントRedisノードにアクセスするために使う(読み書き含む)シングルノード構成無効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"
}
广告
将在 10 秒后关闭
bannerAds