IRecordsProcessor进程记录未被KCL库

时间:2016-10-12 15:14:32

标签: amazon-kinesis

我们多次进行了以下测试,我们很难找到合理解释为什么会发生这种情况:

  • 我们创造了一个消费者,我们等待它准备好
  • 我们在消费者正在收听的流上发布了两条记录

我们有一个碎片,有时消费者没有得到记录的通知。我们使用不同的workerId,但具有相同ApplicationName的应用程序可能会窃取记录。

KCL消费者永远不会获得刚刚发布的记录的原因是什么?

2 个答案:

答案 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-implementation-app-java.html#kcl-java-worker

http://docs.aws.amazon.com/streams/latest/dev/kinesis-record-processor-scaling.html