事件携带状态传输消除了从其他服务查询信息的远程调用的需要。。
让我们假设一个实际案例:
CustomerCreated/CustomerUpdated事件发布到customer主题。OrderCreated事件时,它将需要访问客户地址。送货服务将不再对客户服务进行REST调用,而是已经在本地获得了用户信息。它保存在具有持久存储的KTable/GlobalKTable中。我的问题是我们应该如何实现这一点:我们希望这个系统具有弹性和可伸缩性,这样就会有多个客户和运输服务实例,这意味着客户和订单主题也会有多个分区。
我们可以找到这样的场景:OrderCreated(orderId=1, userId=7, ...)事件是由传送服务读取的,但是如果它使用KTable来保存和访问本地用户信息,那么userId=7可能就不存在了,因为处理该userId的分区可能已经分配给了其他运输服务实例。
可以使用GlobalKTable来解决这个问题,这样所有配送服务实例都可以访问整个客户范围。
GlobalKTable)吗?KTable来实现?发布于 2019-04-08 10:24:55
您可以同时使用GKTable和KTable解决这个问题。前一个数据结构被复制,所以整个表在每个节点上都是可用的(并且消耗了更多的存储)。后者被划分,因此数据分布在不同的节点上。这有一个副作用,正如您所说的,处理userId的分区可能也不会处理相应的客户。您可以通过重新划分其中一个流来解决这个问题,这样它们就可以被共同分割。
因此,在您的示例中,您需要使用航运服务中的客户信息丰富订单事件。您可以这样做:( a)使用客户信息的GlobalKTable并连接到每个节点b上)使用客户信息的KTable并执行相同的操作,但在进行充实之前,您必须使用selectKey()操作符来确保数据是共分区的(即相同的键将位于同一个节点上)。您还必须在Customer和Orders主题中有相同数量的分区。
汇合微服务示例中的库存服务示例做了类似的事情。它重新锁定订单流,以便由productId对它们进行分区,然后加入到库存的KTable (也是productId键)。
关于你的个人问题:
GlobalKTable是实现该模式的推荐方法吗?两样都有用。如果您的服务因任何原因而丢失存储,GKTable将有更长的最坏情况重新加载时间。当数据必须重新分区时,KTable将有一个稍微大的延迟,这意味着将数据写入Kafka并再次读取它。GKTable和KTable的语义略有不同(GKTable在启动时加载完全,KTable加载则以事件时间为基础,但这与这个问题并不严格相关)。KTable来实现?请参见上面的。https://stackoverflow.com/questions/55548618
复制相似问题