

# DynamoDB 吞吐能力
<a name="capacity-mode"></a>

本节概述可用于 DynamoDB 表的两种吞吐量模式，以及为应用程序选择合适的容量模式时的注意事项。表的吞吐量模式决定了如何管理表的容量。吞吐量模式还决定了对表的读取和写入操作进行收费的方式。在 Amazon DynamoDB 中，您可以为表选择**按需**模式和**预置**模式，来适应不同的工作负载要求。

**Topics**
+ [

## 按需模式
](#capacity-mode-on-demand)
+ [

## 预置模式
](#capacity-mode-provisioned)
+ [

# DynamoDB 按需容量模式
](on-demand-capacity-mode.md)
+ [

# DynamoDB 预置容量模式
](provisioned-capacity-mode.md)
+ [

# 了解 DynamoDB 热吞吐量
](warm-throughput.md)
+ [

# DynamoDB 容量暴增和自适应容量
](burst-adaptive-capacity.md)
+ [

# 在 DynamoDB 中切换容量模式时的注意事项
](bp-switching-capacity-modes.md)

## 按需模式
<a name="capacity-mode-on-demand"></a>

Amazon DynamoDB 按需模式是一种无服务器吞吐量选项，可简化数据库管理并自动扩展，以支持客户的要求极为苛刻的应用程序。DynamoDB 按需使您能够创建表，而无需担心容量规划、监控使用情况和配置扩展策略等事宜。DynamoDB 按需模式针对读取和写入请求提供按请求支付定价，您只需为使用的资源付费。对于按需模式表，您无需指定预期应用程序执行的读写吞吐量。

按需模式是大多数 DynamoDB 工作负载的默认吞吐量选项，也是建议采用的吞吐量选项。DynamoDB 处理吞吐量管理和扩展的所有各个方面，以支持可以从小规模开始并扩展到每秒数百万个请求的工作负载。您可以根据需要对 DynamoDB 表进行读取和写入，而无需管理表上的吞吐能力。有关更多信息，请参阅 [DynamoDB 按需容量模式](on-demand-capacity-mode.md)。

## 预置模式
<a name="capacity-mode-provisioned"></a>

在预置模式下，必须为应用程序指定所需的每秒读取和写入次数。系统将根据您已预置的每小时读取和写入容量向您收费，而不是根据您实际消耗的预置容量向您收费。这可帮助您控制您对 DynamoDB 的使用，使之保持或低于定义的请求速率，以便获得成本可预测性。

如果您的工作负载稳定且增长可预测，并且您可以可靠地预测应用程序的容量需求，则可以选择使用预置容量。有关更多信息，请参阅 [DynamoDB 预置容量模式](provisioned-capacity-mode.md)。

# DynamoDB 按需容量模式
<a name="on-demand-capacity-mode"></a>

Amazon DynamoDB 按需可提供真正的无服务器数据库体验，可以自动扩展以适应要求极为苛刻的工作负载，而无需进行容量规划。按需可简化设置过程，消除容量管理和监控，并提供快速、自动的扩展。使用按请求付费的定价，您不必担心闲置的容量，因为您只需为您实际使用的吞吐量付费。将按读取或写入请求向您收费，因此您的费用直接反映了您的实际使用量。

在选择按需模式时，DynamoDB 会随着工作负载的增加或减少，根据之前达到的任意流量水平即时调节工作负载。如果工作负载的流量级别达到新的峰值，DynamoDB 将自动扩展以适应增加的吞吐量需求。按需模式是默认和建议采用的吞吐量选项，因为它简化了构建现代无服务器应用程序的过程，这些应用程序可以从小规模起步，然后扩展到每秒数百万个请求。横向扩展按需表后，将来可以立即实现同样的吞吐量，而不会受到节流。如果您的表流量为零，那么在按需模式下，您无需为任何吞吐量付费。有关按需模式的扩展属性的更多信息，请参阅[初始吞吐量和扩展属性](#on-demand-capacity-mode-initial)。

使用按需模式的表可提供 DynamoDB 预置模式所提供的相同个位数毫秒级延迟、服务水平协议（SLA）和安全性。

**注意**  
默认情况下，DynamoDB 可防止您的用量出现意外、失控的状况。要扩展以超越账户中所有表的 40000 个表级读取和写入吞吐量限制，您可以申请提高此配额。超过默认表吞吐量配额的吞吐量请求将受到限制。有关更多信息，请参阅 [吞吐量默认限额](ServiceQuotas.md#default-limits-throughput)。

而且，您还可以选择为各个按需表和全局二级索引配置每秒最大读取和/或写入吞吐量。通过配置吞吐量，可以限制表级使用量和成本，防止消耗的资源意外激增，同时防止过度使用，从而实现可预测的成本管理。超过最大表吞吐量的吞吐量请求会受到节流。您可以根据应用程序的要求，随时修改表特定的最大吞吐量。有关更多信息，请参阅 [DynamoDB 按需表的最大吞吐量](on-demand-capacity-mode-max-throughput.md)。

要开始使用，请创建或更新表来使用按需模式。有关更多信息，请参阅 [针对 DynamoDB 表的基本操作](WorkingWithTables.Basics.md)。

在 24 小时滚动窗口内，表最多可以从预置容量模式切换到按需模式四次。您可以随时将表从按需模式切换到预置容量模式。

有关在读取和写入容量模式之间切换的更多信息，请参阅[在 DynamoDB 中切换容量模式时的注意事项](bp-switching-capacity-modes.md)。有关按需表配额，请参阅[读/写吞吐量](ServiceQuotas.md#default-limits-throughput-capacity-modes)。

**Topics**
+ [

## 读取请求单位和写入请求单位
](#read-write-request-units)
+ [

## 初始吞吐量和扩展属性
](#on-demand-capacity-mode-initial)
+ [

# DynamoDB 按需表的最大吞吐量
](on-demand-capacity-mode-max-throughput.md)

## 读取请求单位和写入请求单位
<a name="read-write-request-units"></a>

DynamoDB 按照*读取请求单位*和*写入请求单位*，对应用程序在表上执行的读取和写入操作收费。

一个*读取请求单位*表示对大小最多为 4 KB 的项目每秒执行一次强一致性读取操作，或每秒执行两次最终一致性读取操作。有关 DynamoDB 读取一致性模型的更多信息，请参阅[DynamoDB 读取一致性](HowItWorks.ReadConsistency.md)。

一个*写入请求单位*表示对大小最多为 1 KB 的项目每秒执行一次写入操作。

有关如何使用读取和写入单位的更多信息，请参阅[DynamoDB 读取和写入操作](read-write-operations.md)。

## 初始吞吐量和扩展属性
<a name="on-demand-capacity-mode-initial"></a>

使用按需容量模式的 DynamoDB 表会自动适应应用程序的流量。新的按需表将能够保持多达每秒 4000 次写入和每秒 12000 次读取。按需容量模式会即时在表中承受之前双倍的峰值流量。例如，假设应用程序的流量模式在每秒 25000 到 50000 次强一致性读取之间变化，那么先前流量峰值就是每秒 50000 次读取。按需容量模式可即时容纳最高每秒 10 万次读取的持续流量。如果您的应用程序保持每秒 10 万次读取的流量，则该峰值将成为新的先前峰值。这个先前峰值使后续流量可高达每秒 20 万次读取。

如果工作负载在表上产生的流量是先前峰值的两倍以上，DynamoDB 会随着流量的增加自动分配更多容量。这种容量分配有助于确保您的工作负载不会受到节流。但是，如果您在 30 分钟内超出先前峰值的两倍，则可能发生限制。例如，假设应用程序的流量模式在每秒 25000 到 50000 次强一致性读取之间变化，那么先前流量峰值就是每秒 50000 次读取。我们建议您在每秒读取量超过 10 万次之前，先对表进行预热或将流量增长的间隔设置为至少 30 分钟。有关预热的更多信息，请参阅[了解 DynamoDB 热吞吐量](warm-throughput.md)。

如果您的工作负载的峰值流量保持在之前峰值的两倍以内，DynamoDB 将不会设置 30 分钟的节流限制。如果峰值流量超过之前峰值的两倍，请确保这种增长发生在您上次达到峰值后 30 分钟内。

# DynamoDB 按需表的最大吞吐量
<a name="on-demand-capacity-mode-max-throughput"></a>

对于按需表，您可以选择指定单个表和关联全局二级索引（GSI）每秒的最大读取和/或写入吞吐量。指定最大按需吞吐量有助于限制表级用量和成本。默认情况下，最大吞吐量设置不适用，按需吞吐率受账户中所有表的 40000 个表级读写吞吐量 [AWS 服务配额](ServiceQuotas.md#default-limits-throughput)的限制。如果需要，您可以请求增加服务配额。

为按需表配置最大吞吐量时，超过指定最大吞吐量的吞吐量请求将受到节流。您可以根据应用程序要求，随时修改表级吞吐量设置。

在以下的一些常见使用案例中，对按需表使用最大吞吐量可以获得好处：
+ **吞吐量成本优化** – 对按需表使用最大吞吐量，可提供额外的一层成本可预测性和可管理性。此外，它还带来了更大的灵活性，能够通过使用按需模式来支持具有不同流量模式和预算的工作负载。
+ **防止过度使用** – 通过设置最大吞吐量，您可以防止对于按需表的读取或写入消耗量意外激增，这可能是由于未优化的代码或恶意进程造成的。这个表级设置可以防止组织在一定时间范围内消耗过多的资源。
+ **保护下游服务** - 客户应用程序可以包括无服务器和非无服务器技术。架构中的无服务器部分可以快速扩展来匹配需求。但具有固定容量的下游组件可能会不堪重负。为按需表实施最大吞吐量设置，可以防止大量事件传播到多个下游组件而产生意想不到的副作用。

您可以为新的和现有的单区域表、全局表和 GSI 配置按需模式的最大吞吐量。您还可以在表还原和从 Amazon S3 工作流程导入数据期间配置最大吞吐量。

您可以使用 [DynamoDB 控制台](https://console.aws.amazon.com/dynamodb/)、[AWS CLI](AccessingDynamoDB.md#Tools.CLI)、[AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html) 或 [DynamoDB API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/Welcome.html) 为按需表指定最大吞吐量设置。

**注意**  
按需表的最大吞吐量是在尽最大努力的基础上应用的，应被视为目标而不是保证的请求上限。由于[*容量爆增*](burst-adaptive-capacity.md#burst-capacity)，您的工作负载可能会暂时超过指定的最大吞吐量。在某些情况下，DynamoDB 使用*容量爆增*来容纳超出表的最大吞吐量设置的读取或写入。利用容量暴增，意外的读取或写入请求可在原本会受限制的环境中获得成功。

**Topics**
+ [

## 对按需模式使用最大吞吐量时的注意事项
](#consideration-use-max-throughput-ondemand)
+ [

## 请求节流和 CloudWatch 指标
](#max-throughput-ondemand-request-throttle)

## 对按需模式使用最大吞吐量时的注意事项
<a name="consideration-use-max-throughput-ondemand"></a>

在按需模式下对表使用最大吞吐量时，需要考虑以下注意事项：
+ 您可以为任何按需表或该表中的单个全局二级索引单独设置最大读写吞吐量，以便根据特定的要求来微调方法。
+ 您可以使用 Amazon CloudWatch 来监控和了解 DynamoDB 表级用量指标，并为按需模式确定适当的最大吞吐量设置。有关更多信息，请参阅 [DynamoDB 指标与维度](metrics-dimensions.md)。
+ 当您在一个全局表副本上指定最大读取和/或写入吞吐量设置时，相同的最大吞吐量设置将自动应用于所有副本表。全局表中的副本表和二级索引务必具有相同的写入吞吐量设置，以确保正确复制数据。有关更多信息，请参阅 [全局表的最佳实践](globaltables-bestpractices.md)。
+ 您可以指定的最大读取或写入吞吐量的最小值为每秒一个请求单位。
+ 您指定的最大吞吐量必须低于任何按需表或该表中单个全局二级索引可用的默认吞吐量配额。

## 请求节流和 CloudWatch 指标
<a name="max-throughput-ondemand-request-throttle"></a>

如果应用程序超过了您在按需表上设置的最大读取或写入吞吐量，DynamoDB 就会开始节流这些请求。当 DynamoDB 限制读取或写入时，它会将 `ThrottlingException` 返回给调用方。然后，您可以根据需要采取适当的措施。例如，您可以增加或禁用最大表吞吐量设置，或者等待一小段时间后再重试请求。

为了更易于监控为表或全局二级索引配置的最大吞吐量，CloudWatch 提供了以下指标：[OnDemandMaxReadRequestUnits](metrics-dimensions.md#OnDemandMaxReadRequestUnits) 和 [OnDemandMaxWriteRequestUnits](metrics-dimensions.md#OnDemandMaxWriteRequestUnits)。

# DynamoDB 预置容量模式
<a name="provisioned-capacity-mode"></a>

在 DynamoDB 中创建新的预置表时，您必须指定其*预置的吞吐能力*。这是表可以支持的读写吞吐量。系统将根据您已预置的每小时读取和写入容量向您收费，而不是根据您实际消耗的预置容量向您收费。

随着应用程序的数据和访问要求发生变化，您可能需要调整表的吞吐量设置。您可以使用自动扩缩根据流量变化自动调整表的预置容量。DynamoDB 自动扩缩在 [Application Auto Scaling](https://docs.aws.amazon.com/autoscaling/application/userguide/what-is-application-auto-scaling.html) 中使用[扩缩策略](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-target-tracking.html)。要在 DynamoDB 中配置自动扩缩，除了目标利用率百分比外，还需要设置读取和写入容量的最低和最高级别。Application Auto Scaling 创建和管理当指标偏离目标时触发扩缩事件的 CloudWatch 警报。自动扩缩会监控表的活动，并根据预配置的阈值向上或向下调整其容量设置。当所使用的容量在两个连续的一分钟时段内均超过配置的目标利用率时，就会触发自动扩缩。在触发自动扩缩之前，CloudWatch 警报可能会有至多几分钟的短暂延迟。有关更多信息，请参阅 [使用 DynamoDB Auto Scaling 自动管理吞吐能力](AutoScaling.md)。

如果您使用 DynamoDB Auto Scaling，则吞吐量设置将自动调整以响应实际工作负载。您也可以使用 [UpdateTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTable.html) 操作来手动调整表的吞吐能力。例如，如果您需要将现有数据存储中的数据批量加载到新的 DynamoDB 表中，则可能会决定执行此操作。您可以使用较大的写入吞吐量设置创建表，然后在批量加载完数据后减小此设置。

**注意**  
默认情况下，DynamoDB 可防止您的用量出现意外、失控的状况。要扩展以超越账户中所有表的 40000 个表级读取和写入吞吐量限制，您可以申请提高此配额。超过默认表吞吐量配额的吞吐量请求将受到限制。有关更多信息，请参阅 [吞吐量默认限额](ServiceQuotas.md#default-limits-throughput)。

在 24 小时滚动窗口内，表最多可以从预置容量模式切换到按需模式四次。您可以随时将表从按需模式切换到预置容量模式。

有关在读取和写入容量模式之间切换的更多信息，请参阅[在 DynamoDB 中切换容量模式时的注意事项](bp-switching-capacity-modes.md)。

**Topics**
+ [

## 读取容量单位和写入容量单位
](#read-write-capacity-units)
+ [

## 选择初始吞吐量设置
](#choosing-initial-throughput)
+ [

## DynamoDB Auto Scaling
](#ddb-autoscaling)
+ [

# 使用 DynamoDB Auto Scaling 自动管理吞吐能力
](AutoScaling.md)
+ [

# DynamoDB 预留容量
](reserved-capacity.md)

## 读取容量单位和写入容量单位
<a name="read-write-capacity-units"></a>

对于预置模式表，您可以按*容量单位*指定吞吐量要求。这些单位表示您的应用程序每秒需要读取或写入的数据量。您可以稍后修改这些设置（如果需要）或启用 DynamoDB Auto Scaling 以自动修改这些设置。

对于最大为 4 KB 的项目，一个*读取容量单位*（RCU）表示每秒执行一次强一致性读取操作，或每秒执行两次最终一致性读取操作。有关 DynamoDB 读取一致性模型的更多信息，请参阅[DynamoDB 读取一致性](HowItWorks.ReadConsistency.md)。

一个*写入容量单位*（WCU）表示对最大为 1 KB 的项目每秒执行一次写入操作。有关不同读取和写入操作的更多信息，请参阅[DynamoDB 读取和写入操作](read-write-operations.md)。

## 选择初始吞吐量设置
<a name="choosing-initial-throughput"></a>

每个应用程序对从数据库中读取和写入数据库有着不同的要求。在确定 DynamoDB 表的初始吞吐量设置时，请考虑以下事项：
+ **预期的读取和写入请求速率** - 您应该估计每秒需要执行的读取和写入次数。
+ **项目大小** - 一些项目足够小，可使用单个容量单位进行读取或写入。较大的项目需要多个容量单位。通过估计表中将包含的项目的平均大小，您可以为表的预调配吞吐量指定准确的设置。
+ **读取一致性要求** - 读取容量单位基于强一致性读取操作，这些操作消耗的数据库资源是最终一致性读取的两倍。您应确定您的应用程序是否需要强一致性读取，或者是否能放宽此要求并改为执行最终一致性读取操作。默认情况下，DynamoDB 中的读取操作是最终一致性读取。如有必要，您可以为这些操作请求强一致性读取。

例如，假设您希望从表中每秒读取 80 个项目。这些项目的大小为 3 KB，而且您需要强一致性读取。在这种情况下，每次读取需要一个预置读取容量单位。为确定此数字，请将此操作的项目大小除以 4 KB。然后，向上舍入到最近的整数，如下面的示例所示：
+ 3 KB/4 KB = 0.75，或者 **1** 个读取容量单位

因此，要从表中每秒读取 80 个项目，请将表的预置读取吞吐量设置为 80 个读取容量单位，如以下示例所示：
+ 每个项目 1 个读取容量单位 x 每秒 80 次读取 = **80** 个读取容量单位

现在假设您希望每秒向您的表写入 100 个项目，并且每个项目的大小为 512 个字节。在这种情况下，每次写入需要一个预置写入容量单位。为确定此数字，请将此操作的项目大小除以 1 KB。然后，向上舍入到最近的整数，如下面的示例所示：
+ 512 个字节/1 KB = 0.5 或 **1** 个写入容量单位

要每秒向表写入 100 个项目，请将表的预置写入吞吐量设置为 100 个写入容量单位：
+ 每个项目 1 个写入容量单位 x 每秒 100 次写入 = **100** 个写入容量单位

## DynamoDB Auto Scaling
<a name="ddb-autoscaling"></a>

DynamoDB 自动扩缩主动管理表和全局二级索引的预置吞吐能力。使用自动扩缩功能，您可以为读取和写入容量单位定义一个范围（上限和下限）。您还可以定义该范围内的目标利用率百分比。DynamoDB Auto Scaling 旨在维持目标利用率，即使在应用程序工作负载增加或减少的情况下也是如此。

利用 DynamoDB Auto Scaling，表或全局二级索引可以增加其预置读写容量，以处理突增流量，而不限制请求。当工作负载减少时，DynamoDB Auto Scaling 可以减少吞吐量，这样您就无需为未使用的预置容量付费。

**注意**  
如果您使用 AWS 管理控制台 创建表或全局二级索引，默认情况下将启用 DynamoDB Auto Scaling。  
您可以随时使用控制台、AWS CLI 或其中一个 AWS SDK 管理自动扩缩设置。有关更多信息，请参阅 [使用 DynamoDB Auto Scaling 自动管理吞吐能力](AutoScaling.md)。

### 利用率
<a name="ddb-autoscaling-utilization-rate"></a>

利用率有助于您确定是否过度预置容量，如果存在过度预置，应减少表容量来节省成本。反过来，它也有助于您确定预置容量是否不足。在这种情况下，您应该增加表容量，防止在意外的高流量期间可能出现请求节流。有关更多信息，请参阅 [Amazon DynamoDB auto scaling: Performance and cost optimization at any scale](https://aws.amazon.com/blogs/database/amazon-dynamodb-auto-scaling-performance-and-cost-optimization-at-any-scale/)。

如果您使用 DynamoDB 自动扩缩，则还需要设置目标利用率百分比。自动扩缩将使用此百分比作为向上或向下调整容量的目标。我们建议将目标利用率设置为 70%。有关更多信息，请参阅 [使用 DynamoDB Auto Scaling 自动管理吞吐能力](AutoScaling.md)。

# 使用 DynamoDB Auto Scaling 自动管理吞吐能力
<a name="AutoScaling"></a>

许多数据库工作负载本质上是周期性的，而另一些则难以提前进行预测。例如，考虑一个大多数用户在白天处于活跃状态的社交网络应用程序。数据库必须能够处理白天活动，但夜间不需要相同级别的吞吐量。而在另一个例子中，请考虑正在经历用户快速增长的新移动游戏应用程序。如果此游戏变得太受欢迎，它可能会超出可用的数据库资源，从而导致性能降低并使客户感到不满。这些类型的工作负载通常需要手动干预来扩展或缩减数据库资源，以便响应不断变化的使用量级别。

Amazon DynamoDB Auto Scaling 使用 AWS Application Auto Scaling 服务代表您动态调整预置的吞吐容量，以响应实际的流量模式。这使表或全局二级索引（GSI）能够增大其预置的读取和写入容量来处理突发的流量增加，而不会发生节流。当工作负载减少时，Application Auto Scaling 可以减少吞吐量，这样您就无需为未使用的预置容量付费。

**注意**  
如果您使用 AWS 管理控制台 创建表或全局二级索引，默认情况下将启用 DynamoDB Auto Scaling。您可以随时修改 Auto Scaling 设置。有关更多信息，请参阅 [通过 AWS 管理控制台使用 DynamoDB 自动扩缩](AutoScaling.Console.md)。  
删除表或全局表副本时，任何关联的可扩展目标、扩缩策略或 CloudWatch 告警都不会随之自动删除。

使用 Application Auto Scaling，您可以创建为表或全局二级索引*扩展策略*。扩展策略指定是要扩展读取容量还是写入容量（或二者同时扩展），并为表或索引指定最小的和最大的预置容量单位设置。

扩展策略还包含*目标使用率*，某个时间点已使用的预调配吞吐量的百分比。Application Auto Scaling 使用*目标跟踪*算法来向上或向下调整表（或索引）的预调配吞吐量以响应实际工作负载，从而使实际容量使用率达到或接近您的目标使用率。

DynamoDB 输出在一分钟时段内所使用的预调配吞吐量。当所使用的容量在两个连续的一分钟时段内均超过配置的目标利用率时，就会触发自动扩缩。在触发自动扩缩之前，CloudWatch 警报可能会有至多几分钟的短暂延迟。这一延迟可确保准确评估 CloudWatch 指标。如果已使用的吞吐量峰值间隔超过一分钟，则可能不会触发自动扩缩。同样，当 15 个连续的数据点低于目标利用率时，则可能发生缩减事件。无论是哪种情况，在自动扩缩触发之后，都会调用 [UpdateTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTable.html) API。然后，需要几分钟的时间才能更新表或索引的预置容量。在此期间，任何超过表的先前预置容量的请求都会被节流。

**重要**  
您无法调整要超过的数据点数量来触发底层警报（尽管当前的数值将来可能会发生变化）。

 您可以为读取和写入容量设置介于 20% 和 90% 之间的 Auto Scaling 目标利用率值。

**注意**  
除了表之外，DynamoDB Auto Scaling 还支持全局二级索引。每个全局二级索引均有各自的预置的吞吐容量，这独立于其基表的吞吐容量。在为全局二级索引创建扩展策略时，Application Auto Scaling 将调整索引的预调配吞吐量设置，确保其实际使用量达到或接近所需的使用率。

## DynamoDB Auto Scaling 的工作原理
<a name="AutoScaling.HowItWorks"></a>

**注意**  
要快速开始使用 DynamoDB Auto Scaling，请参阅 [通过 AWS 管理控制台使用 DynamoDB 自动扩缩](AutoScaling.Console.md)。

下图简要概述了 DynamoDB Auto Scaling 管理表的吞吐能力的方式。

![\[DynamoDB Auto Scaling 会调整表的吞吐能力以满足需求。\]](http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/images/auto-scaling.png)


以下步骤汇总了上图中所示的 Auto Scaling 流程：

1. 为 DynamoDB 表创建 Application Auto Scaling 策略。

1. DynamoDB 会将使用的容量指标发布到 Amazon CloudWatch。

1. 如果表使用的容量在特定时段内超出目标使用率 (或低于目标使用率)，则 Amazon CloudWatch 将触发警报。您可以在控制台上查看警报并使用 Amazon Simple Notification Service (Amazon SNS) 接收通知。

1. CloudWatch 警报调用 Application Auto Scaling 来评估扩展策略。

1. Application Auto Scaling 发出 `UpdateTable` 请求以调整表的预调配吞吐量。

1. DynamoDB 处理 `UpdateTable` 请求，并动态增加（或减少）表的预置的吞吐容量，使它接近目标使用率。

为了解 DynamoDB Auto Scaling 的工作方式，假定您有一个名为 `ProductCatalog` 的表。由于很少将数据批量加载到表中，因此不会出现大量写入活动。不过，表会遇到大量的读取活动，此活动随时间的推移而变化。通过监控 `ProductCatalog` 的 Amazon CloudWatch 指标，您确定表需要 1200 个读取容量单位（避免在活动到达峰值时出现 DynamoDB 限制读取请求的情况）。您还确定，在读取流量达到其最低值时，`ProductCatalog` 至少需要 150 个读取容量单位。有关防止限制的更多信息，请参阅[Amazon DynamoDB 中的节流故障排除](TroubleshootingThrottling.md)。

在 150 到 1200 个读取容量单位的范围内，您确定 70% 的目标使用率将适合 `ProductCatalog` 表。*目标利用率*是使用的容量单位与预置容量单位的比率（以百分比表示）。应用 Application Auto Scaling 使用其目标跟踪算法来确保 `ProductCatalog` 会根据需要进行调整，使利用率保持在 70% 或接近 70%。

**注意**  
仅当实际工作负载在几分钟的持续时段内保持提高或降低时，DynamoDB Auto Scaling 才会修改预调配吞吐量设置。Application Auto Scaling 目标跟踪算法寻求使目标使用率长期达到或接近选定值。  
表的内置容量暴增将容纳活动的短时间突增峰值。有关更多信息，请参阅 [容量爆增](burst-adaptive-capacity.md#burst-capacity)。

要为 `ProductCatalog` 表启用 DynamoDB Auto Scaling，请创建扩展策略。此策略指定以下内容：
+ 要管理的表或全局二级索引
+ 要管理的容量类型（读取容量或写入容量）
+ 预配置吞吐量设置的上限和下限
+ 您的目标利用率

创建扩展策略时，Application Auto Scaling 将代表您创建一对 Amazon CloudWatch 警报。每对警报均指明预调配吞吐量设置的上限和下限。当表的实际使用率在一段持续时间内偏离目标使用率时，将触发这些 CloudWatch 警报。

当触发某个 CloudWatch 警报时，Amazon SNS 将向您发送通知（如果您已启用通知）。随后，CloudWatch 警报将调用 Application Auto Scaling，后者随之通知 DynamoDB 视情况向上或向下调整 `ProductCatalog` 表的预配置容量。

在扩展事件发生期间，AWS Config 按记录的配置项目进行收费。发生扩展事件时，会为每个读取和写入自动扩缩事件创建四个 CloudWatch 警报，即两个 ProvisionedCapacity 警报（ProvisionedCapacityLow、ProvisionedCapacityHigh）和两个 ConsumedCapacity 警报（AlarmHigh、AlarmLow）。这会导致总共创建八个警报。因此，AWS Config 为每个扩展事件记录八个配置项目。

**注意**  
您还可以安排 DynamoDB 扩展，使其在特定时间进行。点击[此处](https://docs.aws.amazon.com/autoscaling/application/userguide/get-started-exercise.html)了解基本步骤。

## 使用说明
<a name="AutoScaling.UsageNotes"></a>

在开始使用 DynamoDB Auto Scaling 之前，您应了解以下内容：
+ DynamoDB Auto Scaling 会根据您的自动扩缩策略增加读取容量或写入容量任意次数。所有 DynamoDB 配额都将保持有效，如 [Amazon DynamoDB 中的配额](ServiceQuotas.md) 中所述。
+ DynamoDB Auto Scaling 不会阻止您手动修改预置的吞吐量设置。这些手动调整不会影响与 DynamoDB Auto Scaling 相关的任何现有 CloudWatch 警报。
+ 如果您为包含一个或多个全局二级索引的表启用 DynamoDB Auto Scaling，强烈建议您也对这些索引统一应用自动扩缩。这将有助于确保更好的表写入和读取性能，并帮助避免节流。您可以在 AWS 管理控制台 中选择**将相同设置应用到全局二级索引**来启用自动扩缩。有关更多信息，请参阅 [在现有表上启用 DynamoDB 自动扩缩](AutoScaling.Console.md#AutoScaling.Console.ExistingTable)。
+ 删除表或全局表副本时，任何关联的可扩展目标、扩缩策略或 CloudWatch 告警都不会随之自动删除。
+ 为现有表创建 GSI 时，系统不会为 GSI 启用自动扩缩。在构建 GSI 时，您必须手动管理容量。GSI 上的回填完成并到达活动状态后，自动扩缩操作将正常运行。

# 通过 AWS 管理控制台使用 DynamoDB 自动扩缩
<a name="AutoScaling.Console"></a>

如果您使用 AWS 管理控制台 创建表或，默认情况下将启用 Amazon DynamoDB 自动扩缩。您还可以使用控制台为现有表启用自动扩缩、修改自动扩缩设置或禁用自动扩缩。

**注意**  
 对于设置缩减和扩展冷却时间等更高级的功能，请使用 AWS Command Line Interface (AWS CLI) 通过编程方式管理 DynamoDB 自动扩缩。有关更多信息，请参阅 [使用 AWS CLI 管理 DynamoDB 自动扩缩](AutoScaling.CLI.md)。

**Topics**
+ [

## 开始之前：向用户授予 DynamoDB 自动扩缩的权限
](#AutoScaling.Permissions)
+ [

## 创建启用了自动扩缩的新表
](#AutoScaling.Console.NewTable)
+ [

## 在现有表上启用 DynamoDB 自动扩缩
](#AutoScaling.Console.ExistingTable)
+ [

## 在控制台上查看自动扩缩活动
](#AutoScaling.Console.ViewingActivities)
+ [

## 修改或禁用 DynamoDB 自动扩缩设置
](#AutoScaling.Console.Modifying)

## 开始之前：向用户授予 DynamoDB 自动扩缩的权限
<a name="AutoScaling.Permissions"></a>

在 AWS Identity and Access Management（IAM）中，AWS 托管策略 `DynamoDBFullAccess` 提供使用 DynamoDB 控制台所需的权限。但是，对于 DynamoDB 自动扩缩，用户需要额外的权限。

**重要**  
 要删除启用自动扩缩的表，需要 `application-autoscaling:*` 权限。AWS 托管策略 `DynamoDBFullAccess` 包含此类权限。

要设置用户来执行 DynamoDB 控制台访问和 DynamoDB 自动扩缩操作，请创建一个角色并向该角色添加 **AmazonDynamoDBFullAccess** 策略。然后，将该角色分配给用户。

## 创建启用了自动扩缩的新表
<a name="AutoScaling.Console.NewTable"></a>

**注意**  
DynamoDB Auto Scaling 功能需要存在一个代表您执行自动扩缩操作的服务相关角色（`AWSServiceRoleForApplicationAutoScaling_DynamoDBTable`）。将自动为您创建此角色。有关更多信息，请参阅《应用程序自动扩缩用户指南》**中的[实现应用程序自动扩缩的服务相关角色](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html)。

**创建启用了自动扩缩的新表**

1. 打开 DynamoDB 控制台：[https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)。

1. 选择**创建表**。

1. 在**创建表**页面上，输入**表名称**和主键详细信息。

1. 如果您选择**默认设置**，则会在新表中启用自动扩缩。

   否则，请选择**自定义设置**，并执行以下操作来指定表的自定义设置：

   1. 对于**表类**，请保留默认选择 **DynamoDB 标准**。

   1. 对于**读/写容量设置**，请保留默认选择**已预置**，然后执行以下操作：

      1. 对于**读取容量**，请确保将**自动扩缩**设置为**开启**。

      1. 对于**写入容量**，请确保将**自动扩缩**设置为**开启**。

      1. 对于**读取容量**和**写入容量**，请为表以及表的所有全局二级索引（可选）设置所需的扩展策略。
         + **最小容量单位** – 输入自动扩缩范围的下限。
         + **最大容量单位** – 输入自动扩缩范围的上限。
         + **目标利用率** - 输入表的目标利用率百分比。
**注意**  
如果为新表创建全局二级索引，则该索引在创建时的容量将与基表的容量相同。创建表后，您可以在表的设置中更改索引的容量。

1. 选择**创建表**。这会使用您指定的自动扩缩参数创建表。

## 在现有表上启用 DynamoDB 自动扩缩
<a name="AutoScaling.Console.ExistingTable"></a>

**注意**  
DynamoDB 自动扩缩功能需要存在一个代表您执行自动扩缩操作的服务相关角色（`AWSServiceRoleForApplicationAutoScaling_DynamoDBTable`）。将自动为您创建此角色。有关更多信息，请参阅 [Application Auto Scaling 的服务相关角色](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html)。

**为现有表启用 DynamoDB 自动扩缩**

1. 打开 DynamoDB 控制台：[https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)。

1. 在控制台左侧的导航窗格中，选择**表**。

1. 选择您要启用自动扩缩的表，然后执行以下操作：

   1. 选择**其他设置**选项卡。

   1. 在**读/写容量**部分中，选择**编辑**。

   1. 在**容量模式**部分中，选择**预调配**。

   1. 在**表容量**部分，对于**读取容量**和/或**写入容量**，将**自动扩缩**设置为**开启**。对于其中每一个，请为表以及表的所有全局二级索引（可选）设置所需的扩展策略。
      + **最小容量单位** – 输入自动扩缩范围的下限。
      + **最大容量单位** – 输入自动扩缩范围的上限。
      + **目标利用率** - 输入表的目标利用率百分比。
      + **将相同的读/写容量设置应用于所有全局二级索引** – 选择全局二级索引是否应使用与基表相同的自动扩缩策略。
**注意**  
为获得最佳性能，建议您启用**将相同的读/写容量设置应用于所有全局二级索引**。此选项允许 DynamoDB 自动扩缩均匀扩展表上的所有全局二级索引。这包括现有的全局二级索引，以及您将来为此表创建的任何其他索引。  
启用此选项后，您无法对单个全局二级索引设置扩展策略。

1. 根据需要进行设置后，选择 **Save (保存)**。

## 在控制台上查看自动扩缩活动
<a name="AutoScaling.Console.ViewingActivities"></a>

当您的应用程序驱动对表进行读取和写入流量时，DynamoDB 自动扩缩功能会动态修改表的吞吐量设置。Amazon CloudWatch 会跟踪所有 DynamoDB 表和二级索引的预配置和使用的容量、受限事件、延迟以及其他指标。

要在 DynamoDB 控制台中查看这些指标，请选择要处理的表，然后选择**监控**选项卡。要创建表指标的可自定义视图，请选择 **View all in CloudWatch (在 CloudWatch 中查看全部)**。

## 修改或禁用 DynamoDB 自动扩缩设置
<a name="AutoScaling.Console.Modifying"></a>

您可以使用 AWS 管理控制台 修改 DynamoDB 自动扩缩设置。要执行此操作，请转至表的**其他设置**选项卡，然后选择**读/写容量**部分中的**编辑**。有关这些设置的更多信息，请参阅 [在现有表上启用 DynamoDB 自动扩缩](#AutoScaling.Console.ExistingTable)。

# 使用 AWS CLI 管理 DynamoDB 自动扩缩
<a name="AutoScaling.CLI"></a>

您可以不再使用 AWS 管理控制台，而改为使用 AWS Command Line Interface（AWS CLI）来管理 Amazon DynamoDB 自动扩缩。本部分中的教程演示如何安装和配置 AWS CLI 来管理 DynamoDB 自动扩缩。在本教程中，您将执行以下操作：
+ 创建 DynamoDB 表 `TestTable`。初始吞吐量设置为 5 个读取容量单位和 5 个写入容量单位。
+ 为 `TestTable` 创建 Application Auto Scaling 策略。该策略旨在将消耗的写入容量和预置的写入容量之间的比例维持在 50% 这一目标值。此指标的范围是 5 到 10 个写入容量单位。（不允许 Application Auto Scaling 调整超出此范围的吞吐量。）
+ 运行 Python 程序以将写入流量驱动到 `TestTable`。当目标比率在持续时间内超过 50% 时，Application Auto Scaling 会通知 DynamoDB 调整 `TestTable` 以维持 50% 的目标利用率。
+ 验证 DynamoDB 是否已成功调整了 `TestTable` 的预置写入容量。

**注意**  
您还可以安排 DynamoDB 扩展，使其在特定时间进行。点击[此处](https://docs.aws.amazon.com/autoscaling/application/userguide/get-started-exercise.html)了解基本步骤。

**Topics**
+ [

## 开始前的准备工作
](#AutoScaling.CLI.BeforeYouBegin)
+ [

## 步骤 1：创建 DynamoDB 表
](#AutoScaling.CLI.CreateTable)
+ [

## 第 2 步：注册一个可扩展目标
](#AutoScaling.CLI.RegisterScalableTarget)
+ [

## 第 3 步：创建一个扩展策略
](#AutoScaling.CLI.CreateScalingPolicy)
+ [

## 第 4 步：将写入流量路由到 TestTable
](#AutoScaling.CLI.DriveTraffic)
+ [

## 第 5 步：查看 Application Auto Scaling 操作
](#AutoScaling.CLI.ViewCWAlarms)
+ [

## （可选）第 6 步：清除
](#AutoScaling.CLI.CleanUp)

## 开始前的准备工作
<a name="AutoScaling.CLI.BeforeYouBegin"></a>

开始教程前前，请完成以下任务：

### 安装 AWS CLI
<a name="AutoScaling.CLI.BeforeYouBegin.InstallCLI"></a>

如果您尚未安装和配置 AWS CLI，则必须先执行此操作。为此，请按照 *AWS Command Line Interface 用户指南*中的这些指示操作：
+ [安装 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/installing.html)
+ [配置 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)

### 安装 Python
<a name="AutoScaling.CLI.BeforeYouBegin.InstallPython"></a>

本教程的一部分要求您运行 Python 程序（请参阅 [第 4 步：将写入流量路由到 TestTable](#AutoScaling.CLI.DriveTraffic)）。如果还没有安装，可以[下载 Python](https://www.python.org/downloads)。

## 步骤 1：创建 DynamoDB 表
<a name="AutoScaling.CLI.CreateTable"></a>

在此步骤中，您将使用 AWS CLI 创建一个 `TestTable`。主键包含 `pk`（分区键）和 `sk`（排序键）。这两个属性的类型为 `Number`。初始吞吐量设置为 5 个读取容量单位和 5 个写入容量单位。

1. 输入以下 AWS CLI 命令以创建表。

   ```
   aws dynamodb create-table \
       --table-name TestTable \
       --attribute-definitions \
           AttributeName=pk,AttributeType=N \
           AttributeName=sk,AttributeType=N \
       --key-schema \
           AttributeName=pk,KeyType=HASH \
           AttributeName=sk,KeyType=RANGE \
       --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5
   ```

1. 要查看表的状态，请使用以下命令。

   ```
   aws dynamodb describe-table \
       --table-name TestTable \
       --query "Table.[TableName,TableStatus,ProvisionedThroughput]"
   ```

   当状态为 `ACTIVE` 时，表已可供使用。

## 第 2 步：注册一个可扩展目标
<a name="AutoScaling.CLI.RegisterScalableTarget"></a>

接下来，将将表的写入容量注册为使 Application Auto Scaling 的可扩展目标。这允许 Application Auto Scaling 调整 *TestTable*，但仅在 5—10 个容量单位的范围内。

**注意**  
DynamoDB 自动扩缩功能需要存在一个代表您执行自动扩缩操作的服务相关角色（`AWSServiceRoleForApplicationAutoScaling_DynamoDBTable`）。将自动为您创建此角色。有关更多信息，请参阅《Application Auto Scaling 用户指南》**中的 [Service-linked roles for Application Auto Scaling](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html)。

1. 输入下面的命令注册可扩展目标。

   ```
   aws application-autoscaling register-scalable-target \
       --service-namespace dynamodb \
       --resource-id "table/TestTable" \
       --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
       --min-capacity 5 \
       --max-capacity 10
   ```

1. 要检验注册，使用下面的命令。

   ```
   aws application-autoscaling describe-scalable-targets \
       --service-namespace dynamodb \
       --resource-id "table/TestTable"
   ```
**注意**  
 您还可以针对全局二级索引注册可扩展目标。例如，对于全局二级索引（“test index”），资源 ID 和可扩展维度参数都会相应地更新。  

   ```
   aws application-autoscaling register-scalable-target \
       --service-namespace dynamodb \
       --resource-id "table/TestTable/index/test-index" \
       --scalable-dimension "dynamodb:index:WriteCapacityUnits" \
       --min-capacity 5 \
       --max-capacity 10
   ```

## 第 3 步：创建一个扩展策略
<a name="AutoScaling.CLI.CreateScalingPolicy"></a>

在此步骤中，您将为 `TestTable` 创建扩展政策。该策略定义 Application Auto Scaling 调整表的预调配吞吐量的详细信息，调整表的预调配吞吐量，以及调整表的预调配吞吐量。将此策略与您上一步定义的可扩展目标（`TestTable` 表的写入容量单位）相关联。

该策略包含以下元素：
+ `PredefinedMetricSpecification`-允许应 Application Auto Scaling 调整的指标。对于 DynamoDB，以下值是 `PredefinedMetricType` 的有效值
  + `DynamoDBReadCapacityUtilization`
  + `DynamoDBWriteCapacityUtilization`
+ `ScaleOutCooldown`-增加预调配吞吐量的每个 Application Auto Scaling 事件之间的最短时间（以秒为单位）。此参数允许应 Application Auto Scaling 不断增加吞吐量，以响应实际工作负载。`ScaleOutCooldown` 的默认设置为 0。
+ `ScaleInCooldown`-减少预配置吞吐量的每个 Application Auto Scaling 事件之间的最短时间（以秒为单位）。此参数允许 Application Auto Scaling 逐步和可预测地降低吞吐量。`ScaleInCooldown` 的默认设置为 0。
+ `TargetValue`—Application Auto Scaling 可确保消耗的容量与预置容量的比例保持在该值或接近该值。您将 `TargetValue` 定义为百分比。

**注意**  
为了进一步了解 `TargetValue` 的工作原理，假设您的表的预配置吞吐量设置为 200 个写入容量单位。您决定为此表创建扩展策略，并使用 `TargetValue` 的 70%。  
现在假设您开始将写入流量驱动到表，以便实际写入吞吐量为 150 个容量单位。占用预置比现在为 (150/200)，即 75%。此比率超出了您的目标值，因此 Application Auto Scaling 会将预置写入容量增加到 215，使该比率为（150/215）或 69.77% – 尽可能接近 `TargetValue`，但不超过。

对于 `TestTable`，您可以设置 `TargetValue` 增加 50%。Application Auto Scaling 在 5-10 个容量单位范围内调整表的预调配吞吐量（请参阅 [第 2 步：注册一个可扩展目标](#AutoScaling.CLI.RegisterScalableTarget)），以便使消耗/预置比例保持或接近 50%。您可以将 `ScaleOutCooldown` 和 `ScaleInCooldown` 值设置为 60 秒。

1. 使用以下内容创建名为 `scaling-policy.json` 的文件。

   ```
   {
       "PredefinedMetricSpecification": {
           "PredefinedMetricType": "DynamoDBWriteCapacityUtilization"
       },
       "ScaleOutCooldown": 60,
       "ScaleInCooldown": 60,
       "TargetValue": 50.0
   }
   ```

1. 使用以下 AWS CLI 命令创建策略：

   ```
   aws application-autoscaling put-scaling-policy \
       --service-namespace dynamodb \
       --resource-id "table/TestTable" \
       --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
       --policy-name "MyScalingPolicy" \
       --policy-type "TargetTrackingScaling" \
       --target-tracking-scaling-policy-configuration file://scaling-policy.json
   ```

1. 在输出中，请注意，Application Auto Scaling 已创建两个 Amazon CloudWatch 警报，分别针对扩展目标范围的上限和下限。

1. 请使用以下 AWS CLI 命令查看有关扩展策略的更多详细信息。

   ```
   aws application-autoscaling describe-scaling-policies \
       --service-namespace dynamodb \
       --resource-id "table/TestTable" \
       --policy-name "MyScalingPolicy"
   ```

1. 在输出中，验证策略设置是否符合 [第 2 步：注册一个可扩展目标](#AutoScaling.CLI.RegisterScalableTarget) 和 [第 3 步：创建一个扩展策略](#AutoScaling.CLI.CreateScalingPolicy) 规范。

## 第 4 步：将写入流量路由到 TestTable
<a name="AutoScaling.CLI.DriveTraffic"></a>

现在，可以将数据写入到 `TestTable` 测试扩展策略。要执行此操作，请运行 Python 程序。

1. 使用以下内容创建名为 `bulk-load-test-table.py` 的文件。

   ```
   import boto3
   dynamodb = boto3.resource('dynamodb')
   
   table = dynamodb.Table("TestTable")
   
   filler = "x" * 100000
   
   i = 0
   while (i < 10):
       j = 0
       while (j < 10):
           print (i, j)
           
           table.put_item(
               Item={
                   'pk':i,
                   'sk':j,
                   'filler':{"S":filler}
               }
           )
           j += 1
       i += 1
   ```

1. 要运行该程序，请输入以下命令。

   `python bulk-load-test-table.py`

   预置写入容量 `TestTable` 非常低（5 个写入容量单位），因此程序偶尔会因写入限制而停顿。这是预料之中的行为。

   让程序继续运行，同时继续下一步。

## 第 5 步：查看 Application Auto Scaling 操作
<a name="AutoScaling.CLI.ViewCWAlarms"></a>

 在此步骤中，您可查看代表您启动的 Application Auto Scaling 操作。您还可以验证 Application Auto Scaling 已更新 `TestTable` 的预置写入容量。

1. 输入以下命令以查看 Application Auto Scaling 操作。

   ```
   aws application-autoscaling describe-scaling-activities \
       --service-namespace dynamodb
   ```

   在 Python 程序运行时偶尔重新运行此命令。（调用扩展策略之前需要几分钟。） 最终应看到如下输出。

   ```
   ...
   {
       "ScalableDimension": "dynamodb:table:WriteCapacityUnits", 
       "Description": "Setting write capacity units to 10.", 
       "ResourceId": "table/TestTable", 
       "ActivityId": "0cc6fb03-2a7c-4b51-b67f-217224c6b656", 
       "StartTime": 1489088210.175, 
       "ServiceNamespace": "dynamodb", 
       "EndTime": 1489088246.85, 
       "Cause": "monitor alarm AutoScaling-table/TestTable-AlarmHigh-1bb3c8db-1b97-4353-baf1-4def76f4e1b9 in state ALARM triggered policy MyScalingPolicy", 
       "StatusMessage": "Successfully set write capacity units to 10. Change successfully fulfilled by dynamodb.", 
       "StatusCode": "Successful"
   }, 
   ...
   ```

   这表示 Application Auto Scaling 已将 `UpdateTable` 请求发送给 DynamoDB。

1. 输入以下命令以验证 DynamoDB 是否增加了表的写入容量。

   ```
   aws dynamodb describe-table \
       --table-name TestTable \
       --query "Table.[TableName,TableStatus,ProvisionedThroughput]"
   ```

   `WriteCapacityUnits` 应该从 `5` 扩展到 `10`。

## （可选）第 6 步：清除
<a name="AutoScaling.CLI.CleanUp"></a>

在本教程中，您创建了多个资源。如果您不再需要这些资源，就可以删除它们了。

1. 删除 `TestTable` 的扩展策略。

   ```
   aws application-autoscaling delete-scaling-policy \
       --service-namespace dynamodb \
       --resource-id "table/TestTable" \
       --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
       --policy-name "MyScalingPolicy"
   ```

1. 取消注册可扩展目标。

   ```
   aws application-autoscaling deregister-scalable-target \
       --service-namespace dynamodb \
       --resource-id "table/TestTable" \
       --scalable-dimension "dynamodb:table:WriteCapacityUnits"
   ```

1. 删除 `TestTable` 表。

   ```
   aws dynamodb delete-table --table-name TestTable
   ```

# 使用 AWS SDK 为 Amazon DynamoDB 表配置自动扩缩功能
<a name="AutoScaling.HowTo.SDK"></a>

除了使用 AWS 管理控制台 和 AWS Command Line Interface (AWS CLI) 之外，还可以编写与 Amazon DynamoDB Auto Scaling 交互的应用程序。本节包含两个可用于测试此功能的 Java 程序：
+ `EnableDynamoDBAutoscaling.java`
+ `DisableDynamoDBAutoscaling.java`

## 为表启用 Application Auto Scaling
<a name="AutoScaling.HowTo.SDK-enable"></a>

以下程序显示了为 DynamoDB 表 (`TestTable`) 设置自动扩缩策略的示例。其操作过程如下所示：
+ 程序将写入容量单位注册为 `TestTable` 的可扩展目标。此指标的范围是 5 到 10 个写入容量单位。
+ 创建可扩展目标后，程序将构建目标跟踪配置。该策略旨在将消耗的写入容量和预置的写入容量之间的比例维持在 50% 这一目标值。
+ 然后，程序基于目标跟踪配置创建缩放策略。

**注意**  
手动删除表或全局表副本时，不会自动删除任何关联的可扩展目标、扩缩策略或 CloudWatch 告警。

------
#### [ Java v2 ]

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.applicationautoscaling.ApplicationAutoScalingClient;
import software.amazon.awssdk.services.applicationautoscaling.model.ApplicationAutoScalingException;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalableTargetsRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalableTargetsResponse;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalingPoliciesRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalingPoliciesResponse;
import software.amazon.awssdk.services.applicationautoscaling.model.PolicyType;
import software.amazon.awssdk.services.applicationautoscaling.model.PredefinedMetricSpecification;
import software.amazon.awssdk.services.applicationautoscaling.model.PutScalingPolicyRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.RegisterScalableTargetRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.ScalingPolicy;
import software.amazon.awssdk.services.applicationautoscaling.model.ServiceNamespace;
import software.amazon.awssdk.services.applicationautoscaling.model.ScalableDimension;
import software.amazon.awssdk.services.applicationautoscaling.model.MetricType;
import software.amazon.awssdk.services.applicationautoscaling.model.TargetTrackingScalingPolicyConfiguration;
import java.util.List;

/**
 * Before running this Java V2 code example, set up your development environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class EnableDynamoDBAutoscaling {
    public static void main(String[] args) {
        final String usage = """

            Usage:
               <tableId> <roleARN> <policyName>\s

            Where:
               tableId - The table Id value (for example, table/Music).
               roleARN - The ARN of the role that has ApplicationAutoScaling permissions.
               policyName - The name of the policy to create.
               
            """;

        if (args.length != 3) {
            System.out.println(usage);
            System.exit(1);
        }

        System.out.println("This example registers an Amazon DynamoDB table, which is the resource to scale.");
        String tableId = args[0];
        String roleARN = args[1];
        String policyName = args[2];
        ServiceNamespace ns = ServiceNamespace.DYNAMODB;
        ScalableDimension tableWCUs = ScalableDimension.DYNAMODB_TABLE_WRITE_CAPACITY_UNITS;
        ApplicationAutoScalingClient appAutoScalingClient = ApplicationAutoScalingClient.builder()
            .region(Region.US_EAST_1)
            .build();

        registerScalableTarget(appAutoScalingClient, tableId, roleARN, ns, tableWCUs);
        verifyTarget(appAutoScalingClient, tableId, ns, tableWCUs);
        configureScalingPolicy(appAutoScalingClient, tableId, ns, tableWCUs, policyName);
    }

    public static void registerScalableTarget(ApplicationAutoScalingClient appAutoScalingClient, String tableId, String roleARN, ServiceNamespace ns, ScalableDimension tableWCUs) {
        try {
            RegisterScalableTargetRequest targetRequest = RegisterScalableTargetRequest.builder()
                .serviceNamespace(ns)
                .scalableDimension(tableWCUs)
                .resourceId(tableId)
                .roleARN(roleARN)
                .minCapacity(5)
                .maxCapacity(10)
                .build();

            appAutoScalingClient.registerScalableTarget(targetRequest);
            System.out.println("You have registered " + tableId);

        } catch (ApplicationAutoScalingException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
        }
    }

    // Verify that the target was created.
    public static void verifyTarget(ApplicationAutoScalingClient appAutoScalingClient, String tableId, ServiceNamespace ns, ScalableDimension tableWCUs) {
        DescribeScalableTargetsRequest dscRequest = DescribeScalableTargetsRequest.builder()
            .scalableDimension(tableWCUs)
            .serviceNamespace(ns)
            .resourceIds(tableId)
            .build();

        DescribeScalableTargetsResponse response = appAutoScalingClient.describeScalableTargets(dscRequest);
        System.out.println("DescribeScalableTargets result: ");
        System.out.println(response);
    }

    // Configure a scaling policy.
    public static void configureScalingPolicy(ApplicationAutoScalingClient appAutoScalingClient, String tableId, ServiceNamespace ns, ScalableDimension tableWCUs, String policyName) {
        // Check if the policy exists before creating a new one.
        DescribeScalingPoliciesResponse describeScalingPoliciesResponse = appAutoScalingClient.describeScalingPolicies(DescribeScalingPoliciesRequest.builder()
            .serviceNamespace(ns)
            .resourceId(tableId)
            .scalableDimension(tableWCUs)
            .build());

        if (!describeScalingPoliciesResponse.scalingPolicies().isEmpty()) {
            // If policies exist, consider updating an existing policy instead of creating a new one.
            System.out.println("Policy already exists. Consider updating it instead.");
            List<ScalingPolicy> polList = describeScalingPoliciesResponse.scalingPolicies();
            for (ScalingPolicy pol : polList) {
                System.out.println("Policy name:" +pol.policyName());
            }
        } else {
            // If no policies exist, proceed with creating a new policy.
            PredefinedMetricSpecification specification = PredefinedMetricSpecification.builder()
                .predefinedMetricType(MetricType.DYNAMO_DB_WRITE_CAPACITY_UTILIZATION)
                .build();

            TargetTrackingScalingPolicyConfiguration policyConfiguration = TargetTrackingScalingPolicyConfiguration.builder()
                .predefinedMetricSpecification(specification)
                .targetValue(50.0)
                .scaleInCooldown(60)
                .scaleOutCooldown(60)
                .build();

            PutScalingPolicyRequest putScalingPolicyRequest = PutScalingPolicyRequest.builder()
                .targetTrackingScalingPolicyConfiguration(policyConfiguration)
                .serviceNamespace(ns)
                .scalableDimension(tableWCUs)
                .resourceId(tableId)
                .policyName(policyName)
                .policyType(PolicyType.TARGET_TRACKING_SCALING)
                .build();

            try {
                appAutoScalingClient.putScalingPolicy(putScalingPolicyRequest);
                System.out.println("You have successfully created a scaling policy for an Application Auto Scaling scalable target");
            } catch (ApplicationAutoScalingException e) {
                System.err.println("Error: " + e.awsErrorDetails().errorMessage());
            }
        }
    }
}
```

------
#### [ Java v1 ]

程序要求您为有效的 Application Auto Scaling 服务相关角色提供 Amazon Resource Name (ARN)。例如：`arn:aws:iam::122517410325:role/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable`。在以下程序中，用实际的 ARN 替换 `SERVICE_ROLE_ARN_GOES_HERE`。

```
package com.amazonaws.codesamples.autoscaling;

import com.amazonaws.services.applicationautoscaling.AWSApplicationAutoScalingClient;
import com.amazonaws.services.applicationautoscaling.AWSApplicationAutoScalingClientBuilder;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalableTargetsRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalableTargetsResult;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalingPoliciesRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalingPoliciesResult;
import com.amazonaws.services.applicationautoscaling.model.MetricType;
import com.amazonaws.services.applicationautoscaling.model.PolicyType;
import com.amazonaws.services.applicationautoscaling.model.PredefinedMetricSpecification;
import com.amazonaws.services.applicationautoscaling.model.PutScalingPolicyRequest;
import com.amazonaws.services.applicationautoscaling.model.RegisterScalableTargetRequest;
import com.amazonaws.services.applicationautoscaling.model.ScalableDimension;
import com.amazonaws.services.applicationautoscaling.model.ServiceNamespace;
import com.amazonaws.services.applicationautoscaling.model.TargetTrackingScalingPolicyConfiguration;

public class EnableDynamoDBAutoscaling {

	static AWSApplicationAutoScalingClient aaClient = (AWSApplicationAutoScalingClient) AWSApplicationAutoScalingClientBuilder
			.standard().build();

	public static void main(String args[]) {

		ServiceNamespace ns = ServiceNamespace.Dynamodb;
		ScalableDimension tableWCUs = ScalableDimension.DynamodbTableWriteCapacityUnits;
		String resourceID = "table/TestTable";

		// Define the scalable target
		RegisterScalableTargetRequest rstRequest = new RegisterScalableTargetRequest()
				.withServiceNamespace(ns)
				.withResourceId(resourceID)
				.withScalableDimension(tableWCUs)
				.withMinCapacity(5)
				.withMaxCapacity(10)
				.withRoleARN("SERVICE_ROLE_ARN_GOES_HERE");

		try {
			aaClient.registerScalableTarget(rstRequest);
		} catch (Exception e) {
			System.err.println("Unable to register scalable target: ");
			System.err.println(e.getMessage());
		}

		// Verify that the target was created
		DescribeScalableTargetsRequest dscRequest = new DescribeScalableTargetsRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceIds(resourceID);
		try {
			DescribeScalableTargetsResult dsaResult = aaClient.describeScalableTargets(dscRequest);
			System.out.println("DescribeScalableTargets result: ");
			System.out.println(dsaResult);
			System.out.println();
		} catch (Exception e) {
			System.err.println("Unable to describe scalable target: ");
			System.err.println(e.getMessage());
		}

		System.out.println();

		// Configure a scaling policy
		TargetTrackingScalingPolicyConfiguration targetTrackingScalingPolicyConfiguration = new TargetTrackingScalingPolicyConfiguration()
				.withPredefinedMetricSpecification(
						new PredefinedMetricSpecification()
								.withPredefinedMetricType(MetricType.DynamoDBWriteCapacityUtilization))
				.withTargetValue(50.0)
				.withScaleInCooldown(60)
				.withScaleOutCooldown(60);

		// Create the scaling policy, based on your configuration
		PutScalingPolicyRequest pspRequest = new PutScalingPolicyRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceId(resourceID)
				.withPolicyName("MyScalingPolicy")
				.withPolicyType(PolicyType.TargetTrackingScaling)
				.withTargetTrackingScalingPolicyConfiguration(targetTrackingScalingPolicyConfiguration);

		try {
			aaClient.putScalingPolicy(pspRequest);
		} catch (Exception e) {
			System.err.println("Unable to put scaling policy: ");
			System.err.println(e.getMessage());
		}

		// Verify that the scaling policy was created
		DescribeScalingPoliciesRequest dspRequest = new DescribeScalingPoliciesRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceId(resourceID);

		try {
			DescribeScalingPoliciesResult dspResult = aaClient.describeScalingPolicies(dspRequest);
			System.out.println("DescribeScalingPolicies result: ");
			System.out.println(dspResult);
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("Unable to describe scaling policy: ");
			System.err.println(e.getMessage());
		}

	}

}
```

------

## 禁用表的 Application Auto Scaling
<a name="AutoScaling.HowTo.SDK-disable"></a>

以下程序将反转前面的过程。它删除 Auto Scaling 策略，然后撤消可扩展目标的注册。

------
#### [ Java v2 ]

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.applicationautoscaling.ApplicationAutoScalingClient;
import software.amazon.awssdk.services.applicationautoscaling.model.ApplicationAutoScalingException;
import software.amazon.awssdk.services.applicationautoscaling.model.DeleteScalingPolicyRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DeregisterScalableTargetRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalableTargetsRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalableTargetsResponse;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalingPoliciesRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalingPoliciesResponse;
import software.amazon.awssdk.services.applicationautoscaling.model.ScalableDimension;
import software.amazon.awssdk.services.applicationautoscaling.model.ServiceNamespace;

/**
 * Before running this Java V2 code example, set up your development environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class DisableDynamoDBAutoscaling {
    public static void main(String[] args) {
        final String usage = """

            Usage:
               <tableId> <policyName>\s

            Where:
               tableId - The table Id value (for example, table/Music).\s
               policyName - The name of the policy (for example, $Music5-scaling-policy). 
        
            """;
        if (args.length != 2) {
            System.out.println(usage);
            System.exit(1);
        }

        ApplicationAutoScalingClient appAutoScalingClient = ApplicationAutoScalingClient.builder()
            .region(Region.US_EAST_1)
            .build();

        ServiceNamespace ns = ServiceNamespace.DYNAMODB;
        ScalableDimension tableWCUs = ScalableDimension.DYNAMODB_TABLE_WRITE_CAPACITY_UNITS;
        String tableId = args[0];
        String policyName = args[1];

        deletePolicy(appAutoScalingClient, policyName, tableWCUs, ns, tableId);
        verifyScalingPolicies(appAutoScalingClient, tableId, ns, tableWCUs);
        deregisterScalableTarget(appAutoScalingClient, tableId, ns, tableWCUs);
        verifyTarget(appAutoScalingClient, tableId, ns, tableWCUs);
    }

    public static void deletePolicy(ApplicationAutoScalingClient appAutoScalingClient, String policyName, ScalableDimension tableWCUs, ServiceNamespace ns, String tableId) {
        try {
            DeleteScalingPolicyRequest delSPRequest = DeleteScalingPolicyRequest.builder()
                .policyName(policyName)
                .scalableDimension(tableWCUs)
                .serviceNamespace(ns)
                .resourceId(tableId)
                .build();

            appAutoScalingClient.deleteScalingPolicy(delSPRequest);
            System.out.println(policyName +" was deleted successfully.");

        } catch (ApplicationAutoScalingException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
        }
    }

    // Verify that the scaling policy was deleted
    public static void verifyScalingPolicies(ApplicationAutoScalingClient appAutoScalingClient, String tableId, ServiceNamespace ns, ScalableDimension tableWCUs) {
        DescribeScalingPoliciesRequest dscRequest = DescribeScalingPoliciesRequest.builder()
            .scalableDimension(tableWCUs)
            .serviceNamespace(ns)
            .resourceId(tableId)
            .build();

        DescribeScalingPoliciesResponse response = appAutoScalingClient.describeScalingPolicies(dscRequest);
        System.out.println("DescribeScalableTargets result: ");
        System.out.println(response);
    }

    public static void deregisterScalableTarget(ApplicationAutoScalingClient appAutoScalingClient, String tableId, ServiceNamespace ns, ScalableDimension tableWCUs) {
        try {
            DeregisterScalableTargetRequest targetRequest = DeregisterScalableTargetRequest.builder()
                .scalableDimension(tableWCUs)
                .serviceNamespace(ns)
                .resourceId(tableId)
                .build();

            appAutoScalingClient.deregisterScalableTarget(targetRequest);
            System.out.println("The scalable target was deregistered.");

        } catch (ApplicationAutoScalingException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
        }
    }

    public static void verifyTarget(ApplicationAutoScalingClient appAutoScalingClient, String tableId, ServiceNamespace ns, ScalableDimension tableWCUs) {
        DescribeScalableTargetsRequest dscRequest = DescribeScalableTargetsRequest.builder()
            .scalableDimension(tableWCUs)
            .serviceNamespace(ns)
            .resourceIds(tableId)
            .build();

        DescribeScalableTargetsResponse response = appAutoScalingClient.describeScalableTargets(dscRequest);
        System.out.println("DescribeScalableTargets result: ");
        System.out.println(response);
    }
}
```

------
#### [ Java v1 ]

```
package com.amazonaws.codesamples.autoscaling;

import com.amazonaws.services.applicationautoscaling.AWSApplicationAutoScalingClient;
import com.amazonaws.services.applicationautoscaling.model.DeleteScalingPolicyRequest;
import com.amazonaws.services.applicationautoscaling.model.DeregisterScalableTargetRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalableTargetsRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalableTargetsResult;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalingPoliciesRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalingPoliciesResult;
import com.amazonaws.services.applicationautoscaling.model.ScalableDimension;
import com.amazonaws.services.applicationautoscaling.model.ServiceNamespace;

public class DisableDynamoDBAutoscaling {

	static AWSApplicationAutoScalingClient aaClient = new AWSApplicationAutoScalingClient();

	public static void main(String args[]) {

		ServiceNamespace ns = ServiceNamespace.Dynamodb;
		ScalableDimension tableWCUs = ScalableDimension.DynamodbTableWriteCapacityUnits;
		String resourceID = "table/TestTable";

		// Delete the scaling policy
		DeleteScalingPolicyRequest delSPRequest = new DeleteScalingPolicyRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceId(resourceID)
				.withPolicyName("MyScalingPolicy");

		try {
			aaClient.deleteScalingPolicy(delSPRequest);
		} catch (Exception e) {
			System.err.println("Unable to delete scaling policy: ");
			System.err.println(e.getMessage());
		}

		// Verify that the scaling policy was deleted
		DescribeScalingPoliciesRequest descSPRequest = new DescribeScalingPoliciesRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceId(resourceID);

		try {
			DescribeScalingPoliciesResult dspResult = aaClient.describeScalingPolicies(descSPRequest);
			System.out.println("DescribeScalingPolicies result: ");
			System.out.println(dspResult);
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("Unable to describe scaling policy: ");
			System.err.println(e.getMessage());
		}

		System.out.println();

		// Remove the scalable target
		DeregisterScalableTargetRequest delSTRequest = new DeregisterScalableTargetRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceId(resourceID);

		try {
			aaClient.deregisterScalableTarget(delSTRequest);
		} catch (Exception e) {
			System.err.println("Unable to deregister scalable target: ");
			System.err.println(e.getMessage());
		}

		// Verify that the scalable target was removed
		DescribeScalableTargetsRequest dscRequest = new DescribeScalableTargetsRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceIds(resourceID);

		try {
			DescribeScalableTargetsResult dsaResult = aaClient.describeScalableTargets(dscRequest);
			System.out.println("DescribeScalableTargets result: ");
			System.out.println(dsaResult);
			System.out.println();
		} catch (Exception e) {
			System.err.println("Unable to describe scalable target: ");
			System.err.println(e.getMessage());
		}

	}

}
```

------

# DynamoDB 预留容量
<a name="reserved-capacity"></a>

对于使用标准[表类](HowItWorks.TableClasses.md)的预置容量表，DynamoDB 提供了为读取和写入容量购买预留容量的功能。预留容量购买是一种协议，即在协议期限内支付最低量的预置吞吐能力，以换取折扣定价。

**注意**  
您不能为复制的写入容量单位（rWCU）购买预留容量。预留容量仅适用于购买该容量的区域。预留容量也不适用于使用 DynamoDB Standard-IA 表类别或按需容量模式的表。

预留容量以 100 WCU 或 100 RCU 的分配方式购买。所提供的最小预留容量为 100 个容量单位（读取或写入）。DynamoDB 预留容量以一年承诺形式提供，或在特定区域以三年承诺形式提供。在标准费率的基础上，一年期最高可节省 54%，而三年期最高可节省 77%。有关应如何以及何时购买的更多信息，请参阅 [Amazon DynamoDB Reserved Capacity](https://aws.amazon.com/dynamodb/reserved-capacity/)。

**注意**  
您可以使用 AWS 管理控制台为写入容量单位（WCU）和读取容量单位（RCU）组合购买多达 1000000 个预留容量单位。如果您想在一次购买中购买超过 1000000 个预置容量单位，或者您拥有活动的预留容量并想购买额外的预留容量，从而产生超过 1000000 个活动的预置容量单位，请按照 [Amazon DynamoDB 预留容量](https://aws.amazon.com/dynamodb/reserved-capacity/)中“如何购买预留容量”一节中提到的流程进行操作。

当您购买 DynamoDB 预留容量时，您可以一次性预付部分款项，并获得承诺预置用量的折扣小时费率。无论实际用量如何，您都需要为承诺的全部预置用量付费，因此节省的成本与用量密切相关。对于您预置的超出所购买预留容量的任何容量，将按照标准预置容量费率收费。通过提前预留读取和写入容量单元，您可以节省大量的预置容量成本。

您不能出售、取消预留容量或将其转移到其它区域或账户。

# 了解 DynamoDB 热吞吐量
<a name="warm-throughput"></a>

*热吞吐量* 是指 DynamoDB 表可以立即支持的读取和写入操作的数量。默认情况下，这些值适用于所有表和全局二级索引（GSI），并表示它们根据历史使用情况已扩展的程度。如果您使用的是按需模式，或者将预置吞吐量更新为这些值，则应用程序将能够立即发出不超过这些值的请求。

随着使用量增加，DynamoDB 将自动调整热吞吐量值。您也可以在需要时主动增加这些值，这对于即将到来的产品发布或销售等高峰事件尤其有用。对于计划的高峰事件，其中对 DynamoDB 表的请求速率可能会增加 10 倍、100 倍或更多，您现在可以评测当前的热吞吐量是否足以处理预期的流量。如果不是这种情况，则可以在不更改吞吐量设置或[计费模式](capacity-mode.md)的情况下增加热吞吐量值。此过程称为*预热* 表，可让您设置表可以立即支持的基准。这可以确保应用程序从请求发生的那一刻起就可以处理更高的请求速率。一旦增加，就无法降低热吞吐量值。

您可以增加读取操作和/或写入操作的热吞吐量值。您可以为新的和现有的单区域表、全局表和 GSI 增加此值。对于全局表，此功能适用于[版本 2019.11.21（当前版）](GlobalTables.md)，并且您设置的热吞吐量设置将自动应用于全局表中的所有副本表。对您可以随时预热的 DynamoDB 表的数量没有限制。完成预热的时间取决于您设置的值以及表或索引的大小。您可以提交多个同时的预热请求，这些请求不会干扰任何表操作。您可以将表预热到该区域中账户的表或索引配额限制。使用[服务配额控制台](https://console.aws.amazon.com/servicequotas)来检查您当前的限制，并在需要时提高这些限制。

默认情况下，所有表和二级索引均可免费使用热吞吐量值。但是，如果您主动增加这些默认的热吞吐量值来预热表，则需要为这些请求付费。有关更多信息，请参阅 [Amazon DynamoDB 定价](https://aws.amazon.com/dynamodb/pricing/)。

有关热吞吐量的更多信息，请参阅以下主题：

**Topics**
+ [

# 检查 DynamoDB 表的当前热吞吐量
](check-warm-throughput.md)
+ [

# 增加现有 DynamoDB 表的热吞吐量
](update-warm-throughput.md)
+ [

# 创建具有更高热吞吐量的新 DynamoDB 表
](create-table-warm-throughput.md)
+ [

# 了解不同场景下的 DynamoDB 热吞吐量
](warm-throughput-scenarios.md)

# 检查 DynamoDB 表的当前热吞吐量
<a name="check-warm-throughput"></a>

使用以下 AWS CLI 和 AWS 管理控制台说明来检查表或索引的当前热吞吐量值。

## AWS 管理控制台
<a name="warm-throughput-check-console"></a>

要使用 DynamoDB 控制台检查 DynamoDB 表的热吞吐量，请执行以下操作：

1. 登录 AWS 管理控制台，并打开 DynamoDB 控制台：[https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)。

1. 在左侧导航窗格中，选择 表。

1. 在**表**页面上，选择所需的表。

1. 选择**其它设置**以查看您当前的热吞吐量值。此值显示为每秒读取单位数和每秒写入单位数。

## AWS CLI
<a name="warm-throughput-check-CLI"></a>

以下 AWS CLI 示例向您展示如何检查 DynamoDB 表的热吞吐量。

1. 对 DynamoDB 表运行 `describe-table` 操作。

   ```
   aws dynamodb describe-table --table-name GameScores
   ```

1. 您将收到与以下内容类似的响应。您的 `WarmThroughput` 设置将显示为 `ReadUnitsPerSecond` 和 `WriteUnitsPerSecond`。当热吞吐量值正在更新时，`Status` 将为 `UPDATING`，当设置了新的热吞吐量值时，则为 `ACTIVE`。

   ```
   {
       "Table": {
           "AttributeDefinitions": [
               {
                   "AttributeName": "GameTitle",
                   "AttributeType": "S"
               },
               {
                   "AttributeName": "TopScore",
                   "AttributeType": "N"
               },
               {
                   "AttributeName": "UserId",
                   "AttributeType": "S"
               }
           ],
           "TableName": "GameScores",
           "KeySchema": [
               {
                   "AttributeName": "UserId",
                   "KeyType": "HASH"
               },
               {
                   "AttributeName": "GameTitle",
                   "KeyType": "RANGE"
               }
           ],
           "TableStatus": "ACTIVE",
           "CreationDateTime": 1726128388.729,
           "ProvisionedThroughput": {
               "NumberOfDecreasesToday": 0,
               "ReadCapacityUnits": 0,
               "WriteCapacityUnits": 0
           },
           "TableSizeBytes": 0,
           "ItemCount": 0,
           "TableArn": "arn:aws:dynamodb:us-east-1:XXXXXXXXXXXX:table/GameScores",
           "TableId": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
           "BillingModeSummary": {
               "BillingMode": "PAY_PER_REQUEST",
               "LastUpdateToPayPerRequestDateTime": 1726128388.729
           },
           "GlobalSecondaryIndexes": [
               {
                   "IndexName": "GameTitleIndex",
                   "KeySchema": [
                       {
                           "AttributeName": "GameTitle",
                           "KeyType": "HASH"
                       },
                       {
                           "AttributeName": "TopScore",
                           "KeyType": "RANGE"
                       }
                   ],
                   "Projection": {
                       "ProjectionType": "INCLUDE",
                       "NonKeyAttributes": [
                           "UserId"
                       ]
                   },
                   "IndexStatus": "ACTIVE",
                   "ProvisionedThroughput": {
                       "NumberOfDecreasesToday": 0,
                       "ReadCapacityUnits": 0,
                       "WriteCapacityUnits": 0
                   },
                   "IndexSizeBytes": 0,
                   "ItemCount": 0,
                   "IndexArn": "arn:aws:dynamodb:us-east-1:XXXXXXXXXXXX:table/GameScores/index/GameTitleIndex",
                   "WarmThroughput": {
                       "ReadUnitsPerSecond": 12000,
                       "WriteUnitsPerSecond": 4000,
                       "Status": "ACTIVE"
                   }
               }
           ],
           "DeletionProtectionEnabled": false,
           "WarmThroughput": {
               "ReadUnitsPerSecond": 12000,
               "WriteUnitsPerSecond": 4000,
               "Status": "ACTIVE"
           }
       }
   }
   ```

# 增加现有 DynamoDB 表的热吞吐量
<a name="update-warm-throughput"></a>

检查 DynamoDB 表的当前热吞吐量值后，就可以通过以下步骤对其进行更新：

## AWS 管理控制台
<a name="warm-throughput-update-console"></a>

要使用 DynamoDB 控制台检查 DynamoDB 表的热吞吐量值，请执行以下操作：

1. 登录 AWS 管理控制台，并打开 DynamoDB 控制台：[https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)。

1. 在左侧导航窗格中，选择 表。

1. 在**表**页面上，选择所需的表。

1. 在**热吞吐量**字段中，选择**编辑**。

1. 在**编辑热吞吐量**页面上，选择**增加热吞吐量**。

1. 调整**每秒读取单位**和**每秒写入单位**。这两个设置定义了表可以立即处理的吞吐量。

1. 选择**保存**。

1. 请求处理完毕后，将在**热吞吐量**字段中更新**每秒读取单位**和**每秒写入单位**。
**注意**  
更新热吞吐量值是一项异步任务。更新完成后，`Status` 将从 `UPDATING` 变为 `ACTIVE`。

## AWS CLI
<a name="warm-throughput-update-CLI"></a>

以下 AWS CLI 示例向您展示如何更新 DynamoDB 表的热吞吐量值。

1. 对 DynamoDB 表运行 `update-table` 操作。

   ```
   aws dynamodb update-table \
       --table-name GameScores \
       --warm-throughput ReadUnitsPerSecond=12345,WriteUnitsPerSecond=4567 \
       --global-secondary-index-updates \
           "[
               {
                   \"Update\": {
                       \"IndexName\": \"GameTitleIndex\",
                       \"WarmThroughput\": {
                           \"ReadUnitsPerSecond\": 88,
                           \"WriteUnitsPerSecond\": 77
                       }
                   }
               }
           ]" \
       --region us-east-1
   ```

1. 您将收到与以下内容类似的响应。您的 `WarmThroughput` 设置将显示为 `ReadUnitsPerSecond` 和 `WriteUnitsPerSecond`。当热吞吐量值正在更新时，`Status` 将为 `UPDATING`，当设置了新的热吞吐量值时，则为 `ACTIVE`。

   ```
   {
       "TableDescription": {
           "AttributeDefinitions": [
               {
                   "AttributeName": "GameTitle",
                   "AttributeType": "S"
               },
               {
                   "AttributeName": "TopScore",
                   "AttributeType": "N"
               },
               {
                   "AttributeName": "UserId",
                   "AttributeType": "S"
               }
           ],
           "TableName": "GameScores",
           "KeySchema": [
               {
                   "AttributeName": "UserId",
                   "KeyType": "HASH"
               },
               {
                   "AttributeName": "GameTitle",
                   "KeyType": "RANGE"
               }
           ],
           "TableStatus": "ACTIVE",
           "CreationDateTime": 1730242189.965,
           "ProvisionedThroughput": {
               "NumberOfDecreasesToday": 0,
               "ReadCapacityUnits": 20,
               "WriteCapacityUnits": 10
           },
           "TableSizeBytes": 0,
           "ItemCount": 0,
           "TableArn": "arn:aws:dynamodb:us-east-1:XXXXXXXXXXXX:table/GameScores",
           "TableId": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
           "GlobalSecondaryIndexes": [
               {
                   "IndexName": "GameTitleIndex",
                   "KeySchema": [
                       {
                           "AttributeName": "GameTitle",
                           "KeyType": "HASH"
                       },
                       {
                           "AttributeName": "TopScore",
                           "KeyType": "RANGE"
                       }
                   ],
                   "Projection": {
                       "ProjectionType": "INCLUDE",
                       "NonKeyAttributes": [
                           "UserId"
                       ]
                   },
                   "IndexStatus": "ACTIVE",
                   "ProvisionedThroughput": {
                       "NumberOfDecreasesToday": 0,
                       "ReadCapacityUnits": 50,
                       "WriteCapacityUnits": 25
                   },
                   "IndexSizeBytes": 0,
                   "ItemCount": 0,
                   "IndexArn": "arn:aws:dynamodb:us-east-1:XXXXXXXXXXXX:table/GameScores/index/GameTitleIndex",
                   "WarmThroughput": {
                       "ReadUnitsPerSecond": 50,
                       "WriteUnitsPerSecond": 25,
                       "Status": "UPDATING"
                   }
               }
           ],
           "DeletionProtectionEnabled": false,
           "WarmThroughput": {
               "ReadUnitsPerSecond": 12300,
               "WriteUnitsPerSecond": 4500,
               "Status": "UPDATING"
           }
       }
   }
   ```

## AWS SDK
<a name="warm-throughput-update-SDK"></a>

以下 SDK 示例向您展示如何更新 DynamoDB 表的热吞吐量值。

------
#### [ Java ]

```
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.GlobalSecondaryIndexUpdate;
import software.amazon.awssdk.services.dynamodb.model.UpdateGlobalSecondaryIndexAction;
import software.amazon.awssdk.services.dynamodb.model.UpdateTableRequest;
import software.amazon.awssdk.services.dynamodb.model.WarmThroughput;

...
public static WarmThroughput buildWarmThroughput(final Long readUnitsPerSecond,
                                                 final Long writeUnitsPerSecond) {
    return WarmThroughput.builder()
            .readUnitsPerSecond(readUnitsPerSecond)
            .writeUnitsPerSecond(writeUnitsPerSecond)
            .build();
}

public static void updateDynamoDBTable(DynamoDbClient ddb,
                                       String tableName,
                                       Long tableReadUnitsPerSecond,
                                       Long tableWriteUnitsPerSecond,
                                       String globalSecondaryIndexName,
                                       Long globalSecondaryIndexReadUnitsPerSecond,
                                       Long globalSecondaryIndexWriteUnitsPerSecond) {

    final WarmThroughput tableWarmThroughput = buildWarmThroughput(tableReadUnitsPerSecond, tableWriteUnitsPerSecond);
    final WarmThroughput gsiWarmThroughput = buildWarmThroughput(globalSecondaryIndexReadUnitsPerSecond, globalSecondaryIndexWriteUnitsPerSecond);

    final GlobalSecondaryIndexUpdate globalSecondaryIndexUpdate = GlobalSecondaryIndexUpdate.builder()
            .update(UpdateGlobalSecondaryIndexAction.builder()
                    .indexName(globalSecondaryIndexName)
                    .warmThroughput(gsiWarmThroughput)
                    .build()
            ).build();

    final UpdateTableRequest request = UpdateTableRequest.builder()
            .tableName(tableName)
            .globalSecondaryIndexUpdates(globalSecondaryIndexUpdate)
            .warmThroughput(tableWarmThroughput)
            .build();

    try {
        ddb.updateTable(request);
    } catch (DynamoDbException e) {
        System.err.println(e.getMessage());
        System.exit(1);
    }

    System.out.println("Done!");
}
```

------
#### [ Python ]

```
from boto3 import resource
from botocore.exceptions import ClientError

def update_dynamodb_table_warm_throughput(table_name, table_read_units, table_write_units, gsi_name, gsi_read_units, gsi_write_units, region_name="us-east-1"):
    """
    Updates the warm throughput of a DynamoDB table and a global secondary index.

    :param table_name: The name of the table to update.
    :param table_read_units: The new read units per second for the table's warm throughput.
    :param table_write_units: The new write units per second for the table's warm throughput.
    :param gsi_name: The name of the global secondary index to update.
    :param gsi_read_units: The new read units per second for the GSI's warm throughput.
    :param gsi_write_units: The new write units per second for the GSI's warm throughput.
    :param region_name: The AWS Region name to target. defaults to us-east-1
    """
    try:
        ddb = resource('dynamodb', region_name)
        
        # Update the table's warm throughput
        table_warm_throughput = {
            "ReadUnitsPerSecond": table_read_units,
            "WriteUnitsPerSecond": table_write_units
        }

        # Update the global secondary index's warm throughput
        gsi_warm_throughput = {
            "ReadUnitsPerSecond": gsi_read_units,
            "WriteUnitsPerSecond": gsi_write_units
        }

        # Construct the global secondary index update
        global_secondary_index_update = [
            {
                "Update": {
                    "IndexName": gsi_name,
                    "WarmThroughput": gsi_warm_throughput
                }
            }
        ]

        # Construct the update table request
        update_table_request = {
            "TableName": table_name,
            "GlobalSecondaryIndexUpdates": global_secondary_index_update,
            "WarmThroughput": table_warm_throughput
        }

        # Update the table
        ddb.update_table(**update_table_request)
        print("Table updated successfully!")
    except ClientError as e:
        print(f"Error updating table: {e}")
        raise e
```

------
#### [ Javascript ]

```
import { DynamoDBClient, UpdateTableCommand } from "@aws-sdk/client-dynamodb";

async function updateDynamoDBTableWarmThroughput(
  tableName,
  tableReadUnits,
  tableWriteUnits,
  gsiName,
  gsiReadUnits,
  gsiWriteUnits,
  region = "us-east-1"
) {
  try {
    const ddbClient = new DynamoDBClient({ region: region });

    // Construct the update table request
    const updateTableRequest = {
      TableName: tableName,
      GlobalSecondaryIndexUpdates: [
        {
            Update: {
                IndexName: gsiName,
                WarmThroughput: {
                    ReadUnitsPerSecond: gsiReadUnits,
                    WriteUnitsPerSecond: gsiWriteUnits,
                },
            },
        },
      ],
      WarmThroughput: {
          ReadUnitsPerSecond: tableReadUnits,
          WriteUnitsPerSecond: tableWriteUnits,
      },
    };

    const command = new UpdateTableCommand(updateTableRequest);
    const response = await ddbClient.send(command);
    console.log(`Table updated successfully! Response: ${response}`);
  } catch (error) {
    console.error(`Error updating table: ${error}`);
    throw error;
  }
}
```

------

# 创建具有更高热吞吐量的新 DynamoDB 表
<a name="create-table-warm-throughput"></a>

在创建 DynamoDB 表时，您可以按照以下步骤调整热吞吐量值。这些步骤也适用于创建[全局表](GlobalTables.md)或[二级索引](SecondaryIndexes.md)。

## AWS 管理控制台
<a name="warm-throughput-create-console"></a>

要通过控制台创建 DynamoDB 表并调整热吞吐量值，请执行以下操作：

1. 登录 AWS 管理控制台，并打开 DynamoDB 控制台：[https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)。

1. 选择**创建表**。

1. 选择**表名称**、**分区键**和**排序键（可选）**。

1. 对于**表设置**，选择**自定义设置**。

1. 在**热吞吐量**字段中，选择**增加热吞吐量**。

1. 调整**每秒读取单位**和**每秒写入单位**。这两个设置定义了表可以立即处理的最大吞吐量。

1. 继续添加所有剩余的表详细信息，然后选择**创建表**。

## AWS CLI
<a name="warm-throughput-create-CLI"></a>

以下 AWS CLI 示例显示了如何使用自定义的热吞吐量值创建 DynamoDB 表。

1. 运行 `create-table` 操作以创建以下 DynamoDB 表。

   ```
   aws dynamodb create-table \
       --table-name GameScores \
       --attribute-definitions AttributeName=UserId,AttributeType=S \
                               AttributeName=GameTitle,AttributeType=S \
                               AttributeName=TopScore,AttributeType=N  \
       --key-schema AttributeName=UserId,KeyType=HASH \
                    AttributeName=GameTitle,KeyType=RANGE \
       --provisioned-throughput ReadCapacityUnits=20,WriteCapacityUnits=10 \
       --global-secondary-indexes \
           "[
               {
                   \"IndexName\": \"GameTitleIndex\",
                   \"KeySchema\": [{\"AttributeName\":\"GameTitle\",\"KeyType\":\"HASH\"},
                                   {\"AttributeName\":\"TopScore\",\"KeyType\":\"RANGE\"}],
                   \"Projection\":{
                       \"ProjectionType\":\"INCLUDE\",
                       \"NonKeyAttributes\":[\"UserId\"]
                   },
                   \"ProvisionedThroughput\": {
                       \"ReadCapacityUnits\": 50,
                       \"WriteCapacityUnits\": 25
                   },\"WarmThroughput\": {
                       \"ReadUnitsPerSecond\": 1987,
                       \"WriteUnitsPerSecond\": 543
                   }
               }
           ]" \
       --warm-throughput ReadUnitsPerSecond=12345,WriteUnitsPerSecond=4567 \
       --region us-east-1
   ```

1. 您将收到与以下内容类似的响应。您的 `WarmThroughput` 设置将显示为 `ReadUnitsPerSecond` 和 `WriteUnitsPerSecond`。当热吞吐量值正在更新时，`Status` 将为 `UPDATING`，当设置了新的热吞吐量值时，则为 `ACTIVE`。

   ```
   {
       "TableDescription": {
           "AttributeDefinitions": [
               {
                   "AttributeName": "GameTitle",
                   "AttributeType": "S"
               },
               {
                   "AttributeName": "TopScore",
                   "AttributeType": "N"
               },
               {
                   "AttributeName": "UserId",
                   "AttributeType": "S"
               }
           ],
           "TableName": "GameScores",
           "KeySchema": [
               {
                   "AttributeName": "UserId",
                   "KeyType": "HASH"
               },
               {
                   "AttributeName": "GameTitle",
                   "KeyType": "RANGE"
               }
           ],
           "TableStatus": "CREATING",
           "CreationDateTime": 1730241788.779,
           "ProvisionedThroughput": {
               "NumberOfDecreasesToday": 0,
               "ReadCapacityUnits": 20,
               "WriteCapacityUnits": 10
           },
           "TableSizeBytes": 0,
           "ItemCount": 0,
           "TableArn": "arn:aws:dynamodb:us-east-1:XXXXXXXXXXXX:table/GameScores",
           "TableId": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
           "GlobalSecondaryIndexes": [
               {
                   "IndexName": "GameTitleIndex",
                   "KeySchema": [
                       {
                           "AttributeName": "GameTitle",
                           "KeyType": "HASH"
                       },
                       {
                           "AttributeName": "TopScore",
                           "KeyType": "RANGE"
                       }
                   ],
                   "Projection": {
                       "ProjectionType": "INCLUDE",
                       "NonKeyAttributes": [
                           "UserId"
                       ]
                   },
                   "IndexStatus": "CREATING",
                   "ProvisionedThroughput": {
                       "NumberOfDecreasesToday": 0,
                       "ReadCapacityUnits": 50,
                       "WriteCapacityUnits": 25
                   },
                   "IndexSizeBytes": 0,
                   "ItemCount": 0,
                   "IndexArn": "arn:aws:dynamodb:us-east-1:XXXXXXXXXXXX:table/GameScores/index/GameTitleIndex",
                   "WarmThroughput": {
                       "ReadUnitsPerSecond": 1987,
                       "WriteUnitsPerSecond": 543,
                       "Status": "UPDATING"
                   }
               }
           ],
           "DeletionProtectionEnabled": false,
           "WarmThroughput": {
               "ReadUnitsPerSecond": 12345,
               "WriteUnitsPerSecond": 4567,
               "Status": "UPDATING"
           }
       }
   }
   ```

## AWS SDK
<a name="warm-throughput-create-SDK"></a>

以下 SDK 示例显示了如何通过自定义的热吞吐量值创建 DynamoDB 表。

------
#### [ Java ]

```
import software.amazon.awscdk.services.dynamodb.ProjectionType;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse;
import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest;
import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement;
import software.amazon.awssdk.services.dynamodb.model.KeyType;
import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput;
import software.amazon.awssdk.services.dynamodb.model.Projection;
import software.amazon.awssdk.services.dynamodb.model.GlobalSecondaryIndex;
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
import software.amazon.awssdk.services.dynamodb.model.WarmThroughput;
...

public static WarmThroughput buildWarmThroughput(final Long readUnitsPerSecond,
                                                 final Long writeUnitsPerSecond) {
    return WarmThroughput.builder()
            .readUnitsPerSecond(readUnitsPerSecond)
            .writeUnitsPerSecond(writeUnitsPerSecond)
            .build();
}
private static AttributeDefinition buildAttributeDefinition(final String attributeName, 
                                                            final ScalarAttributeType scalarAttributeType) {
    return AttributeDefinition.builder()
            .attributeName(attributeName)
            .attributeType(scalarAttributeType)
            .build();
}
private static KeySchemaElement buildKeySchemaElement(final String attributeName, 
                                                      final KeyType keyType) {
    return KeySchemaElement.builder()
            .attributeName(attributeName)
            .keyType(keyType)
            .build();
}
public static void createDynamoDBTable(DynamoDbClient ddb,
                                       String tableName,
                                       String partitionKey,
                                       String sortKey,
                                       String miscellaneousKeyAttribute,
                                       String nonKeyAttribute,
                                       Long tableReadCapacityUnits,
                                       Long tableWriteCapacityUnits,
                                       Long tableWarmReadUnitsPerSecond,
                                       Long tableWarmWriteUnitsPerSecond,
                                       String globalSecondaryIndexName,
                                       Long globalSecondaryIndexReadCapacityUnits,
                                       Long globalSecondaryIndexWriteCapacityUnits,
                                       Long globalSecondaryIndexWarmReadUnitsPerSecond,
                                       Long globalSecondaryIndexWarmWriteUnitsPerSecond) {

    // Define the table attributes
    final AttributeDefinition partitionKeyAttribute = buildAttributeDefinition(partitionKey, ScalarAttributeType.S);
    final AttributeDefinition sortKeyAttribute = buildAttributeDefinition(sortKey, ScalarAttributeType.S);
    final AttributeDefinition miscellaneousKeyAttributeDefinition = buildAttributeDefinition(miscellaneousKeyAttribute, ScalarAttributeType.N);
    final AttributeDefinition[] attributeDefinitions = {partitionKeyAttribute, sortKeyAttribute, miscellaneousKeyAttributeDefinition};

    // Define the table key schema
    final KeySchemaElement partitionKeyElement = buildKeySchemaElement(partitionKey, KeyType.HASH);
    final KeySchemaElement sortKeyElement = buildKeySchemaElement(sortKey, KeyType.RANGE);
    final KeySchemaElement[] keySchema = {partitionKeyElement, sortKeyElement};

    // Define the provisioned throughput for the table
    final ProvisionedThroughput provisionedThroughput = ProvisionedThroughput.builder()
            .readCapacityUnits(tableReadCapacityUnits)
            .writeCapacityUnits(tableWriteCapacityUnits)
            .build();

    // Define the Global Secondary Index (GSI)
    final KeySchemaElement globalSecondaryIndexPartitionKeyElement = buildKeySchemaElement(sortKey, KeyType.HASH);
    final KeySchemaElement globalSecondaryIndexSortKeyElement = buildKeySchemaElement(miscellaneousKeyAttribute, KeyType.RANGE);
    final KeySchemaElement[] gsiKeySchema = {globalSecondaryIndexPartitionKeyElement, globalSecondaryIndexSortKeyElement};

    final Projection gsiProjection = Projection.builder()
            .projectionType(String.valueOf(ProjectionType.INCLUDE))
            .nonKeyAttributes(nonKeyAttribute)
            .build();
    final ProvisionedThroughput gsiProvisionedThroughput = ProvisionedThroughput.builder()
            .readCapacityUnits(globalSecondaryIndexReadCapacityUnits)
            .writeCapacityUnits(globalSecondaryIndexWriteCapacityUnits)
            .build();
    // Define the warm throughput for the Global Secondary Index (GSI)
    final WarmThroughput gsiWarmThroughput = buildWarmThroughput(globalSecondaryIndexWarmReadUnitsPerSecond, globalSecondaryIndexWarmWriteUnitsPerSecond);
    final GlobalSecondaryIndex globalSecondaryIndex = GlobalSecondaryIndex.builder()
            .indexName(globalSecondaryIndexName)
            .keySchema(gsiKeySchema)
            .projection(gsiProjection)
            .provisionedThroughput(gsiProvisionedThroughput)
            .warmThroughput(gsiWarmThroughput)
            .build();

    // Define the warm throughput for the table
    final WarmThroughput tableWarmThroughput = buildWarmThroughput(tableWarmReadUnitsPerSecond, tableWarmWriteUnitsPerSecond);

    final CreateTableRequest request = CreateTableRequest.builder()
            .tableName(tableName)
            .attributeDefinitions(attributeDefinitions)
            .keySchema(keySchema)
            .provisionedThroughput(provisionedThroughput)
            .globalSecondaryIndexes(globalSecondaryIndex)
            .warmThroughput(tableWarmThroughput)
            .build();

    CreateTableResponse response = ddb.createTable(request);
    System.out.println(response);
}
```

------
#### [ Python ]

```
from boto3 import resource
from botocore.exceptions import ClientError

def create_dynamodb_table_warm_throughput(table_name, partition_key, sort_key, misc_key_attr, non_key_attr, table_provisioned_read_units, table_provisioned_write_units, table_warm_reads, table_warm_writes, gsi_name, gsi_provisioned_read_units, gsi_provisioned_write_units, gsi_warm_reads, gsi_warm_writes, region_name="us-east-1"):
    """
    Creates a DynamoDB table with a warm throughput setting configured.

    :param table_name: The name of the table to be created.
    :param partition_key: The partition key for the table being created.
    :param sort_key: The sort key for the table being created.
    :param misc_key_attr: A miscellaneous key attribute for the table being created.
    :param non_key_attr: A non-key attribute for the table being created.
    :param table_provisioned_read_units: The newly created table's provisioned read capacity units.
    :param table_provisioned_write_units: The newly created table's provisioned write capacity units.
    :param table_warm_reads: The read units per second setting for the table's warm throughput.
    :param table_warm_writes: The write units per second setting for the table's warm throughput.
    :param gsi_name: The name of the Global Secondary Index (GSI) to be created on the table.
    :param gsi_provisioned_read_units: The configured Global Secondary Index (GSI) provisioned read capacity units.
    :param gsi_provisioned_write_units: The configured Global Secondary Index (GSI) provisioned write capacity units.
    :param gsi_warm_reads: The read units per second setting for the Global Secondary Index (GSI)'s warm throughput.
    :param gsi_warm_writes: The write units per second setting for the Global Secondary Index (GSI)'s warm throughput.
    :param region_name: The AWS Region name to target. defaults to us-east-1
    """
    try:
        ddb = resource('dynamodb', region_name)
        
        # Define the table attributes
        attribute_definitions = [
            { "AttributeName": partition_key, "AttributeType": "S" },
            { "AttributeName": sort_key, "AttributeType": "S" },
            { "AttributeName": misc_key_attr, "AttributeType": "N" }
        ]
        
        # Define the table key schema
        key_schema = [
            { "AttributeName": partition_key, "KeyType": "HASH" },
            { "AttributeName": sort_key, "KeyType": "RANGE" }
        ]
        
        # Define the provisioned throughput for the table
        provisioned_throughput = {
            "ReadCapacityUnits": table_provisioned_read_units,
            "WriteCapacityUnits": table_provisioned_write_units
        }
        
        # Define the global secondary index
        gsi_key_schema = [
            { "AttributeName": sort_key, "KeyType": "HASH" },
            { "AttributeName": misc_key_attr, "KeyType": "RANGE" }
        ]
        gsi_projection = {
            "ProjectionType": "INCLUDE",
            "NonKeyAttributes": [non_key_attr]
        }
        gsi_provisioned_throughput = {
            "ReadCapacityUnits": gsi_provisioned_read_units,
            "WriteCapacityUnits": gsi_provisioned_write_units
        }
        gsi_warm_throughput = {
            "ReadUnitsPerSecond": gsi_warm_reads,
            "WriteUnitsPerSecond": gsi_warm_writes
        }
        global_secondary_indexes = [
            {
                "IndexName": gsi_name,
                "KeySchema": gsi_key_schema,
                "Projection": gsi_projection,
                "ProvisionedThroughput": gsi_provisioned_throughput,
                "WarmThroughput": gsi_warm_throughput
            }
        ]
        
        # Define the warm throughput for the table
        warm_throughput = {
            "ReadUnitsPerSecond": table_warm_reads,
            "WriteUnitsPerSecond": table_warm_writes
        }
        
        # Create the DynamoDB client and create the table
        response = ddb.create_table(
            TableName=table_name,
            AttributeDefinitions=attribute_definitions,
            KeySchema=key_schema,
            ProvisionedThroughput=provisioned_throughput,
            GlobalSecondaryIndexes=global_secondary_indexes,
            WarmThroughput=warm_throughput
        )
        
        print(response)
    except ClientError as e:
        print(f"Error creating table: {e}")
        raise e
```

------
#### [ Javascript ]

```
import { DynamoDBClient, CreateTableCommand } from "@aws-sdk/client-dynamodb";

async function createDynamoDBTableWithWarmThroughput(
  tableName,
  partitionKey,
  sortKey,
  miscKeyAttr,
  nonKeyAttr,
  tableProvisionedReadUnits,
  tableProvisionedWriteUnits,
  tableWarmReads,
  tableWarmWrites,
  indexName,
  indexProvisionedReadUnits,
  indexProvisionedWriteUnits,
  indexWarmReads,
  indexWarmWrites,
  region = "us-east-1"
) {
  try {
    const ddbClient = new DynamoDBClient({ region: region });
    const command = new CreateTableCommand({
      TableName: tableName,
      AttributeDefinitions: [
          { AttributeName: partitionKey, AttributeType: "S" },
          { AttributeName: sortKey, AttributeType: "S" },
          { AttributeName: miscKeyAttr, AttributeType: "N" },
      ],
      KeySchema: [
          { AttributeName: partitionKey, KeyType: "HASH" },
          { AttributeName: sortKey, KeyType: "RANGE" },
      ],
      ProvisionedThroughput: {
          ReadCapacityUnits: tableProvisionedReadUnits,
          WriteCapacityUnits: tableProvisionedWriteUnits,
      },
      WarmThroughput: {
          ReadUnitsPerSecond: tableWarmReads,
          WriteUnitsPerSecond: tableWarmWrites,
      },
      GlobalSecondaryIndexes: [
          {
            IndexName: indexName,
            KeySchema: [
                { AttributeName: sortKey, KeyType: "HASH" },
                { AttributeName: miscKeyAttr, KeyType: "RANGE" },
            ],
            Projection: {
                ProjectionType: "INCLUDE",
                NonKeyAttributes: [nonKeyAttr],
            },
            ProvisionedThroughput: {
                ReadCapacityUnits: indexProvisionedReadUnits,
                WriteCapacityUnits: indexProvisionedWriteUnits,
            },
            WarmThroughput: {
                ReadUnitsPerSecond: indexWarmReads,
                WriteUnitsPerSecond: indexWarmWrites,
            },
          },
      ],
    });
    const response = await ddbClient.send(command);
    console.log(response);
  } catch (error) {
    console.error(`Error creating table: ${error}`);
    throw error;
  }
}
```

------

# 了解不同场景下的 DynamoDB 热吞吐量
<a name="warm-throughput-scenarios"></a>

以下是您在使用 DynamoDB 热吞吐量时可能会遇到的一些不同场景。

**Topics**
+ [

## 热吞吐量和不均匀的访问模式
](#warm-throughput-scenarios-uneven)
+ [

## 预置表的热吞吐量
](#warm-throughput-scenarios-provisioned)
+ [

## 按需表的热吞吐量
](#warm-throughput-scenarios-ondemand)
+ [

## 配置了最大吞吐量的按需表的热吞吐量
](#warm-throughput-scenarios-max)

## 热吞吐量和不均匀的访问模式
<a name="warm-throughput-scenarios-uneven"></a>

表的热吞吐量可能为每秒 30000 个读取单位和每秒 10000 个写入单位，但在达到这些值之前，读取或写入仍可能受到节流。这可能是由于热分区造成的。虽然 DynamoDB 可以保持扩展以支持几乎无限的吞吐量，但每个分区都限制为每秒 1000 个写入单位和每秒 3000 个读取单位。如果应用程序将过多的流量带到表的一小部分分区，则甚至在达到表的热吞吐量值之前就可能发生节流。我们建议遵循 [DynamoDB 最佳实践](bp-partition-key-design.md)，以确保无缝可扩展性并避免热分区。

## 预置表的热吞吐量
<a name="warm-throughput-scenarios-provisioned"></a>

假设一个预置表，它的热吞吐量为每秒 30000 个读取单位和每秒 10000 个写入单位，但目前具有的预置吞吐量为 4000 个 RCU 和 8000 个 WCU。通过更新预置吞吐量设置，可以立即将表的预置吞吐量扩展到 30000 个 RCU 或 10000 个 WCU。当您将预置吞吐量增加到超过这些值时，热吞吐量将自动调整为新的更高值，因为您已经建立了新的峰值吞吐量。例如，如果您将预置吞吐量设置为 50000 RCU，则热吞吐量将增加到每秒 50000 个读取单位。

```
"ProvisionedThroughput": 
    {
        "ReadCapacityUnits": 4000,
        "WriteCapacityUnits": 8000 
    }
"WarmThroughput": 
    { 
        "ReadUnitsPerSecond": 30000,
        "WriteUnitsPerSecond": 10000
    }
```

## 按需表的热吞吐量
<a name="warm-throughput-scenarios-ondemand"></a>

新的按需表将以每秒 12000 个读取单位和每秒 4000 个写入单位的热吞吐量开始。表可以立即容纳高达这些级别的持续流量。当请求超过每秒 12000 个读取单位或每秒 4000 个写入单位时，热吞吐量将自动调整为更高的值。

```
"WarmThroughput": 
    { 
        "ReadUnitsPerSecond": 12000,
        "WriteUnitsPerSecond": 4000
    }
```

## 配置了最大吞吐量的按需表的热吞吐量
<a name="warm-throughput-scenarios-max"></a>

考虑一个按需表，其热吞吐量为每秒 30000 个读取单位，但[最大吞吐量](on-demand-capacity-mode-max-throughput.md)配置为 5000 个读取请求单位（RRU）。在这种情况下，表的吞吐量将限制在您设置的最大 5000 个 RRU 范围内。任何超过此最大值的吞吐量请求都将受到限制。但是，可以根据应用程序的需要，随时修改表特定的最大吞吐量。

```
"OnDemandThroughput": 
    {
        "MaxReadRequestUnits": 5000,
        "MaxWriteRequestUnits": 4000
    }
"WarmThroughput": 
    { 
        "ReadUnitsPerSecond": 30000,
        "WriteUnitsPerSecond": 10000
    }
```

# DynamoDB 容量暴增和自适应容量
<a name="burst-adaptive-capacity"></a>

为最大限度地减少因吞吐量异常而造成的节流，DynamoDB 使用*容量爆增*来应对用量峰值。DynamoDB 使用*自适应容量* 来协助适应不均匀的访问模式。

## 容量爆增
<a name="burst-capacity"></a>

DynamoDB 通过*容量暴增*，为吞吐量调配提供一定的灵活性。如果您未完全使用可用的吞吐量，DynamoDB 将为稍后的吞吐量*爆增*保留一部分未使用的容量，来应对用量峰值。利用容量暴增，意外的读取或写入请求可在原本会受限制的环境中获得成功。

DynamoDB 目前保留最多五分钟（300 秒）未使用的读取和写入容量。在读取或写入操作偶尔爆增期间，可以快速消耗这些额外容量单位 - 甚至比已经为表定义的每秒预置吞吐能力还快。

DynamoDB 还可能在不事先通知的情况下，将暴增容量用于后台维护和其他任务。

请注意，这些暴增容量详细信息未来可能发生变化。

## 自适应容量
<a name="adaptive-capacity"></a>

DynamoDB 会自动将您的数据分布到不同的[分区](HowItWorks.Partitions.md)（分区存储在 AWS 云中的多个服务器上）。不可能始终均匀地分布读取活动和写入活动。如果数据访问不平衡，“热门”分区的读取和写入量将高于其他分区。由于分区上的读取和写入操作是独立管理的，因此，如果单个分区接收 3000 次以上的读取操作或 1000 次以上的写入操作，则会发生节流。自适应容量的工作原理是，自动增加分区的吞吐容量来接收更多流量。

 为了更好地适应不均匀访问模式，DynamoDB 自适应容量允许应用程序继续对热门分区进行读写操作，而不节流，前提是流量未超出表的总预置容量或分区最大容量。自适应容量自动即时增加接收更多流量的分区的吞吐容量。

下图说明自适应性容量的工作方式。示例表配置了 400 个 WCU，均匀分布在 4 个分区，每个分区每秒可以承受最多 100 个 WCU。分区 1、2 和 3 各接收 50 WCU/秒的写入流量。分区 4 接收 150 WCU/秒。这个热门分区可以接收写入流量，同时仍具有未使用的暴增容量，但最终将节流超过 100 WCU/秒的流量。

DynamoDB 自适应容量通过增加分区 4 的容量来应对，这样可以保持 150 WCU/秒的更高工作负载，而不会节流。

![\[自适应容量会自动增加流量较高的分区 4 的吞吐量，来避免节流。\]](http://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/images/adaptive-capacity.png)


自适应容量对每个 DynamoDB 表自动启用，无附加费用。无需明确启用或禁用。

### 隔离频繁访问的项目
<a name="isolate-frequent-access-items"></a>

如果应用程序到一个或多个项目的流量特别高，自适应容量将重新平衡分区，使频繁访问的项目不在同一分区中。这种隔离频繁访问的项目的做法，可以降低因工作负荷超出单个分区上的吞吐量配额而造成请求限制的可能性。您还可以通过排序键将项目集合分为多个区段，只要项目集合不是由排序键的单调增加或减少跟踪的流量即可。

如果应用程序带来的高流量始终针对单个项目，自适应容量可能重新平衡数据，以使分区仅包含单个频繁访问的项目。在此情况下，DynamoDB 可以为这个项目的主键提供达到分区最大 3000 RCU 和 1000 WCU 的吞吐量。当表上有[本地二级索引](LSI.md)时，自适应容量不会跨表的多个分区拆分项目集合。

# 在 DynamoDB 中切换容量模式时的注意事项
<a name="bp-switching-capacity-modes"></a>

创建 DynamoDB 表时，您必须选择按需容量模式或预置容量模式。

在 24 小时滚动窗口内，表最多可以从预置容量模式切换到按需模式四次。您可以随时将表从按需模式切换到预置容量模式。

**Topics**
+ [

## 从预置容量模式切换到按需容量模式
](#switch-provisioned-to-ondemand)
+ [

## 从按需容量模式切换到预置容量模式
](#switch-ondemand-to-provisioned)

## 从预置容量模式切换到按需容量模式
<a name="switch-provisioned-to-ondemand"></a>

在预置模式下，您可以根据预期的应用程序需求设置读取和写入容量。​当您将表从预置模式更新为按需模式时，您无需指定预期应用程序执行的读写吞吐量。DynamoDB 按需模式针对读取和写入请求提供简单的按请求支付定价，以便您只需为使用的资源付费，这样就可以轻松平衡成本与性能。您可以选择为各个按需表和关联全局二级索引配置最大读取和/或写入吞吐量，来协助限制成本和用量。有关为特定表或索引设置最大吞吐量的更多信息，请参阅[DynamoDB 按需表的最大吞吐量](on-demand-capacity-mode-max-throughput.md)。

当您从预置容量模式切换到按需容量模式时，DynamoDB 会对表和分区的结构进行若干更改。此过程可能耗时数分钟。在切换期间，您的表将提供与先前预置的写入容量单位和读取容量单位数量相一致的吞吐量。

### 按需容量模式的最初吞吐量
<a name="initial-throughput-ondemand-mode"></a>

如果您最近首次将现有表切换为按需容量模式，则该表将具有下面的先前峰值设置，即使该表之前尚未使用按需容量模式提供流量也是如此。

以下是可能的场景示例：
+ **任何配置为低于 4000 WCU 和 12000 RCU 的预置表，这些表以前从未配置为更多容量单位。**当您首次将此表切换为按需模式时，DynamoDB 将确保其横向扩展到能够即时维持每秒至少 4000 个写入单位和 12000 个读取单位。
+ **配置为 8000 WCU 和 24000 RCU 的预置表。**当您将此表切换为按需模式时，它将继续能够维持在任何时候均为每秒至少 8000 个写入单位和 24000 个读取单位。
+ **配置了 8,000WCU 和 24,000RCU 的预置表，在维持期间每秒占用 6,000 个写入单位和 18,000 个读取单位。**当您将此表切换为按需模式时，它将继续能够维持为每秒至少 8000 个写入单位和 24000 个读取单位。之前的流量可能进一步允许该表维持相当高的流量水平而不节流。
+ **之前预置了 10,000WCU 和 10,000RCU，但目前预置了 10RCU 和 10WCU 的表。**当您将此表切换为按需模式时，它将能够维持每秒至少 10000 个写入单位和 10000 个读取单位。

### 自动扩缩设置
<a name="autoscaling-settings"></a>

当您将表从预置模式更新为按需模式时：
+ 如果使用控制台，则将删除您的所有自动扩缩设置（如果有）。
+ 如果您使用 AWS CLI 或 AWS SDK，则将保留您的自动扩缩设置。当您再次将表更新为预置的结算模式时，这些设置可能适用。

### 在 [DynamoDB 控制台](https://console.aws.amazon.com/dynamodb)中批量编辑容量模式
<a name="bulk-edit-capacity-mode"></a>

您可以使用 [DynamoDB 控制台](https://console.aws.amazon.com/dynamodb)批量编辑多个表，将其从预置容量模式切换到按需容量模式。要批量编辑容量模式，请执行以下操作：

1. 在 DynamoDB 控制台中，转到**表**页面。

1. 选中要更新为按需容量模式的表的复选框。

1. 选择**操作**，然后选择**更新为按需容量模式**。

通过此批量操作，您可以高效地将多个表切换到按需容量模式，而不必单独更新每个表。

## 从按需容量模式切换到预置容量模式
<a name="switch-ondemand-to-provisioned"></a>

当从按需容量模式切换回预置的容量模式时，表将提供与表设置为按需容量模式时达到的先前峰值一致的吞吐量。

### 管理容量
<a name="switch-ondemand-capacity"></a>

当您将表从按需模式更新为预置模式时，考虑以下事项：
+  如果您使用 AWS CLI 或 AWS SDK，请通过以下方式选择表和全局二级索引的适当预置容量设置：使用 Amazon CloudWatch 查看历史使用情况（`ConsumedWriteCapacityUnits` 和 `ConsumedReadCapacityUnits` 指标）以确定新的吞吐量设置。
**注意**  
如果您将全局表切换为预置模式，则在确定新的吞吐量设置时，请查阅跨基表和全局二级索引的所有区域副本的最大使用量。
+ 如果您要从按需模式切换回预置模式，请确保将初始预置单位设置得足够高，以便在过渡期间处理您的表或索引容量。

### 管理自动扩缩
<a name="switch-ondemand-autoscaling"></a>

当您将表从按需模式更新为预置模式时：
+ 如果您使用控制台，我们建议您使用以下默认值启用自动扩缩：
  + 目标利用率：70%
  + 最小预置容量：5 个单位
  + 最大预置容量：区域最大值
+  如果您使用 AWS CLI 或开发工具包，则将保留您先前的自动扩缩设置（如果有）。