如何检测和排查 Kinesis Data Streams 中的 ReadProvisionedThroughputExceeded 异常?

上次更新时间:2020 年 9 月 18 日

我在 Amazon Kinesis Data Streams 中遇到了 ReadProvisionedThroughputExceeded 错误。为什么会发生这种情况?如何排查此问题?

简短描述

GetRecords 调用被 Kinesis Data Streams 持续限制时,将会发生 ReadProvisionedThroughputExceeded 错误。

如果超过了以下限制,您的 Amazon Kinesis 数据流可能会被限流:

  • 每个分片可支持每秒最多 5 个事务(或每个分片 5 个 GetRecords 调用/秒)。
  • 每个分片可支持的最高读取速率为 2MiB/s。
  • GetRecords 在每个调用中可从单个分片检索最多 10MiB 的数据,每个调用最多 10000 个记录。如果调用 GetRecords 后返回了 10MiB 的数据,则在接下来 5 秒内进行的后续调用将产生错误。

如果您遇到 ReadProvisionedThroughputExceeded 错误,请考虑以下方法:

  • 确定问题的根本原因。
  • 确定可能的微爆流。
  • 遵循 Kinesis Data Streams 最佳实践。

解决方法

确定问题的根本原因

要确定 Data Streams 中出现 ReadProvisionedThroughputExceeded 错误的根本原因,通过 Amazon CloudWatch 监控 Amazon Kinesis Data Streams 服务。请注意 CloudWatch 中的以下指标:

  • GetRecords.Bytes:在指定时段内测得的从 Kinesis 数据流检索的字节数。
  • GetRecords.Records:指定时段内从 Kinesis 数据流检索的记录数量。
  • ReadProvisionedThroughputExceeded:Kinesis 数据流中正在限流的 GetRecords 调用数量。

设置您的 CloudWatch 控制面板以将统计数据显示为 Sum(总计),时间段设置为一分钟。然后,用总计值除以 60 秒以获得平均值。

例如,如果使用 GetRecords.Records 指标值,则用总计值除以 60 秒来计算平均每秒发送的记录数量。然后,检查平均值是否小于为您的 Amazon Kinesis 数据流设置的限制中的每秒发送的记录数量。有关分片限制的更多信息,请参阅 Kinesis Data Streams 配额和限制

注意:您可以启用增强监控功能以确保负载均匀地分布在您的所有分片上。

您还可以使用 GetRecords.Records 指标,并将统计数据作为 SampleCount 查看,时间段设置为一分钟。用 SampleCount 值除以 60 秒来计算每个分片每秒进行的 GetRecords 调用的平均数量。如果平均值为每秒大约 5 个 GetRecords 调用,并且您收到 ReadProvisionedThroughputExceeded 错误,请验证您的使用者未超过分片限制。如果它们未超过分片限制,则 ReadProvisionedThroughputExceeded 错误可能是因为您的使用者每秒的 GetRecords 调用数量超过了五个。

最后,检查您的分片 ReadProvisionedThroughputExceeded 值之间的不一致性。如果分片的分配不均匀,或者一个分片收到的数据比其他分片更多或更少,则可能存在分配不平衡。要解决这种分片分配不平衡并且避免存在热分片,请使用 UUID 作为 putRecords API 调用中的分区键。

确定可能的微爆流

虽然罕见,但指标值可能会低于分片限制,导致 Kinesis 数据流在读取期限限流。

我们以下面的情景为例:GetRecords.Bytes Sum:1min 代表一分钟读取 10MiB 的数据。在第一秒,GetRecords.Bytes 调用读取 2MiB 数据,没有任何限制。然后,在第二秒,GetRecords.Bytes 调用读取 8MiB 数据。在第三秒,不能执行任何读取操作,也没有任何限流。尽管并未达到每分钟的分片限制(2MiB*60 = 120MiB 数据),但您可能会收到 ReadProvisionedThroughputExceeded 错误。如果您注意到指标值中出现突增,查找导致 ReadProvisionedThroughputExceeded 异常的微爆流。

遵循数据流最佳实践

要缓解 ReadProvisionedThroughputExceeded 例外,应当采用这些最佳实践:

  • 对流进行分片以增加流中的分片数量。
  • 降低 GetRecords 请求的大小。您可以通过配置限制参数或降低 GetRecords 请求的频率实现此目的。
    注意:如果使用者是 Amazon Kinesis Data Firehose,则 Kinesis 数据流进行调整以适应正在进行的 GetRecords 调用的频率。如果使用者是具有事件源映射的 AWS Lambda 函数,则每秒轮询该流一次。轮询频率无法修改。如果使用者是 Amazon Kinesis Client Library (KCL) 应用程序,则通过修改 DEFAULT_IDLETIME_BETWEEN_READS_MILLIS 参数的值调整轮询频率。有关如何在 KCL 中修改该值的更多信息,请参阅 GitHub 网站上的 Amazon Web Services – 实验室
  • 在 Data Streams 中的所有分片上尽可能均匀地分布读取和写入操作。
  • 使用具有 enhanced fan-out 的使用者。有关 enhanced fan-out 的更多信息,请参阅开发具有专用吞吐量 (enhanced fan-out) 的自定义使用者
    注意:如果您的 Kinesis 数据流使用超过五个使用者,最佳实践是使用具有 enhanced fan-out(增强扇出)功能的使用者。
  • 如果遇到 ReadProvisionedThroughputExceeded 异常,则在使用者逻辑中使用错误重试和指数退避机制。对于使用 AWS 开发工具包的使用者应用程序,默认情况下会重试请求。

这篇文章对您有帮助吗?


您是否需要账单或技术支持?