排查 Kinesis Data Streams 使用者的问题 - Amazon Kinesis Data Streams
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

排查 Kinesis Data Streams 使用者的问题

使用 Kinesis 客户端库时,会跳过某些 Kinesis Data Streams 记录

跳过记录的最常见原因是未处理从 processRecords 引发的异常。Kinesis 客户端库 (KCL) 依赖您的processRecords代码来处理处理数据记录时出现的任何异常。抛出的processRecords任何异常都会被 KCL 吸收。为避免重复失败时无限次重试,KCL 不会重新发送异常发生时处理的批记录。然后,KCL 在不重新启动记录处理器的情况下调processRecords用下一批数据记录。这有效地导致使用者应用程序观察到跳过的记录。要防止跳过记录,请适当处理 processRecords 中的所有异常。

属于同一分片的记录通过不同的记录处理器同时处理

对于任何正在运行的 Kinesis 客户端库 (KCL) 应用程序,一个分区只有一个所有者。但是,多个记录处理器可以临时处理同一分片。如果工作服务器实例断开网络连接,KCL 会假定无法访问的工作线程在故障转移时间到期后不再处理记录,并指示其他工作程序实例接管。在一段很短的时间内,新的记录处理器和来自无法联系的工作程序的记录处理器可能都会处理来自同一个分片的数据。

您应该根据您的应用程序设置适当的故障转移时间。对于低延迟应用程序,默认值 10 秒可以代表您可以等待的最长时间。但是,在一些情况下,如您预计会有一些连接问题(如跨地理区域打电话)并且连接可能较频繁地中断时,这个数字设置可能就过低了。

您的应用程序应预料到并处理这种情况,尤其是因为网络连接通常会恢复到之前无法访问的工作程序。如果一个记录处理器让另一个记录处理器接手其分片,它必须处理以下两种情况才能顺利执行关闭:

  1. 当前对的调用完成后,KCL 会调用记录处理器上的关闭方法,关闭原因为 “ZOMBIE”。processRecords您的记录处理器应视情况清除所有资源然后退出。

  2. 当你试图从 “僵尸” 工作人员那里检查点时,KCL 会投掷ShutdownException。收到此异常后,您的代码应完全退出当前方法。

有关更多信息,请参阅 处理重复记录

使用者应用程序的读取速率比预期的慢

读取吞吐量低于预期的最常见原因如下:

  1. 多个使用者应用程序的总读取量超过每个分片的限制。有关更多信息,请参阅 配额和限制。在此情况下,增加 Kinesis 数据流中的分片数量。

  2. 指定GetRecords每次呼叫的最大数量的限制可能已配置为较低的值。如果您正在使用 KCL,您可能已经使用一个较低的 maxRecords 属性值配置了工作程序。一般来说,我们推荐对此属性使用系统默认值。

  3. 出于很多可能的原因,您的 processRecords 调用内的逻辑花费的时间可能超过预期;该逻辑可能是 CPU 使用率高、I/O 阻止或同步出现瓶颈。要测试是否如此,请对空的记录处理器进行测试运行并比较读取吞吐量。有关如何跟踪传入数据的信息,请参阅重新分片、扩展和并行处理

如果您只有一个使用器应用程序,那么读取速率比放入速率至少高两倍始终是可能的。这是因为您最多可以每秒写入 1000 条记录进行写入 (包括分片键) 的最大总数据写入速率为 1 MB。每个打开的分区每秒最多支持 5 个事务读取,最大总数据读取速率为每秒 2 MB。请注意,每次读取(GetRecords 调用)都将获取一批记录。GetRecords 返回的数据的大小因分片的使用率而异。GetRecords可以返回的数据的最大大小为 10 MB。如果某个调用返回了该限制,在接下来 5 分钟内进行的后续调用将引发 ProvisionedThroughputExceededException

GetRecords 即使流中有数据,也返回空记录数组

使用或获取记录是一种拉取模型。开发人员应该连续循环调用 GetRecords,不退缩。每个 GetRecords 调用还将返回一个 ShardIterator 值,该值必须在循环的下一个迭代中使用。

GetRecords 操作不会阻止。相反,它将立即返回一些相关数据记录或一个空的 Records 元素。在两种情况下,将返回空的 Records 元素:

  1. 目前分片中没有更多数据.

  2. ShardIterator 指向的分片部分附近没有数据。

