我在 Amazon Kinesis Data Streams 中遇到了 ReadProvisionedThroughputExceeded 错误,我不知道为什么会出现这种情况。
简短描述
当 Amazon Kinesis Data Streams 在一段时间内限制 GetRecords 调用时,就会出现 ReadProvisionedThroughputExceeded 错误。
如果超过以下配额,那么您的 Amazon Kinesis Data Streams 可能就会受限:
- 每个分片每秒最多支持五个读取事务,或者每个分片每秒支持五次 GetRecords 调用。
- 每个分片支持的最大读取速率为每秒 2 MiB。
- GetRecords 每次调用时最多可检索来自单个分片的 10 MiB 的数据,以及 10,000 条记录。如果对 GetRecords 的调用返回 10 MiB 的数据,则在接下来的 5 秒内进行的后续调用会导致错误。
如果您遇到 ReadProvisionedThroughputExceeded 错误,请完成以下任一任务:
- 确定问题的根本原因。
- 确定是否会出现微爆。
- 遵循 Amazon Kinesis Data Streams 最佳实践。
解决方法
找出问题的根本原因
要确定 Amazon Kinesis Data Streams 中 ReadProvisionedThroughputExceeded 错误的根本原因,请使用 Amazon CloudWatch 监控 Amazon Kinesis Data Streams 服务。
查看 CloudWatch 中的下列指标:
- **GetRecords.Bytes:**从 Amazon Kinesis Data Streams 检索的字节数,仅测量指定时间段。
- **GetRecords.Records:**从 Amazon Kinesis Data Streams 检索的记录数,仅测量指定时间段。
- **ReadProvisionedThroughputExceeded:**在 Amazon Kinesis Data Streams 中遭到限制的 GetRecords 调用次数。
设置 CloudWatch 控制面板,将统计数据显示为总和,时间段设置为 1 分钟。然后,将总和除以 60 秒得出平均值。
例如,如果使用 GetRecords.Records 指标值,则将总和除以 60 秒来计算每秒发送的平均记录数。然后,检查平均值是否小于为您的 Amazon Kinesis Data Streams 设置的每秒发送记录数上限。有关分片配额的更多信息,请参阅 Quotas and limits。
**注意:**开启增强监控功能,确保负载均匀分布在所有分片上。
您也可以使用 GetRecords.Records 指标,将统计数据视为 SampleCount,时间段设置为 1 分钟。将 SampleCount 值除以 60 秒,计算每个分片每秒对 GetRecords 的平均调用次数。如果平均值约为每秒调用五次 GetRecords,并且您收到 ReadProvisionedThroughputExceeded 错误,则请检查您的使用程序和分片配额。如果使用程序没有超过分片上限,那么 ReadProvisionedThroughputExceeded 错误可能是因为您的使用程序每秒进行五次以上的 GetRecords 调用。
最后,检查分片的 ReadProvisionedThroughputExceeded 值之间是否存在差异。如果分片的分布不均匀,或者一个分片接收的数据多于或少于另一个分片,则可能会出现分布不均衡。要解决这种分片分布不均衡问题并避免分片过热,请在 putRecords API 调用中使用 UUID 作为分区键。
确定是否会出现微爆
指标值可能会低于分片配额并导致读取期间数据流受限(虽然这种情况很罕见)。
例如,GetRecords.Bytes Sum:1min 表示读取 1 分钟的 10 MiB 数据。在 1 秒钟时,GetRecords.Bytes 调用会读取 2 MiB 的数据,没有任何限制。然后在 2 秒钟时,GetRecords.Bytes 调用会读取 8 MiB 的数据。在 3 秒钟时,可能没有任何读取操作或任何限制。尽管未达到该分钟的分片配额(2MiB*60 = 120MiB 的数据),但您可能会收到 ReadProvisionedThroughputExceeded 错误。如果您发现指标值突然出现峰值,请寻找导致 ReadProvisionedThroughputExceeded 异常的微爆情况。
遵循 Amazon Kinesis Data Streams 最佳实践
要应对 ReadProvisionedThroughputExceeded 异常,请遵循以下最佳实践:
- 重新分片您的 Amazon Kinesis Data Streams 以增加 Amazon Kinesis Data Streams 中的分片数量。
- 减小 GetRecords 请求的大小。配置限制参数,或降低 GetRecords 请求的频率。
**注意:**如果使用程序是 Amazon Kinesis Data Firehose,则 Amazon Kinesis Data Streams 会根据 GetRecords 的调用频率进行调整。如果使用程序是具有事件源映射的 AWS Lambda 函数,则每秒对 Amazon Kinesis Data Streams 进行一次轮询。您无法修改轮询频率。如果使用程序是 Amazon Kinesis 客户端库(KCL)应用程序,则调整轮询频率。要调整轮询频率,请修改 KinesisClientLibConfiguration 文件中的 DEFAULT_IDLETIME_BETWEEN_READS_MILLIS 参数值。您可以在代码中动态设置这个值。有关如何在 KCL 中修改此值的更多信息,请参阅 GitHub 网站上的 amazon-kinesis-client。
- 尽可能均匀地将读取和写入操作分布在 Amazon Kinesis Data Streams 中的所有分片上。
- 如果您的 Amazon Kinesis Data Streams 使用五个以上的使用程序,则使用具有增强扇出功能的使用程序。
- 如果您遇到 ReadProvisionedThroughputExceeded 异常,请在使用程序逻辑中使用错误重试和指数回退机制。对于使用 AWS SDK 的使用程序,默认情况下会重试请求。