

# 将更改数据捕获用于 DynamoDB Streams
<a name="Streams"></a>

 DynamoDB Streams 可在任何 DynamoDB 表中捕获按时间排序的项目级修改序列，并将这类信息存储在日志中长达 24 个小时。应用程序可访问此日志，并在数据项目修改前后近乎实时地查看所显示的数据项目。

 静态加密会加密 DynamoDB 流中的数据。有关更多信息，请参阅 [静态 DynamoDB 加密](EncryptionAtRest.md)。

*DynamoDB 流*是一种有关 DynamoDB 表中的项目更改的有序信息流。当您对表启用流时，DynamoDB 将捕获有关对表中的数据项目进行的每项修改的信息。

每当应用程序在表中创建、更新或删除项目时，DynamoDB Streams 都将编写一条具有已修改项目的主键属性的流记录。*流记录*包含有关对 DynamoDB 表中的单个项目所做的数据修改的信息。您可以配置流，以便流记录捕获其他信息，例如已修改项目的“前”和“后”图像。

DynamoDB Streams 可以帮助确保：
+ 每个流记录仅在流中显示一次。
+ 对于 DynamoDB 表中修改的每个项目，流记录将按照对该项目进行的实际修改的顺序显示。

DynamoDB Streams 近乎实时编写流记录，以便您能构建使用这些流并根据内容采取操作的应用程序。

