

# 设置 DAX 集群的容量
<a name="dax-cluster-sizing"></a>

DAX 集群的总容量和可用性取决于节点类型和数量。集群中的节点越多，其读取容量就会增加，但写入容量不会增加。较大的节点类型（最大 r5.8xlarge）可以处理更多写入请求，但是当节点发生故障时，节点太少可能会影响可用性。有关设置 DAX 集群容量的更多信息，请参阅[DAX 集群大小调整指南](DAX.sizing-guide.md)。

以下各节讨论了不同的容量设置问题，在为创建可扩展且具成本效益的集群以平衡节点类型和数量时应考虑这些方面。

**Topics**
+ [规划可用性](#dax-sizing-availability)
+ [规划写入吞吐量](#dax-sizing-write-throughput)
+ [规划读取吞吐量](#dax-sizing-read-throughput)
+ [规划数据集大小](#dax-sizing-dataset-size)
+ [计算大致的集群容量需求](#dax-sizing-cluster-capacity)
+ [按节点类型估算集群吞吐能力](#dax-sizing-cluster-throughput-capacity)
+ [扩展 DAX 集群中的写入容量](#dax-sizing-scaling-write-capacity)

## 规划可用性
<a name="dax-sizing-availability"></a>

在调整 DAX 集群容量时，应首先关注其目标可用性。集群服务（如 DAX）的可用性是集群中节点总数的一个维度。由于单节点集群无法容忍故障，因此其可用性等于一个节点。在 10 节点集群中，丢失一个节点对集群总体容量的影响微乎其微。这种损失不会对可用性产生直接影响，因为剩余的节点仍然可以完成读取请求。为了恢复写入，DAX 会快速提名一个新的主节点。

DAX 基于 VPC。它使用子网组来确定可以在哪些[可用区](https://www.amazonaws.cn/about-aws/global-infrastructure/regions_az/)运行节点，以及可以使用子网中的哪些 IP 地址。对于生产工作负载，强烈建议您使用在不同可用区至少具有三个节点的 DAX。这将确保即使单个节点或可用区出现故障，集群仍有多个节点可以处理请求。一个集群最多可以有 11 个节点，其中一个是主节点，10 个是只读副本。

## 规划写入吞吐量
<a name="dax-sizing-write-throughput"></a>

所有 DAX 集群都有一个用于处理直写请求的主节点。集群节点类型的大小决定其写入容量。添加额外的只读副本不会增加集群的写入容量。因此，在创建集群时应考虑写入容量，因为以后无法更改节点类型。

如果您的应用程序需要通过 DAX 直写来更新项目缓存，请考虑增加集群资源使用量以简化写入操作。针对 DAX 的写入消耗的资源大约是缓存命中读取的 25 倍。这可能需要比只读集群更大的节点类型。

有关确定是直写还是绕写更适合您的应用程序的更多指导，请参阅[针对写入的策略](DAX.consistency.md#DAX.consistency.strategies-for-writes)。

## 规划读取吞吐量
<a name="dax-sizing-read-throughput"></a>

DAX 集群的读取容量取决于工作负载的缓存命中率。由于 DAX 在发生缓存未命中时从 DynamoDB 读取数据，因此它消耗的集群资源大约是缓存命中时的 10 倍。要增加缓存命中率，请增加缓存的 [TTL](dax-config-considerations.md#select-ttl-duration-caches) 设置以定义项目存储在缓存中的时间段。但是，除非更新是通过 DAX 写入的，否则较长的 TTL 持续时间会增加读取较旧项目版本的机会。

要确保集群有足够的读取容量，请按[横向扩展集群](dax-cluster-operations.md#dax-cluster-horizontal-scaling)中所述横向扩展集群。添加更多节点会将只读副本添加到资源池中，而移除节点会降低读取容量。在为集群选择节点数量及其大小时，请同时考虑所需的最小和最大读取容量。如果您无法通过横向扩展具有较小节点类型的集群来满足您的读取要求，请使用更大的节点类型。

## 规划数据集大小
<a name="dax-sizing-dataset-size"></a>

每种可用节点类型都有一组内存大小，以供 DAX 缓存数据。如果节点类型太小，则应用程序请求的工作数据集将无法存储在内存中，从而导致缓存不命中。由于较大的节点支持较大的缓存，因此请使用大于需要缓存的估计数据集的节点类型。更大的缓存也会提高缓存命中率。

对于重复读取次数很少的缓存项目，可能会获得越来越少返回。计算经常访问的项目的内存大小，并确保缓存足够大，足以存储该数据集。

## 计算大致的集群容量需求
<a name="dax-sizing-cluster-capacity"></a>

您可以估计工作负载的总容量需求，以帮助您选择适当大小和数量的集群节点。要进行此估计，请计算变量：*每秒标准化请求*（标准化 RPS）。此变量表示您的应用程序需要 DAX 集群提供支持的总工作单元，包括缓存命中率、缓存未命中率和写入次数。要计算标准化 RPS，请使用以下输入：
+ `ReadRPS_CacheHit` – 指定导致缓存命中的每秒读取次数。
+ `ReadRPS_CacheMiss` – 指定导致缓存未命中的每秒读取次数。
+ `WriteRPS` – 指定将通过 DAX 的每秒写入次数。
+ `DaxNodeCount` – 指定 DAX 集群中的节点数。
+ `Size` – 指定正在写入或读取的项目的大小，以 KB 为单位，向上舍入到最接近的 KB。
+ `10x_ReadMissFactor` – 表示值为 10。当出现缓存未命中时，DAX 使用的资源大约是缓存命中时的 10 倍。
+ `25x_WriteFactor` – 表示值为 25，因为 DAX 直写占用的资源大约是缓存命中的 25 倍。

可以使用以下公式计算标准化 RPS。

```
Normalized RPS = (ReadRPS_CacheHit * Size) + (ReadRPS_CacheMiss * Size * 10x_ReadMissFactor) + (WriteRequestRate * 25x_WriteFactor * Size * DaxNodeCount)
```

例如，考虑以下输入值：
+ `ReadRPS_CacheHit` = 50,000
+ `ReadRPS_CacheMiss` = 1,000
+ `ReadMissFactor` = 1
+ `Size` = 2 KB
+ `WriteRPS` = 100
+ `WriteFactor` = 1
+ `DaxNodeCount` = 3

通过在公式中替换这些值，可以按如下方式计算标准化 RPS。

```
Normalized RPS = (50,000 Cache Hits/Sec * 2KB) + (1,000 Cache Misses/Sec * 2KB * 10) + (100 Writes/Sec * 25 * 2KB * 3)
```

在此示例中，计算得到的标准化 RPS 的值为 135,000。但是，这个标准化 RPS 值并没有考虑将集群利用率保持在 100% 以下或节点丢失因素。建议您考虑额外容量。为此，请确定两个乘法因子中较大的一个：目标利用率或节点丢失容忍度。然后，将标准化 RPS 乘以更大的因子，即可获得*每秒的目标请求数*（目标 RPS）。
+ **目标利用率**

  由于性能影响会增加缓存未命中率，因此不建议以 100% 的利用率运行 DAX 集群。理想情况下，应将集群利用率保持在 70% 或以下。为此，请将标准化 RPS 乘以 1.43。
+ **节点丢失容忍度**

  如果某个节点出现故障，您的应用程序必须能够在其余节点之间分配其请求。要确保节点的利用率保持在 100% 以下，请选择足够大的节点类型以吸收额外流量，直到出现故障的节点恢复在线状态。对于节点较少的集群，当一个节点出现故障时，其他节点必须能够容忍更大的流量增长。

  如果主节点发生故障，DAX 会将故障自动转移到一个只读副本并指定该副本作为新的主节点。如果副本节点发生故障，DAX 集群中的其他节点仍能够处理请求，直到发生故障的节点恢复为止。

  例如，出现节点故障的 3 节点 DAX 集群需要在剩下的两个节点上增加 50% 的容量。这需要乘法因子为 1.5。相反，出现节点故障的 11 节点集群需要在其余节点上增加 10% 的容量或乘以因子 1.1。

可以使用以下公式计算目标 RPS。

```
Target RPS = Normalized RPS * CEILING(TargetUtilization, NodeLossTolerance)
```

例如，要计算目标 RPS，请考虑以下值：
+ `Normalized RPS` = 135,000
+ `TargetUtilization` = 1.43

  由于我们的目标是使最大集群利用率达到 70%，因此将 `TargetUtilization` 设置为 1.43。
+ `NodeLossTolerance` = 1.5

  假设我们使用的是 3 节点集群，则将 `NodeLossTolerance` 设置为 50% 容量。

通过在公式中替换这些值，可以按如下方式计算目标 RPS。

```
Target RPS = 135,000 * CEILING(1.43, 1.5)
```

在此示例中，由于 `NodeLossTolerance` 的值大于 `TargetUtilization`，因此我们使用 `NodeLossTolerance` 计算目标 RPS 的值。这使我们的目标 RPS 为 202,500，这是 DAX 集群必须支持的总容量。要确定集群中需要的节点数，请将 Target RPS 映射到[下表](#dax-sizing-cluster-throughput-capacity)中的相应列。在这个目标 RPS 为 202,500 的示例中，您需要具有三个节点的 dax.r5.large 节点类型。

## 按节点类型估算集群吞吐能力
<a name="dax-sizing-cluster-throughput-capacity"></a>

使用 [Target RPS formula](#Target-RPS-formula)，您可以估算不同节点类型的集群容量。下表显示了节点类型为 1、3、5 和 11 的集群的大致容量。这些容量并不能取代使用您自己的数据和请求模式对 DAX 执行负载测试的需求。此外，这些容量不包括 [t-type](DAX.Burstable.md) 实例，因为它们缺少固定的 CPU 容量。下表中所有值的单位均为标准化 RPS。


| 节点类型（内存） | 1 个节点 | 3 个节点 | 5 个节点 | 11 个节点 | 
| --- | --- | --- | --- | --- | 
| dax.r5.24xlarge（768GB） | 1M | 3M | 5M | 11M | 
| dax.r5.16xlarge（512GB） | 1M | 3M | 5M | 11M | 
| dax.r5.12xlarge（384GB） | 1M | 3M | 5M | 11M | 
| dax.r5.8xlarge（256GB） | 1M | 3M | 5M | 11M | 
| dax.r5.4xlarge（128GB） | 600k | 1.8M | 3M | 6.6M | 
| dax.r5.2xlarge（64GB） | 300K | 900k | 1.5M | 3.3M | 
| dax.r5.xlarge（32GB） | 150k | 450k | 750k | 1.65M | 
| dax.r5.large（16GB） | 75K | 225k | 375k | 825k | 

由于每个节点的最大限制为 100 万 NPS（每秒网络操作数），因此 dax.r5.8xlarge 或更大的节点类型不会提供额外的集群容量。大于 8xlarge 的节点类型可能不会影响集群的总吞吐能力。但是，此类节点类型有助于在内存中存储更大的工作数据集。

## 扩展 DAX 集群中的写入容量
<a name="dax-sizing-scaling-write-capacity"></a>

每次写入 DAX 会在每个节点上消耗 25 个标准化请求。由于每个节点的 RPS 限制为 100 万，因此 DAX 集群限制为每秒 40,000 次写入，不考虑读取量。

如果您的用例需要在缓存中每秒写入超过 40,000 次，则必须使用单独的 DAX 集群并在其中对写入进行分片。与 DynamoDB 类似，您可以对正在写入缓存的数据的分区键进行哈希处理。然后，使用模数来确定要将数据写入哪个分片。

以下示例计算输入字符串的哈希值。然后用 10 计算哈希值的模数。

```
def hash_modulo(input_string):
    # Compute the hash of the input string
    hash_value = hash(input_string)

    # Compute the modulus of the hash value with 10
    bucket_number = hash_value % 10

    return bucket_number

#Example usage
if _name_ == "_main_":
    input_string = input("Enter a string: ")
    result = hash_modulo(input_string)
    print(f"The hash modulo 10 of '{input_string}' is: {result}.")
```