经典案例

优化 Amazon Kinesis 数据流的写入吞吐量 大数据博客

  • 2026-01-27 12:33:38
  • 5

优化 Amazon Kinesis 数据流的写入吞吐量

由 Buddhike de Silva 和 Nihar Sheth 于 2024 年 6 月 3 日发布在 中级 (200)、Kinesis 数据流、技术如何做

关键要点

Amazon Kinesis 数据流通过将每个数据流划分为多个分片实现了独特的可扩展性,每个分片的写入吞吐量限制为每秒 1 Mbps 或 1000 条记录。写入吞吐量超出错误通常是由于数据生产者生成的数据超出 Kinesis 数据流的总吞吐量,导致数据堵塞和潜在的数据丢失。记录写入失败的原因可能是数据在分片之间的不均匀分布、热分片问题或是某个分片内单一分区键引发的热键问题。文章介绍了一系列解决方案,包括如何识别问题的根本原因以及如何修复写入吞吐量超出错误。

Amazon Kinesis 数据流被众多客户用于以任何规模捕获、处理和存储数据流。这种无与伦比的规模是通过将每个数据流划分为多个分片实现的。每个分片在流中的写入吞吐量限制为每秒 1 Mbps 或 1000 条记录。无论您的数据流应用程序是从 Web 应用程序收集点击流数据,还是从数十亿个物联网 (IoT) 设备记录遥测数据,流式应用程序都对数据的摄取量变化极为敏感。有时,数据量的巨大波动是最不可预料的。例如,在将记录写入 Kinesis 数据流时,应用程序可能会因网络故障而被迫缓冲数据,待连接恢复后再写入。根据数据缓冲的速度和连接问题的持续时间,当地的缓冲区可能积累足够的数据,从而达到 Kinesis 数据流的可用写入吞吐量配额。

当应用程序尝试写入超过允许的数据时,它将收到写入吞吐量超出错误。在某些情况下,如果无法及时解决这些错误,可能会导致数据丢失、客户不满以及其他不良后果。本文将探讨造成写入吞吐量超出错误的常见原因,以及如何识别它们。然后,我们将指导您快速响应这些事件,并提供多种缓解解决方案。最后,我们还将深入探讨如何使用按需容量模式来有效应对这些错误。

写入吞吐量超出错误的原因

写入吞吐量超出错误一般由三种不同的场景引发:

最简单的情况是生产者应用程序生成的数据超过了 Kinesis 数据流中所有分片可用的吞吐量。其次是数据在所有分片之间分布不均,这被称为“热分片”问题。写入吞吐量超出错误还可能是由于应用程序选择的分区键,以超过单个分片的吞吐量速率写入记录。这种情况与热分片问题有所类似,但我们稍后会看到,解决此问题的方式不同于热分片问题,增加更多分片并不能解决该问题。这种行为通常被称为“热键”问题。

在讨论如何诊断这些问题之前,让我们先了解 Kinesis 数据流如何组织数据及其与写入吞吐量超出错误的关系。

Kinesis 数据流包含一个或多个用于存储数据的分片。每个分片在128位整数空间中分配一个键范围。如果您使用AWS 命令行界面中的describestream操作查看数据流的详细信息,您实际上可以看到这个键范围的分配:

bash aws kinesis describestream streamname mydatastreamStreamDescription { Shards [ { ShardId shardId000000000000 HashKeyRange { StartingHashKey 0 EndingHashKey 85070591730234615865843651857942052863 } } { ShardId shardId000000000001 HashKeyRange { StartingHashKey 85070591730234615865843651857942052864 EndingHashKey 170141183460469231731687303715884105727 } } ]}

当生产者应用程序调用PutRecord或PutRecords API 时,服务为记录中指定的PartitionKey计算一个 MD5 哈希。生成的哈希用于确定将该记录存储在哪个分片。通过在PutRecord请求中设置ExplicitHashKey属性,您可以更好地控制此过程,将哈希键设置在特定分片的键范围内。例如,设置ExplicitHashKey为0将保证该记录写入前面代码片段描述的流中的分片 ID shardId0。

分区键在可用分片中的分布对于最大化 Kinesis 数据流中的可用吞吐量起着至关重要的作用。当使用的分区键频繁重复,且某些键的频率高于其他键时,存储这些记录的分片将被更频繁地使用。如果我们使用ExplicitHashKey,并且选择哈希键的逻辑偏向于某个分片子集,也会产生相同的净效果。

假设您有一组 Web 服务器为每个服务的 Web 请求记录性能指标,并将其写入包含两个分片的 Kinesis 数据流中,您使用请求 URL 作为分区键。每次请求服务时,应用程序会调用PutRecord API,携带 10 字节的记录。假设您总共有 10 个 URL,并且每个 URL 每秒接收到 10 个请求。在这种情况下,工作负载所需的总吞吐量为每秒 1000 字节和 100 个请求每秒。如果假设 10 个 URL 在两个分片之间的分配是完美的,每个分片每秒将接收到 500 字节和 50 个请求。

现在想象一下,这些 URL 中的一个突然开始火爆,每秒接收到 1000 个请求。尽管从商业角度来看,这是个好消息,但您却可能面临用户的不满。随着页面的流行,您在存储着热门 URL 的分片中统计到每秒 1040 个请求1000 10 4。此时,您将收到来自该分片的写入吞吐量超出错误。由于请求每秒的配额被限制,即使请求量增加,您仍在生成大约 11 KB 的数据。

您可以通过为每个请求使用 UUID 作为分区键来解决此问题,以便将负载均匀分摊到两个分片中,或者通过为 Kinesis 数据流添加更多分片。您选择的方法取决于如何想要消费数据。如果您希望每个特定 URL 的性能指标总是由同一个消费实例处理,或者希望按 URL 维护记录的顺序,改变分区键为 UUID 将变得麻烦。