**Topics**
+ [DynamoDB Streams 的端点](#Streams.Endpoints)
+ [启用流](#Streams.Enabling)
+ [读取和处理流](#Streams.Processing)
+ [DynamoDB Streams 和生存时间](time-to-live-ttl-streams.md)
+ [使用 DynamoDB Streams Kinesis Adapter 处理流记录](Streams.KCLAdapter.md)
+ [DynamoDB Streams 低级 API：Java 示例](Streams.LowLevel.Walkthrough.md)
+ [DynamoDB Streams 和 Amazon Lambda 触发器](Streams.Lambda.md)
+ [DynamoDB Streams 和 Apache Flink](StreamsApacheFlink.xml.md)

## DynamoDB Streams 的端点
<a name="Streams.Endpoints"></a>

Amazon 为 DynamoDB 和 DynamoDB Streams 维护单独的端点。要使用数据库表和索引，您的应用程序必须访问 DynamoDB 端点。要读取和处理 DynamoDB Streams 记录，您的应用程序必须访问相同区域内的 DynamoDB Streams 端点。

**注意**  
有关 DynamoDB 和 DynamoDB Streams 区域和端点的完整列表，请参阅《Amazon Web Services 一般参考》**中的[区域和端点](https://docs.amazonaws.cn/general/latest/gr/rande.html)。

Amazon SDK 为 DynamoDB 和 DynamoDB Streams 提供单独的客户端。根据您的要求，您的应用程序可以访问 DynamoDB 端点，DynamoDB Streams 端点或同时访问二者。要连接到两个端点，您的应用程序必须实例化两个客户端 — 一个用于 DynamoDB，另一个用于 DynamoDB Streams。

## 启用流
<a name="Streams.Enabling"></a>

使用 Amazon CLI 或某个 Amazon SDK 创建新表时，可以在新表上启用流。还可以对现有表启用或禁用流，或更改流设置。DynamoDB Streams 可异步执行操作，因此在启用流的情况下不会影响表的性能。

管理 DynamoDB Streams 最简单的方法是使用 Amazon Web Services 管理控制台。

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

1. 在 DynamoDB 控制台控制面板上，选择**表**，然后选择现有表。

1. 选择**导出和流式传输**选项卡。

1. 在 **DynamoDB 流详细信息**部分，选择**开启**。

1. 在**开启 DynamoDB 流**页面中，选择在修改表中的数据时将写入流中的信息：
   + **仅键** — 仅所修改项目的键属性。
   + **新映像** — 修改后的整个项目。
   + **旧映像** — 修改前的整个项目。
   + **新旧映像** — 项目的新旧映像。

   根据需要进行设置后，选择**开启流**。

1. （可选）要禁用现有流，请选择 **DynamoDB 流详细信息**下的**关闭**。

您还可以使用 `CreateTable` 或 `UpdateTable` API 操作来启用或修改流。`StreamSpecification` 参数确定如何配置流：
+ `StreamEnabled` — 指定对表启用 (`true`) 或禁用 (`false`) 流。
+ `StreamViewType` — 指定在修改表中的数据时将写入流中的信息：
  + `KEYS_ONLY` — 仅所修改项目的键属性。
  + `NEW_IMAGE` — 整个项目在修改后的显示。
  + `OLD_IMAGE` — 整个项目在修改前的显示。
  + `NEW_AND_OLD_IMAGES` — 项目的新旧映像。

您可以随时启用或禁用流。但是，如果您尝试在已有流的表上启用流，则会收到 `ValidationException`。如果您尝试在没有流的表上禁用流，也会收到 `ValidationException`。

当您将 `StreamEnabled` 设置为 `true` 时，DynamoDB 将创建一个新流，并为其分配一个唯一的流描述符。如果您在表上禁用然后重新启用流，则将创建一个具有不同流描述符的新流。

每个流均由一个 Amazon 资源名称（ARN）进行唯一标识。以下是名为 `TestTable` 的 DynamoDB 表中一个流的示例 ARN。

```
arn:aws:dynamodb:us-west-2:111122223333:table/TestTable/stream/2015-05-11T21:21:33.291
```

要确定表的最新流描述符，请发出一个 DynamoDB `DescribeTable` 请求并在响应中查找 `LatestStreamArn` 元素。

**注意**  
一旦设置了流，就无法编辑 `StreamViewType`。如果您需要在设置流后对其进行更改，则必须禁用当前流并创建一个新的流。

## 读取和处理流
<a name="Streams.Processing"></a>

要读取和处理流，您的应用程序必须连接到 DynamoDB Streams 端点并发出 API 请求。

流由*流记录* 构成。每条流记录均代表流所在的 DynamoDB 表中的一个数据修改。每条流记录均分配有一个序列号，该序列号反映了将记录发布至流的顺序。

流记录将组织到群组或*分区* 中。每个分区可充当多条流记录的容器，并包含访问和迭代这些记录所需的信息。分区中的流记录将在 24 小时后自动删除。

分区是临时的：将根据需要自动创建和删除它们。此外，任何分区均可拆分为多个新分区；这也是自动进行的。（请注意，父分片还可能只有一个子分片。） 分区可能会在响应其父表上的高级写入活动时拆分，以便应用程序可以并行处理来自多个分区的记录。

如果您禁用流，将关闭已打开的分区。流中的数据在 24 小时内可继续读取。

由于分区存在沿袭 (父分区和子分区)，应用程序必须始终先处理父分区，然后再处理子分区。这可帮助确保流记录也会按正确顺序进行处理。（如果您使用 DynamoDB Streams Kinesis Adapter，则会为您进行处理。您的应用程序按正确顺序处理分片和流记录。它自动处理新分片或过期分片，以及在应用程序运行期间拆分的分片。有关更多信息，请参阅[使用 DynamoDB Streams Kinesis Adapter 处理流记录](Streams.KCLAdapter.md)。）

下图显示流、流中的分区和分区中的流记录之间的关系。

![\[DynamoDB Streams 结构。表示数据修改的流记录以分片的形式加以组织。\]](http://docs.amazonaws.cn/amazondynamodb/latest/developerguide/images/streams-terminology.png)


**注意**  
如果您执行的 `PutItem` 或 `UpdateItem` 操作不更改项目中的任何数据，则 DynamoDB Streams *不会*为该操作编写流记录。

要访问流和处理其中的流记录，您必须执行以下操作：
+ 确定您要访问的流的唯一 ARN。
+ 确定流中的哪些分片包含您感兴趣的流记录。
+ 访问分片并检索所需的流记录。

**注意**  
从同一流的分片中同时读取的进程最多不得超过 2 个。读取器超过 2 个的分片可能会受到限制。

DynamoDB Streams API 提供以下操作以供应用程序使用：
+  `[ListStreams](https://docs.amazonaws.cn/amazondynamodb/latest/APIReference/API_streams_ListStreams.html)` — 返回当前账户和端点的流描述符列表。(可选) 您可以只请求特定表名称的流描述符。
+ `[DescribeStream](https://docs.amazonaws.cn/amazondynamodb/latest/APIReference/API_streams_DescribeStream.html)`：返回有关流的信息，包括流的当前状态、其 Amazon 资源名称（ARN）、其分片的构成及其相应的 DynamoDB 表。您可以选择使用 `ShardFilter` 字段来检索与父分片关联的现有子分片。
+ `[GetShardIterator](https://docs.amazonaws.cn/amazondynamodb/latest/APIReference/API_streams_GetShardIterator.html)` — 返回一个描述分片中位置的*分片迭代器*。您可以请求该迭代器提供对流中最旧的点、最新的点或某个特定点的访问权。
+ `[GetRecords](https://docs.amazonaws.cn/amazondynamodb/latest/APIReference/API_streams_GetRecords.html)` — 返回来自给定分片中的流记录。您必须提供从 `GetShardIterator` 请求中返回的分区迭代器。

有关这些 API 操作的完整描述（包括示例请求和响应），请参阅[Amazon DynamoDB Streams API 参考](https://docs.amazonaws.cn/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB_Streams.html)。

### 分片发现
<a name="Streams.ShardDiscovery"></a>



使用两种强有力的方法在您的 DynamoDB 流中发现新的分片。作为 Amazon DynamoDB Streams 用户，您可以通过两种有效的方法来跟踪和识别新的分片：

**轮询整个流拓扑**  
使用 `DescribeStream` API 定期对流进行轮询。这将返回流中的所有分片，包括已创建的任何新分片。通过比较一段时间内的结果，您可以检测到新添加的分片。

**发现子分片**  
使用 `DescribeStream` API 及 `ShardFilter` 参数来查找分片的子集。通过在请求中指定父分片，DynamoDB Streams 将返回其直接子分片。当只需跟踪分片沿袭而不需要扫描整个流时，这种方法很有用。  
使用来自 DynamoDB Streams 的数据的应用程序可以使用此 `ShardFilter` 参数，高效地从读取已关闭的分片过渡到其子分片，从而避免重复调用 `DescribeStream` API 来检索和遍历所有已关闭和打开的分片的分片映射。这有助于在父分片关闭后快速发现子分片，从而提高流处理应用程序的响应速度和成本效益。

这两种方法都能让您随时掌握 DynamoDB Streams 不断演变的结构，确保您不会错过任何关键的数据更新或分片修改。

### DynamoDB Streams 的数据留存限制
<a name="Streams.DataRetention"></a>

DynamoDB Streams 中所有数据的生命周期为 24 小时。您可以检索和分析任意给定表过去 24 小时的活动。但是，24 小时之前的数据可能会随时被修剪（删除）。

如果您对某个表禁用一个流，该流中的数据仍在 24 小时内可读。此时间过后，数据将过期，并且流记录将自动被删除。没有手动删除现有流的机制。您必须等待直至保留期限过期（24 小时），然后将删除所有流记录。