Kafka Streams GlobalKTable何时是微服务世界中数据存储的好选择?



我是Kafka Streams世界的新手。我想知道什么时候使用Kafka StreamsGlobalKTable(在引子下压缩主题)而不是常规数据库来持久化数据。两种解决方案的优点和缺点是什么?我想两者都确保了数据在同一级别上的持久性。

假设有一个简单的电子商务应用程序,用户注册和更新他们的数据。有两个微服务——第一个(service-users)负责注册用户,第二个(service-orders)负责下订单。现在有两个选项:

  1. 当新用户注册时,service-user接受请求,将新注册的用户数据保存在数据库中(SQL或noSQL,无关紧要),然后将事件发送到Kafka以将其传播到其他服务。service-orders接收这些事件,并将必要的用户数据存储在自己的数据库中。这是一种最常见的模式(从我的经验来看)。

GlobalKTable:

的第二种方法
  1. 当新用户注册或更新时,service-user接受请求并发送带有用户数据快照的事件给Kafka。service-userservice-orders使用GlobalKTable读取用户信息

何时使用哪种溶液?哪种解决方案在哪种情况下更好?这两种方法的优缺点是什么?第二种方法是否打破了"每个微服务都应该在自己的数据库中维护自己的数据"的规则?

希望我很好地解释了我的考虑,它们是有意义的。

总的来说,GlobalKTable的优点是:

  • 你可以做一个外键连接到GlobalKTable
  • 应用程序在内存中有一个完整的数据集,该数据集在应用程序启动时自动加载,所有数据修改都会在所有实例中自动同步。与使用外部数据库的体系结构相比,在消息处理期间不需要(通过网络)与任何其他资源(如关系数据库)通信,因此处理速度明显快得多,因此可以快速处理大量数据。当你想要达到类似的处理性能时,你需要实现自己的某种内存缓存(如Guava),然后,你需要解决所有与适当的缓存管理相关的问题-升温,刷新,驱逐。

主要缺点是:

  • 应用程序在内存中有一个完整的数据集,这是一个优势,但它可能是一个非常大的问题,这取决于你的数据集有多大,或者你如何建模你的数据。参考您的示例,将所有用户订单存储在GlobalKTable中听起来是一个非常糟糕的主意,数据集将增长得非常快,并且数据的大小随着时间的推移而增长,因此在生产环境中运行应用程序几个月/几年之后,数据集可以达到千兆字节,并且它将不断增长。当我们仍然希望在GlobalKTable中存储订单以进行有效处理时,我们需要以不同的方式设计数据模型。也许我们的实体(订单,文档等)有一些生命周期,比如:新的,支付的,关闭的等,他们中的一些是终止的-我的意思是,将没有进一步的处理给定id的实体,(例如关闭的订单),所以如果没有处理,就没有必要将数据存储在内存中,我们可以将其转发到其他存储,如Elasticsearch并从GlobalKTable中删除它。我们可以将处理期间的订单数据集命名为热存储,将终止订单的数据集命名为冷存储。长话短说:在GlobalKTable中只有活动/热订单可能是一个好主意。
  • 查询GlobalKTable仅限于遍历所有数据集、子集或通过记录键或由时间戳组成的键获取数据
  • 基于外部数据库状态的处理已经被广泛使用了很多年,因此,许多开发人员都知道如何发展和维护这种类型的应用程序。在Kafka压缩主题中,我们不能说相同的存储状态。

最新更新