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