后一种情况很微妙,但却是避免在检索数据时搜寻时间无止境(延迟)的一种必要的设计折衷。因此,流使用应用程序应循环并调用 GetRecords,并且理所当然地处理空记录。

在生产场景中,仅当 NextShardIterator 值为 NULL 时,才应退出连续循环。当 NextShardIteratorNULL 时,这意味着当前分片已关闭,ShardIterator 值的指向应越过最后一条记录。如果使用应用程序从不调用 SplitShardMergeShards,分片将保持打开状态,并且对 GetRecords 的调用从不返回为 NextShardIteratorNULL 值。

如果您使用 Kinesis 客户端库 (KCL),则上述消费模式是为您抽象出来的。这包括自动处理一组动态变化的分片。使用 KCL,开发人员仅提供处理传入记录的逻辑。这是可能的,因为该库会为您连续调用 GetRecords

分片迭代器意外过期

每个 GetRecords 请求返回新的分片迭代器(作为 NextShardIterator),然后您可以将其用于下一个 GetRecords 请求(作为 ShardIterator)。此分片迭代器一般来说不会在您使用前过期。不过,您可能会发现,由于您超过 5 分钟没有调用 GetRecords,或者您执行了使用器应用程序的重新启动操作,该分片迭代器会过期。

如果分片迭代器在使用之前立即过期,则可能表明 Kinesis 使用的 DynamoDB 表没有足够的容量来存储租赁数据。如果您的分片数量很多,则很可能发生这种情况。要解决此问题,请增加分配给分片表的写入容量。有关更多信息,请参阅 使用租赁表跟踪 KCL 消费者应用程序处理的碎片

使用者记录处理滞后

对于大多数使用案例,使用者应用程序从流中读取最新数据。在特定情况下,使用者读取可能会滞后,而您可能并不希望出现这种情况。在确定您的使用者读取滞后多久后,请查看使用者滞后的最常见原因。

GetRecords.IteratorAgeMilliseconds 指标开始,该指标跟踪流中所有分片和使用者的读取位置。请注意,如果迭代器的期限超过了保留期的 50%(默认情况下为 24 小时,最多可配置 365 天),则存在因记录过期而丢失数据的风险。一种快速的权宜之计是增加保留期。这会在您进一步对问题进行故障排除时防止重要数据丢失。有关更多信息,请参阅 使用 Amazon CloudWatch 监控 Amazon Kinesis Data Streams。接下来,使用 Kinesis Client Library (KCL) 发出的自定义 CloudWatch 指标,确定您的消费者应用程序在读取每个分片时落后了多远MillisBehindLatest。有关更多信息,请参阅 使用 Amazon CloudWatch 监控 Kinesis 客户端库

下面是使用者滞后的最常见原因:

  • GetRecords.IteratorAgeMillisecondsMillisBehindLatest 突然发生大幅提升,通常表明临时性问题,例如下游应用程序的 API 操作失败。如果任何一个指标持续指示此行为,您应该调查这些突然增长的原因。

  • 这些指标的逐步增大表明,由于处理记录的速度不够快,使用者无法与流保持同步。此行为最常见的根本原因是没有足够的物理资源,或者记录处理逻辑没有随着流吞吐量的增大而进行扩展。您可以通过查看 KCL 发出的与processTask操作相关的其他自定义 CloudWatch指标(包括RecordProcessor.processRecords.TimeSuccess、和)来验证此行为RecordsProcessed

    • 如果您发现与吞吐量上升相关的 processRecords.Time 指标发生增长,则应该分析记录处理逻辑,以确定为什么逻辑没有随吞吐量的增长而扩展。

    • 如果您发现与吞吐量上升无关的 processRecords.Time 值发生增长,请检查您是否在关键路径中执行了任何阻塞性调用,这通常会导致记录处理速度下降。替代方法是通过增加分片数来提高并行度。最后,请确认需求高峰期间在底层处理节点上,您有足够数量的物理资源(内存、CPU 使用率等)。

未授权的 KMS 主密钥权限错误

当使用者应用程序从加密流读取但没有 KMS 主密钥的权限时,会发生此错误。要向应用程序分配访问 KMS 密钥的权限,请参阅在 KMS 中使用密钥策略和在Amazon KMS 中使用 IAM 策略。Amazon

为消费者提供的常见问题、疑问和疑难解答建议