保证Kafka集群上消息的排序



我已经阅读了几十篇关于Kafka消息排序的文章,但仍然没有看到一个开箱即用的解决方案来满足我最常见的需求——发布具有顺序递增ID的消息并以相同的顺序消费它们。

Kafka保留分区内的消息顺序。但是,什么样的企业级解决方案会为关键数据使用单个分区(单点数据丢失故障、没有并行性的吞吐量降低等)呢?因此,挑战在于如何在多分区主题中按顺序使用消息。

做区块链分析,我们从区块链节点中获取顺序递增的数据块,然后将它们发布到我们的Kafka主题。Key=块号,Value=块数据。块号从0开始,以1递增,直到永远。

我们的分析代码需要按顺序使用这些消息(块1,块2,块3等)。如果在区块2的区块链上创建了一个智能合约,然后在区块3中发生了一笔交易,如果我们在区块2之前处理了区块3,我们的分析代码就会失败(例如"没有合约发现错误")。

关于我们用例的更多信息。

  1. 具有块数据的主题将永远不会被清除。这将增长到几TB,并将有数百万条消息。虽然大多数消费者不会直接使用它,但它仍然作为我们区块链的链下副本,并可能满足我们软件的未来需求。

  2. 我们有一个SQL数据库表,它存储了关于我们分析了多少区块链的状态信息(例如,最高块#是25,555,555)。

对于保证排序,大多数文章推荐Kafka Streams和KTables。如果我们使用内存中的KTable,那么我们将面临重大挑战(不能在内存中存储TB的数据,在启动时重新构建KTable需要几天时间,等等)

如果我们使用持久化KTable,那么我们就会增加磁盘使用量(在源主题和KTable之间复制了几TB的数据)。

我们可以创建一个次要的"操作"单分区主题(数据保留时间相对较短),并按顺序将数据流式传输到该主题,然后让我们的消费者从该主题中提取数据。但这与开箱即用恰恰相反,我们希望避免为我们拥有的数百个区块链和消息传递需求这样做。这将成为一场行政崩溃。

这似乎是自Kafka创建以来数千家公司一直存在的技术需求(就像消息队列几十年来所做的那样)。KafkaListener是否没有现成的解决方案来根据数字键(在多分区主题中)按顺序接收消息?

发布具有顺序递增ID的消息并以相同的顺序使用它们

在使用Kafka时,单个分区是实现此目的的唯一方法。

从区块链的角度来看,另一种设计是按钱包地址进行密钥设置,例如,然后为每个钱包排序事件。但是,如果你的钱包之间有交易,就不能保证"其他钱包"因此,在完全处理这些事件之前,您将需要一些其他状态存储(例如KTable)来存储所有已知的钱包地址。

具有块数据的主题永远不会被清除。这将增长到几个TB

未分配分区段。如果您有一个分区,这意味着您只能使用一个HDD的大小。

同样,RocksDB或内存状态存储也会有同样的问题。但是,它们的接口是可插拔的,并且可以替换,在处理顺序保证方面进行了一些权衡。

最新更新