kafka事件承载状态传输系统是否应该使用globalktable实现本地查询?

oug3syen  于 2021-06-06  发布在  Kafka
关注(0)|答案(1)|浏览(422)

携带事件的状态转移消除了从其他服务查询信息的远程调用的需要。
让我们假设一个实际案例:
我们有一个客户服务部 CustomerCreated/CustomerUpdated 事件以客户Kafka为主题。
配送服务侦听订单主题
OrderCreated 事件由装运服务读取,它将需要访问客户地址。配送服务将不再向客户服务打rest电话,而是在本地提供用户信息。它保存在一个 KTable / GlobalKTable 具有持久性存储。
我的问题是关于我们应该如何实现这一点:我们希望这个系统具有弹性和可扩展性,因此将有多个客户和运输服务示例,这意味着客户和订单主题也将有多个分区。
我们可以找到这样的场景:一个 OrderCreated(orderId=1, userId=7, ...) 事件由装运服务读取,但如果它使用 KTable 要保留和访问本地用户信息 userId=7 可能不存在,因为处理该用户标识的分区可能已分配给其他装运服务示例。
这个问题可以用一个简单的方法解决 GlobalKTable 这样所有的配送服务示例都可以访问整个范围的客户。
是这个吗( GlobalKTable )实现这种模式的推荐方法是什么?
当客户数量非常大时,在每个shipping service示例中复制整个客户数据集是否有问题?
这种情况是否可以用 KTable 在某种程度上?

yduiuuwa

yduiuuwa1#

你可以用两种方法解决这个问题 GKTable 和一个 KTable . 以前的数据结构是复制的,因此整个表在每个节点上都可用(并且占用更多的存储空间)。后者是分区的,因此数据分布在各个节点上。这样做的副作用是,正如您所说,处理userid的分区可能不会同时处理相应的客户。您可以通过重新划分其中一个流来解决这个问题,这样它们就会被共同划分。
因此,在您的示例中,您需要在shipping服务中使用客户信息来丰富order事件。你可以:a)使用 GlobalKTable 并连接到每个节点上的信息b)使用 KTable ,并执行相同的操作,但在执行扩展之前,必须使用 selectKey() 运算符以确保数据是共同分区的(即相同的键将位于同一节点上)。在customer和orders主题中还必须有相同数量的分区。
confluent microservices示例中的inventory服务示例也做了类似的事情。它对订单流重新设置密钥,以便它们按productid进行分区,然后连接到 KTable 库存(也由productid键入)。
关于您的个人问题:
GlobalKTable 实现这种模式的推荐方法是什么?两者都有效。这个 GKTable 如果您的服务由于任何原因丢失存储,则最坏情况下的重新加载时间会更长。这个 KTable 由于数据需要重新分区,延迟会稍大一些,这意味着将数据写到kafka并再次读取。
当客户数量非常大时,在每个shipping service示例中复制整个客户数据集是否有问题?主要区别在于前面提到的最坏情况下的重新加载时间。虽然技术上 GKTable 以及 KTable 语义稍有不同( GKTable 启动时满载, KTable 根据事件时间增量加载,但这与此问题没有严格关系)
这种情况是否可以用 KTable 在某种程度上?见上文。
另请参阅:微服务示例、快速入门、博客文章。

相关问题