

# 评估 DynamoDB 流使用情况
<a name="CostOptimization_StreamsUsage"></a>

本节概述如何评估您的 DynamoDB Streams 使用情况。有些使用模式对于 DynamoDB 来说不是最佳的，在性能和成本方面还有优化的空间。

对于流式传输和事件驱动的使用场景，您有两个原生流式传输集成：
+ [Amazon DynamoDB Streams](Streams.md) 
+ [Amazon Kinesis Data Streams](Streams.KCLAdapter.md) 

本页仅侧重介绍这些选项的成本优化策略。如果您只是想知道如何在这两个选项之间作出选择，请参阅 [更改数据捕获的流式传输选项](streamsmain.md#streamsmain.choose)。

**Topics**
+ [优化 DynamoDB Streams 的成本](#CostOptimization_StreamsUsage_Options_DDBStreams)
+ [优化 Kinesis Data Streams 的成本](#CostOptimization_StreamsUsage_Options_KDS)
+ [两种 Streams 使用模式的成本优化策略](#CostOptimization_StreamsUsage_GuidanceForBoth)

## 优化 DynamoDB Streams 的成本
<a name="CostOptimization_StreamsUsage_Options_DDBStreams"></a>

正如 DynamoDB Streams 的[定价页面](https://aws.amazon.com/dynamodb/pricing/on-demand/)所述，无论表的吞吐能力模式，DynamoDB 都基于对表的 DynamoDB Stream 的读取请求量来收费。对 DynamoDB Stream 的读取请求与对 DynamoDB 表的读取请求不同。

对 Stream 的每个读取请求采用的是 `GetRecords` API 调用形式，响应中可以返回最多 1000 条记录或 1MB 的记录，以先到达者为准。[其他 DynamoDB Stream API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html) 均不收费，也不对闲置的 DynamoDB Streams 收费。换言之，如果不对 DynamoDB Stream 发出读取请求，则表上启用了 DynamoDB Stream 并不会产生任何费用。

以下是 DynamoDB Streams 的一些使用器应用程序：
+ AWS Lambda 函数
+ 基于 Amazon Kinesis Data Streams 的应用程序
+ 使用 AWS SDK 构建的客户使用器应用程序

由 DynamoDB Streams 的基于 AWS Lambda 的使用器发出的读取请求是免费的，而由任何其他类型的使用器发出的调用都是收费的。每个月，由非 Lambda 使用器发出的前 250 万次读取请求也是免费的。这适用于每个 AWS 区域的一个 AWS 账户中对于任何 DynamoDB Streams 发出的所有读取请求。

**监控您的 DynamoDB Streams 使用情况**  
在账单控制台上，AWS 区域内一个 AWS 账户中的所有 DynamoDB Streams 费用集中组成一组。目前，暂不支持标记 DynamoDB Streams，因此不能使用成本分配标签来进一步细分 DynamoDB Streams 的成本。可以获得 DynamoDB Stream 级别的 `GetRecords` 调用量来计算每个流的费用。该调用量用 DynamoDB Stream 的 CloudWatch 指标 `SuccessfulRequestLatency` 及其 `SampleCount` 统计数据来表示。该指标还将包括全局表为执行持续复制而进行的 `GetRecords` 调用，以及 AWS Lambda 使用器进行的调用，两者均不收费。有关 DynamoDB Streams 发布的其他 CloudWatch 指标的信息，请参阅 [DynamoDB 指标与维度](metrics-dimensions.md)。

**使用 AWS Lambda 作为使用器**  
评估使用 AWS Lambda 函数作为 DynamoDB Streams 的使用器是否可行，因为这可以消除与读取 DynamoDB Stream 相关的成本。另一方面，对于基于 DynamoDB Streams Kinesis Adapter 或 SDK 的使用器应用程序，将根据它们对 DynamoDB Stream 的 `GetRecords` 调用次数来收费。

将根据标准 Lambda 定价对 Lambda 函数调用收费，但是 DynamoDB Streams 不会产生任何费用。Lambda 将以每秒 4 次的基本频率轮询 DynamoDB Stream 中的分片来获取记录。如果记录可用，Lambda 会调用函数并等待结果。如果处理成功，Lambda 会恢复轮询，直到其收到更多记录。

**调整基于 DynamoDB Streams Kinesis Adapter 的使用器应用程序**  
因为对基于非 Lambda 的使用器发出的读取请求要收取 DynamoDB Streams 费用，所以，如何在近实时要求和使用者应用程序必须轮询 DynamoDB Stream 的次数之间找到一个平衡点非常重要。

使用基于 DynamoDB Streams Kinesis Adapter 的应用程序轮询 DynamoDB Streams 的频率由配置的 `idleTimeBetweenReadsInMillis` 值决定。该参数决定了使用器在对某个分片的 `GetRecords` 调用未返回任何记录时，需等待多久（以毫秒为单位）才能再次处理该分片。该参数的默认值为 1000ms。如果不需要近实时处理，则可以提高该参数值，以减少使用器应用程序的 `GetRecords` 调用次数，并对 DynamoDB Streams 调用进行优化。

## 优化 Kinesis Data Streams 的成本
<a name="CostOptimization_StreamsUsage_Options_KDS"></a>

将一个 Kinesis Data Stream 设置为目的地来传送 DynamoDB 表的变化数据捕获事件时，该 Kinesis Data Stream 可能需要单独的规模调整管理，而这将影响总体成本。DynamoDB 费用按变化数据捕获单位 (CDU) 来收取，每个单位由 DynamoDB 服务向目的地 Kinesis Data Stream 尝试传送的一个 DynamoDB 项目（大小最多 1KB）构成。

除了 DynamoDB 服务费用，还将产生标准 Kinesis Data Stream 费用。如[定价页面](https://aws.amazon.com/kinesis/data-streams/pricing/)所述，服务定价因容量模式（预置和按需模式）而异，这种容量模式与 DynamoDB 表容量模式不同，它们是由用户定义的。概言之，Kinesis Data Streams 费用是一种小时费率，基于容量模式以及 DynamoDB 服务摄取到流中的数据量。根据用户对 Kinesis Data Stream 的配置，可能会存在其他费用，例如数据检索（对于按需模式）、数据留存时间延长（超过默认的 24 小时）和增强的扇出式使用器检索等。

**监控 Kinesis Data Streams 使用情况**  
除了标准的 Kinesis Data Stream CloudWatch 指标外，Kinesis Data Streams for DynamoDB 还发布了来自 DynamoDB 的指标。DynamoDB 服务的 `Put` 尝试受到 Kinesis 服务节流（因 Kinesis Data Streams 容量不足），或者受到依赖组件（例如可能配置为加密静态 Kinesis Data Stream 数据的 AWS KMS 服务）节流是有可能的。

要了解 DynamoDB 服务针对 Kinesis Data Stream 发布的 CloudWatch 指标的更多信息，请参阅 [使用 Kinesis Data Streams 监控更改数据捕获](kds_using-shards-and-metrics.md#kds_using-shards-and-metrics.monitoring)。为避免因节流而导致额外的服务重试费用，在预置模式下适当调整 Kinesis Data Stream 的大小非常重要。

**为 Kinesis Data Streams 选择适当的容量模式**  
Kinesis Data Streams 有两种受支持的容量模式 - 预置模式和按需模式。
+ 如果涉及 Kinesis Data Stream 的工作负载具有可预测的应用程序流量、稳定或逐渐增加的流量或者可以准确预测的流量，那么选择 Kinesis Data Streams **预置模式**合适，并且具有较好的成本效益
+ 如果工作负载是新的，具有不可预测的应用程序流量，或者您不想管理容量，那么 Kinesis Data Streams 的**按需模式**合适，并且具有较好的成本效益

优化成本的一种最佳实践是，评估与 Kinesis Data Stream 关联的 DynamoDB 表是否具有可预测的流量模式，且该模式可以利用 Kinesis Data Streams 的预置模式。如果工作负载是新的，则您可以在最初的几周使用 Kinesis Data Streams 的按需模式，查看 CloudWatch 指标以了解流量模式，然后根据工作负载的性质将相同的 Stream 切换到预置模式。在预置模式下，遵循 Kinesis Data Streams 的分片管理注意事项来估算分片数量。

**使用 Kinesis Data Streams for DynamoDB 评估使用器应用程序**  
由于 Kinesis Data Streams 不对像 DynamoDB Streams 这样的 `GetRecords` 调用收费，所以使用器应用程序可以进行任意次调用，但前提是频率低于 `GetRecords` 的节流限制。在 Kinesis Data Streams 的按需模式下，按 GB 量收取数据读取费。对于 Kinesis Data Streams 的预置模式，如果数据存储时间少于 7 天，则不收取读取费用。当 Lambda 函数作为 Kinesis Data Streams 使用器时，Lambda 按每秒一次的基本频率轮询 Kinesis Stream 中的每个分片以获取记录。

## 两种 Streams 使用模式的成本优化策略
<a name="CostOptimization_StreamsUsage_GuidanceForBoth"></a>

**用于 AWS Lambda 使用器的事件筛选**  
Lambda 事件筛选允许您基于筛选条件丢弃 Lambda 函数调用批处理中的事件。这将优化在使用者函数逻辑中处理或丢弃不需要的流记录的 Lambda 成本。要了解有关配置事件筛选和编写筛选条件的更多信息，请参阅 [Lambda 事件筛选](https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventfiltering.html)。

**调整 AWS Lambda 使用器**  
可以通过调整 Lambda 配置参数来进一步优化成本，例如提高 `BatchSize` 来增加每次调用的处理量，启用 `BisectBatchOnFunctionError` 来防止处理重复项（这会产生额外成本），以及设置 `MaximumRetryAttempts` 以免过多重试。默认情况下，失败的使用器 Lambda 调用会重试无限次，直到记录在流中过期，对于 DynamoDB Streams，记录的过期时间大约为 24 小时，对于 Kinesis Data Streams，过期时间可以配置为从 24 小时到最长 1 年。有关其他可用的 Lambda 配置选项，包括上面提到的 DynamoDB Stream 使用器的配置选项，请参阅 [AWS Lambda 开发人员指南](https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html#services-ddb-params)。