专栏名称: 聊聊架构
聊聊架构
目录
相关文章推荐
51好读  ›  专栏  ›  聊聊架构

Kafka实践:到底该不该把不同类型的消息放在同一个主题中?

聊聊架构  · 公众号  · 架构  · 2018-09-01 13:00

正文

请到「今天看啥」查看全文


对于某些类型的流式数据,例如活动事件,要求同一主题中所有消息都符合相同的模式,这是合理的。但是,有些人把 Kafka 当成了数据库来用,例如 事件溯源,或者 在微服务之间交换数据。对于这种情况,我认为是否将主题定义为具有相同模式的消息集合就不那么重要了。这个时候,更重要的是主题分区中的消息必须是有序的。

想象一下这样的场景:你有一个实体(比如客户),这个实体可能会发生许多不同的事情,比如创建客户、客户更改地址、客户向帐户中添加新的信用卡、客户发起客服请求,客户支付账单、客户关闭帐户。

这些事件之间的顺序很重要。例如,我们希望其他事件必须在创建客户之后才能发生,并且在客户关闭帐户之后不能再发生其他事件。在使用 Kafka 时,你可以将它们全部放在同一个主题分区中来保持它们的顺序。在这个示例中,你可以使用客户 ID 作为分区的键,然后将所有事件放在同一个主题中。它们必须位于同一主题中,因为不同的主题对应不同的分区,而 Kafka 是不保证分区之间的顺序的。

顺序问题

如果你为 customerCreated、customerAddressChanged 和 customerInvoicePaid 事件使用了不同的主题,那么这些主题的消费者可能就看不到这些事件之间的顺序。例如,消费者可能会看到一个不存在的客户做出的地址变更(这个客户尚未创建,因为相应的 customerCreated 事件可能发生了延迟)。

如果消费者暂停一段时间(比如进行维护或部署新版本),那么事件出现乱序的可能性就更高了。在消费者停止期间,事件继续发布,并且这些事件被存储在特定定的主题分区中。当消费者再次启动时,它会消费所有积压在分区中的事件。如果消费者只消费一个分区,那就没问题:积压的事件会按照它们存储的顺序依次被处理。但是,如果消费者同时消费几个主题,就会按任意顺序读取主题中数据。它可以先读取积压在一个主题上的所有数据,然后再读取另一个主题上积压的数据,或者交错地读取多个主题的数据。

因此,如果你将 customerCreated、customerAddressChanged 和 customerInvoicePaid 事件放在三个单独的主题中,那么消费者可能会在看到 customerCreated 事件之前先看到 customerAddressChanged 事件。因此,消费者很可能会看到一个客户的 customerAddressChanged 事件,但这个客户却未被创建。







请到「今天看啥」查看全文


推荐文章
小鹿情感先生  ·  你真的做好啪啪啪的准备了吗?
7 年前
安卓开发精选  ·  我给所有新手程序员的建议
7 年前