Kafka Streams中重新输入密钥时的消息顺序

时间:2019-09-02 10:21:06

标签: apache-kafka apache-kafka-streams

我想通过其他元数据来丰富数据更改事件(通过Debezium进行的CDC)主题;例如说我有一个关于采购订单变更事件的话题,我想用由变更事件起源的交易所键入的元数据来充实。

我最初考虑通过交易ID(包含在更改事件中)为“购买订单” KStream键入密钥,因此我可以将其与交易元数据的KStream结合使用。在使用元数据丰富了采购订单事件之后,我将其再次重新设置为原始订单ID。

但是我现在怀疑这是否可以按预期工作:对于数据更改事件,保持事件的顺序至关重要,即对于一个采购订单(例如123),所有事件都具有相同的密钥( 123),因此将进入“购买订单”主题的一个分区,依次由客户按其产生的顺序使用。

现在,通过上述重新键入密钥,是否可能由于重新键入密钥而改变了一个采购订单的变更事件的顺序?一个采购订单可能会被多个交易更改,因此IIUC通过交易ID进行密钥更新可能会导致一个采购订单的事件最终在不同的分区中终止,从而使原始的订购保证无效。

我对此有哪些选择?我现在正在考虑避免使用rekey + join,而是在“ purchaseorder”流上实现手动的transform()方法,该方法将从状态存储中查找关联的交易数据。但是,在缩放的Kafka Streams应用程序中,如果给定订单事件的交易数据存储在其他节点上(或对交易数据主题使用GlobalKTable),则这意味着可能进行远程查找。

是否有其他推荐的选择?

1 个答案:

答案 0 :(得分:2)

不能将浓缩数据视为表格吗? (这意味着它将数据复制到您的所有处理节点,从而使您“就地充实”)

如果您做不到,并且愿意承受延迟(并且对延迟有所限制...) 您可以重新设置数据密钥(正确的做法是,由于多个源分区现在可能会将数据产生到任何目标分区中,因此可能会发生重新排序),然后使用内存中的窗口将其重新排序(这是延迟时间的关键所在,以及引入延迟的位置),并将其整理成另一个主题...

以这种方式运行将非常昂贵且脆弱。