面向服务架构中的业务数据 querying/reporting

Business data querying/reporting in service oriented architecture

在去年的大部分时间里,我的公司一直在根据(微)服务架构的原则拆分单体并构建新产品。这一切都很好,让我们可以非常灵活地保持 UI 和后端逻辑分离并降低依赖性。

但是!

我们业务中有一个重要部分正因此而变得越来越令人头疼,即报告。

由于我们确保服务之间没有数据复制(和业务逻辑共享),因此每个服务都知道自己的数据,如果另一个服务确实需要保留该数据的引用,它们会通过 ID 来实现(本质上是实体链接)。虽然其他方面很好,但不适合报告。

我们的企业经常需要创建关于发生在我们客户身上的特定事件的临时报告。在 'old days' 中,您进行了一个简单的 SQL 查询,该查询连接了几个数据库表并查询了您需要的任何内容,但这对于解耦服务是不可能的。从企业的角度来看,这是一个问题。

我个人不喜欢在后端出于报告目的进行数据复制,因为这可能有另一种发展成噩梦的趋势(甚至在我们的遗留单体中已经如此)。所以这个问题实际上不是关于遗留单体与现代微服务的问题,而是关于一般数据依赖性的问题。

您遇到过这样的问题吗?如果遇到过,您是如何解决的?

编辑:

我们一直在内部讨论如何解决这个问题的几个潜在解决方案,但其中 none 实际上很好,我还没有得到我正在寻找的解决问题的答案大规模。

  1. 古老的复制一切并让 BI 人搞清楚的方法至今仍在使用。从旧的单体时代开始,BI/data-warehouse 团队对所有数据库进行了复制,但同样的做法更加不方便,但直到今天,所有使用数据库的微服务仍然这样做。由于各种原因,这并不好,并且您可以预料到共享沙箱癌症。

  2. 构建一个单独的微服务或一组用于获取特定报告的微服务。他们每个人都连接到设置微服务,微服务携带相关数据并按预期构建报告。然而,这引入了更紧密的耦合,并且对于大型数据集来说可能非常复杂和缓慢。

  3. 构建一个单独的微服务或一组微服务,每个微服务都在后台从其他数据库复制数据库。这是有问题的,因为团队数据库是耦合的,数据是直接复制的,并且对正在使用的数据库技术有很强的依赖性。

  4. 让每项服务向 RabbitMQ 发送一个事件,BI 服务将接收该事件,然后在需要时获取其他数据。这听起来对我来说是最好的,但实施起来最复杂,因为所有服务都需要开始发布相关数据。这是我目前个人会选择的,从一个非常抽象的层面,即。

所以,我不确定这是否会满足您的需求 - 但我将描述我们对 BI 的总体方法:

  1. 我们系统中的所有内容都会生成一个事件:后端中的操作、移动应用程序中的操作 - 我们要跟踪的所有内容都会生成带有相关数据(ID、时间、名称等)的事件。
  2. 所有事件都被发送到某个公共渠道进行收集 - 它是一个后端应用程序,用于接收事件 - 确保它们有效 - 并存储它们。
  3. 您可以将事件存储在某些非sql 存储(如 Elasticsearch)或云(如 google 的 BigQuery)中。
  4. 进入后,只需查询和交叉引用即可获得所需的整体情况。这就是我们的 BI 人员所做的:他们从我们收集的大量事件中生成图片。

解决方案是将来自不同服务的数据聚合到中央报告数据库中 - 如果收集的数据按时间版本化,这是可行的 - 即您可以转到报告数据并获取时间点数据是正确的(当时)

可以通过各种服务发布的事件或定期导入、"log"聚合或它们的组合将数据获取到服务。

我称这个模式为aggregated reporting

请注意,除此之外,您仍然需要从各个服务获取数据以获取需要更新的数据,因为聚合解决方案具有固有的延迟(降低新鲜度)

编辑: 考虑到您所做的编辑和您所做的评论(临时查询),我想说您需要将此视为一次旅程,也就是说,您想进入选项 4,因此首先从源中提取数据您必须回答您当前的临时需求,在您推进开发并添加更多来源时转换为消息。

您可能还需要考虑服务(它们之间不共享内部数据结构并且具有严格的界限)和方面(可以使用相同源的服务的半独立部分)之间的区别

PS 我还写道 InfoQ piece on BI & SOA Tom 在评论中提到 - 本质上是在谈论这个想法 - 这篇文章是从 2007 年开始的,即我已经成功应用它十多年了(不同的技术,从 schema 到在读取等时写入模式,但原则相同)