我们多次进行了以下测试,我们很难找到合理解释为什么会发生这种情况:
我们有一个碎片,有时消费者没有得到记录的通知。我们使用不同的workerId,但具有相同ApplicationName的应用程序可能会窃取记录。
KCL消费者永远不会获得刚刚发布的记录的原因是什么?
答案 0 :(得分:1)
我的代码的问题是,一旦你在KCL中第一次创建了一个应用程序,Dynamo中用于检查点的匹配条目就存储了分片迭代器的最后位置。
当您重新启动应用程序时,分片迭代器可能会落后于当前时间,并且在您到达发布记录的当前位置之前可能需要大量迭代。
因此,出于测试目的,您可能需要每次都创建一个新的应用程序并每晚清洁您的发电机表
答案 1 :(得分:0)
您的每个应用程序名称似乎都在使用许多工作程序,但您的流只有一个分片。每个分片只能有一个工作程序处于活动状态并检索数据,所有其他工作程序都将处于空闲状态。
您应该确保工作人员数量不超过分片数量(或者只有少数分数用于恢复)。
使用Kinesis,每个应用程序名称可以包含许多工作程序,以便从分片中并行恢复数据。假定具有相同应用程序名称的工作者在同一个流上一起工作。
但是,每个工作人员每次都可以访问每个分片,例如具有相同应用程序名称的两个worker无法同时从同一个分片中读取。如果你有N个工人但只有1个碎片,那么总会有1个工人在运行,而N-1将处于空闲状态。哪个是活跃的工作者,是一个安排问题。
如果您希望许多工作程序并行使用同一分片中的数据,则需要运行应用程序的其他实例,但使用不同的应用程序名称。第二个实例被认为是一个完全独立的应用程序,它也在同一个流上运行。
KCL使用DynamoDB来处理每个应用程序名称的状态信息(例如,分片数,工作者数,检查点数,工作者分片映射数等)。每个应用程序名称对于每个区域应该是唯一的,并且具有自己的DynamoDB表。
当工作程序启动时,它会查询DynamoDB以查看应用程序名称的表是否存在。如果没有表,则创建一个新表并在其中写入其状态。工作人员自动发现分片并创建处理器来处理来自它们的数据。
工作人员可以从许多分片中读取数据,例如它使用DynamoDB表来跟踪它检索的记录,并将使用它来获取新的分片迭代器。但是,正如我之前所说,每次一个工作人员可以访问一个分片(当然我指的是具有相同应用程序名称的工作者)。
如果第二个工作程序启动,它将查询DynamoDB,这次会发现应用程序和流的表存在。所以它只是通过在表中写入状态来注册自己。通过DynamoDB表,工作人员可以相互发现并划分工作,例如如果存在多于一个碎片,则每个工作者都可以读取一半碎片。否则,新工人将处于闲置状态。
最后一件事。如果我没记错的话,当记录被发送到kinesis时它可能需要几秒钟(最多10秒)并且它已准备好被工作人员使用。
希望这有帮助。请查看这些链接以获取更多信息:
http://docs.aws.amazon.com/streams/latest/dev/kinesis-record-processor-scaling.html