了解写入吞吐量超出错误的确切原因是解决这些问题的重要步骤。在接下来的部分中,我们将讨论如何识别根本原因并缓解这个问题。

识别写入吞吐量超出错误的原因

解决问题的第一步是意识到问题的存在。在这种情况下,您可以使用在Amazon CloudWatch中查看的WriteProvisionedThroughputExceeded指标。您可以将WriteProvisionedThroughputExceeded指标的峰值与IncomingBytes和IncomingRecords指标进行关联,以识别是数据的大小还是写入的记录数量导致应用程序受到限制。

让我们来看一下我们在具有两个分片的流中进行的一些测试,以说明各种场景。在这种情况下,流的总吞吐量可为 2 Mbps 或每秒 2000 条记录。

在第一次测试中,我们运行一个生产者,使用PutRecords API 写入每个 100 KB 的 30 条记录的批次。正如下图左侧所示,我们WriteProvisionedThroughputExceeded错误计数增加。右侧的图表显示我们达到了 2 Mbps 的限制,但我们传入记录的速率远低于每秒 2000 条记录的限制Kinesis 指标以 1 分钟的间隔发布,因此 1258 和 120000 为上限。

接下来的图表显示,第二次测试中我们更改生产者以写入每个 50 字节的 500 条记录的批次。这次,我们超出了每秒 2000 条记录的吞吐量限制,但传入字节速率仍在限制范围内。

现在我们知道存在问题后,应寻找线索,以确定我们是超出了流中的总体吞吐量,还是由于不平衡的分区键导致热分片问题。如前所述,使用增强的分片级别指标是一种方法。在我们的测试之前,我们启用了增强的分片级别指标,接下来的图表显示,在第一次测试中,两个分片都均匀达到了配额。

我们已经看到包含数千个分片的 Kinesis 数据流利用其无限可扩展性的力量。然而,在如此大量的流上绘制增强的分片级别指标可能不容易找出哪些分片过度利用。在这种情况下,使用CloudWatch Metrics Insights 可以通过运行查询查看前 N 个项目,如下记录代码相应调整 LIMIT 5 语句:

sql 显示输入字节最多的前 5 个分片SELECTSUM(IncomingBytes)FROM AWS/KinesisGROUP BY ShardId StreamNameORDER BY MAX() DESCLIMIT 5

显示输入记录最多的前 5 个分片SELECTSUM(IncomingRecords)FROM AWS/KinesisGROUP BY ShardId StreamNameORDER BY MAX() DESCLIMIT 5

增强的分片级别指标默认未启用。如果未启用,您想在事件发生后进行根本原因分析,此选项将不太有帮助。此外,您只能查询最近 3 小时的数据。增强的分片级别指标也会增加 CloudWatch 指标的额外费用,对于分片较多的数据流而言,始终启用这项功能可能成本过高。

一个有趣的场景是,当工作负载出现突发性时,这会使得最终的 CloudWatch 指标图表显得相当混乱。这是因为 Kinesis 以 1 分钟的间隔发布 CloudWatch 指标数据。因此,尽管您可以看到写入吞吐量超出错误,但传入字节/记录的图表可能仍在限制内。为了说明这一场景,我们更改了我们的测试,以创建一个超过限制的写入突发,然后休眠几秒钟。之后我们重复这个周期几分钟,以产生如左图所示的图表,图表显示写入吞吐量超出错误,但右图的IncomingBytes和IncomingRecords图表似乎正常。

优化 Amazon Kinesis 数据流的写入吞吐量 大数据博客

为了增强识别写入吞吐量超出错误的过程,我们开发了一款命令行工具 Kinesis Hot Shard Advisor (KHS)。使用 KHS,您可以在没有启用分片级指标时查看分片利用率。这特别有助于追溯调查问题。 KHS 还可以显示特定分片中写入频率最高的键。 KHS 通过读取记录并根据记录中的ApproximateArrivalTimestamp按每秒的间隔进行汇总报告分片利用率。因此,您也可以理解在突发写入工作负载下分片利用率的驱动因素。

通过运行以下命令,我们可以让 KHS 检查在第一次测试期间到达 1 分钟的数据并生成报告:

bashkhs stream mydatastream from 20230622 173500 to 20230622 173600

迅猛兔加速器正版

在给定的时间窗口中,生成的报告的摘要部分显示观察到的每秒最大字节率、总字节数、观察到的最大记录每秒数及每个分片的记录总数。

选择第一列中的分片 ID 将显示该分片的传入字节和记录的图表。这类似于您在 CloudWatch 指标中看到的图表,但 KHS 图表以每秒为基础报告。例如,在下图中,我们可以看到生产者经历了一系列突发性写入,之后在我们的测试案例中发生了限制事件。

使用带aggregatekey选项运行同样的命令可启用分区键分布分析。它为每个分片生成附加的键分布图,如下图所示。对于我们的测试场景,由于为每条记录使用了新的 UUID,我们只能看到每个键的使用一次。

由于 KHS 在启动时创建了增强的外发消费者,因此根据存储的数据生成报告,以避免消耗其他消费者的读取吞吐量配额。分析完成后,它会删除该增强外发消费者。

由于 KHS 的数据流读取性质,分析期间可能会传输大量数据。例如,假设您有一个包含 100 个分片的


发表评论

提交
迅猛兔加速器正版

迅猛兔官方网站提供全球连线服务,实现一键速度提升,助您畅享网络,加速体验,无论身处何地,轻松连接。

网站地图

找到迅猛兔加速器免费下载