为什么我的 Amazon DynamoDB streams 的 Lambda IteratorAge 指标会增加?

上次更新日期:2022 年 9 月 12 日

在使用我的 Amazon DynamoDB 流中的记录时,我看到 AWS Lambda IteratorAge 指标出现了激增。为什么我的函数的迭代器年龄在增加,我如何解决这个问题?

简短描述

Lambda IteratorAge 指标将记录添加到 DynamoDB 流与函数处理该记录之间的延迟。当 IteratorAge 增加时,这意味着 Lambda 无法高效地处理写入 DynamoDB 流的记录。

以下是 IteratorAge 增加的主要原因:

  • 调用错误
  • 出现节流情况
  • Lambda 吞吐量低

解决方法

调用错误

Lambda 旨在按顺序处理批量记录,并在出现错误时重试。因此,如果函数每次被调用时都返回错误,则 Lambda 将继续重试。它会一直执行此操作,直到记录过期或超过您在事件源映射上配置的最大期限。DynamoDB 流的保留期为 24。Lambda 会持续重试长达一天,直到记录过期,然后转到下一批记录。

检查 Lambda 错误指标以确认调用错误是否是 IteratorAge 峰值的根本原因。如果是这样,请检查 Lambda 日志以调试错误,然后修改您的代码。处理错误时,请确保在代码中包含 try-catch 语句。

事件源映射配置中有三个参数可以帮助您防止 IteratorAge 出现峰值:

  • 重试次数:当函数返回错误时,Lambda 重试的最大次数。
  • 最长记录期限 — Lambda 发送到您的函数的记录的最大期限。这可以帮助您丢弃过旧的记录。
  • 出错时拆分批处理 — 当函数返回错误时,请在重试之前将批次分成两部分。使用较小的批次重试可以隔离不良记录并解决超时问题。注意:拆分批次不计入重试配额。

要保留丢弃的事件,请配置事件源映射,将失败批次的详细信息发送到 Amazon Simple Queue Service (Amazon SQS) 队列。或者,配置偶数源映射以将详细信息发送到 Amazon Simple Notification Service (Amazon SNS) 主题。为此,请使用故障时目标参数。

出现节流情况

因为事件记录是按顺序读取的,所以如果当前调用被限制,Lambda 函数将无法前进到下一个记录。

使用 DynamoDB 流时,不要在同一个流分片上配置两个以上的使用者。如果每个分片有两个以上的读取器,这可能会导致节流。如果您在单个流分片上需要两个以上的读取器,请使用扇出模式。配置 Lambda 函数以使用流中的记录,然后将其转发到其他下游 Lambda 函数或 Amazon Kinesis 流。

在 Lambda 端,使用并发限制来防止节流。

Lambda 吞吐量

运行时持续时间

如果 Lambda 函数的持续时间指标较高,则会降低该函数的吞吐量并增加 IteratorAge。

要减少函数的运行时持续时间,请使用以下一种或两种方法:

1.    增加分配给函数的内存量

2.    优化函数代码,以便减少处理记录所需的时间。

并发 Lambda 运行

并发 Lambda 运行的最大数量计算如下:

并发运行 = 分片数 x 每个分片的并发批次(并行系数)

  • 分片数 - 在 DynamoDB 流中,表的分区数和流分片数之间有 1<>1 的映射。分区的数量由表的大小及其吞吐量决定。表中的每个分区最多可提供 3,000 个读请求单位或 1,000 个写请求单位,或此两者的线性组合。因此,要提高并发性,请通过增加表的预配置容量来增加分片的数量。
  • 每个分片的并发批处理(并行化因子) - 您可以在事件源映射中配置每个分片的并行批处理数。默认值为 1,最多可增加到 10。

例如,如果表有 10 个分区,并且每个分片的并发批次数设置为 5,那么您最多可以有 50 个并发运行。

注意:要在任何给定时间以正确的顺序处理项目级别修改,具有相同分区键的项目将转到同一个批次。因此,请确保您的表分区键具有较高的基数,并且您的流量不会生成热键。例如,如果您将每个分片的并发批次数值设置为 10,并且您的写入流量以一个分区键为目标,则每个分片只能有一个并发运行。

批处理大小

调整批量大小值有助于提高 Lambda 吞吐量。如果每批处理的记录数量较少,则会减慢流的处理速度。

另一方面,如果每个批次的记录数很多,这可能会延长函数运行的持续时间。因此,使用多个值进行测试以找到最适合您的用例的值。

如果函数的运行时持续时间与事件中的记录数无关,则增加函数的批处理大小会缩短函数的迭代器年限。