我想知道为什么我的 Amazon DynamoDB 流需要这么长时间才能处理。
解决方法
当您通过 AWS Lamdba 使用 DynamoDB 流时,您的记录可能会写入表中,但不会由 Lambda 处理。这些记录甚至可能需要几个小时才能处理。要排查原因,请查看 Lambda IteratorAge 指标。
当 IteratorAge 增加时,Lambda 无法高效地处理写入到 DynamoDB 流中的记录。可能造成 IteratorAge 增加的原因如下。
调用错误
Lambda 旨在按顺序批量处理记录,当出现错误时重试。如果每次调用函数时函数都返回错误,则 Lambda 函数将继续尝试处理记录。该函数会继续尝试处理记录,直到记录过期或记录超过在事件源映射上配置的最大期限。由于流中存在的记录未被处理,IteratorAge 指标可能会出现激增。您可以检查 Lambda 错误指标中是否存在错误指标的峰值。或者,查看您的 Lambda 日志以获取详细信息。
为防止调用错误导致 IteratorAge 指标激增,请将记录发送到死信队列 (DLQ)。创建事件源映射时,为特定参数输入以下信息:
- **Retry attempts:**此参数是 lambda 函数出现错误时运行的次数。根据您的用例更新此值,并在函数重试特定次数后将记录发送到 DLQ。
- **Split batch on error:**在函数重试批量处理之前,此参数将一个批次分成两个批次。使用此参数拆分批次并以较小的批次继续调用。拆分批次可以帮助隔离导致调用错误的错误记录。
节流错误
当您使用 DynamoDB 流时,最佳做法是每个分片不超过两个使用者,以避免节流。由于 Lambda 按顺序处理记录,因此如果当前调用受到限制,Lambda 将无法继续处理记录。如果您必须使用两个以上的使用者,请使用 Amazon Kinesis 或扇出模式。或者,在 Lambda 中使用并发限制来防止节流。
Lambda 吞吐量
Lambda 吞吐量是指单次调用 lambda 函数来处理一个记录或一批记录所花费的时间。以下因素可能会影响 Lambda 函数的吞吐量:
运行时持续时间
如果持续时间指标值很高,则该函数的吞吐量很低,并导致该函数的 IteratorAge 指标增加。要缩短函数的运行时持续时间,请增加分配给函数的内存。
您还可以优化函数代码,以减少处理记录所需的时间。
Lambda 并发运行数
并发是指您的 Lambda 函数同时处理的进行中的请求数量。增加并发 Lambda 调用次数可以提高流记录的处理速度。对于每个并发请求,Lambda 会为您的执行环境预置一个单独的实例。最大 Lambda 并发运行数的计算方法如下:
并发运行数 = 分片数 x 每个分片的并发批次数(并行化系数)
在 DynamoDB 流中,表的分区数和流分片的数量之间存在一对一的映射。分区的数量由表的大小及其吞吐量决定。表上的每个分区最多可以提供 3,000 个读取请求单元或 1,000 个写入请求单元,或者二者的线性组合。因此,要提高并发数,请增加表的预置容量以增加分片的数量。您可以在事件源映射中配置每个分片的并发批次数。默认值为 1,最多可以增加到 10。例如,如果表内有 10 个分区,并且每个分片的并发批次数设置为 5,则并发运行数最多可达 50。
要在任何给定时间以正确的顺序处理项目级修改,具有相同分区键的项目应划分到同一批次。您的表分区键必须具有高基数,并且您的流量无法生成热密钥。例如,如果将每个分片的并发批次数值设置为 10,并且写入流量以单个分区键为目标,则每个分片的并发运行数只能为 1。
批次大小和批处理窗口
如果调整不正确,Lambda 批处理行为可能会降低函数的吞吐量。要优化 DynamoDB 流的处理,请根据您的用例调整批处理窗口和批次大小。
如果批次大小设置的值太低,则会使用少量记录频繁调用该函数。这些频繁的调用会减慢流的处理速度。如果批次大小值设置得过高,则您的函数持续时间可能会延长。
如果批处理窗口的值和该窗口中的记录数未得到优化,您可能会不必要地调用同一个分片。这些不必要的调用会减慢流的处理速度。如果批处理窗口值过高,则可能需要等待更长的时间才能让该函数处理流。更长的处理时间会增加 IteratorAge。
要提高吞吐量并降低 IteratorAge,最佳做法是测试批处理窗口和批次大小的多种组合。
相关信息
性能指标
Understanding Lambda scaling and throughput
了解 Lambda 函数扩展
使用 DynamoDB Streams Amazon Kinesis Adapter 处理流记录
DynamoDB Streams 和 Lambda 触发器