我有一个用例,我需要从主题读取数据,然后批处理数据(100条记录),并将批处理写入特定的文件或外部存储。我计划为此使用处理器API,并使用由kafka支持的状态存储在处理方法中对数据进行批处理,并在批处理大小达到100条记录时写入文件。从状态存储中清除批次以创建新的批次。
另一个要求是我们不能重复数据。这意味着同一记录不能分为两个不同的批次。
流是否恰好适合此用例?我在设计中读到,如果我们要批处理数据,则不建议这样做,并且有关此问题的大多数文章都说,仅在使用过程和产生模式的情况下,Exactly一次有效。
答案 0 :(得分:0)
仅当您将结果写回Kafka时,Kafka Stream才执行一次。因为您想将数据写入外部系统,所以Kafka无法为一次保证提供任何帮助,因为Kafka事务不是跨系统事务。
答案 1 :(得分:0)
正如@Matthias所指出的,仅一种语义仅适用于Kafka流到Kafka流类型的应用程序,与外部系统的集成可能会破坏语义。您可以在this文章中详细了解它。
我建议您使用Kafka Consumer API,因为它将在使用案例的灵活性和抽象性之间提供最佳的平衡。您需要做的就是删除enable.auto.commit = false并在使用consumer.commitSync()成功将批处理写入外部系统后手动提交。
根据您的使用情况,有时仅要确保一次可能会有些困难。您需要使用自定义逻辑来确保您的使用者是幂等的。您可以考虑使用外部持久性存储来保留消息的哈希值(如果是唯一的,则为键),并检查是否尚未处理每条消息。您也可以为此使用状态存储,但是我觉得清除状态存储有时会很麻烦,但这在很大程度上取决于您的用例。
如果有帮助,您可以查看this文章。