【问题标题】:How to filter and sort data from multiple microservices?如何过滤和排序来自多个微服务的数据?
【发布时间】:2018-07-05 15:10:06
【问题描述】:

我们的微服务可以处理不同但相关的数据。例如,广告及其统计信息。我们希望能够为 UI 过滤、排序和聚合这些相关数据(而不仅仅是它)。例如,我们希望向用户展示其文字中包含“汽车”且点击次数超过 100 次的广告。

挑战:

  • 可能有很多数据。部分用户过滤后有数百万行
  • 服务没有所有数据。例如,对于没有统计信息的统计服务广告 == 不存在的广告。它对此类广告一无所知。但是排序和过滤无论如何都应该起作用(没有统计信息的广告应该被视为没有零点击的广告)

要求:

  • 几秒钟内的最终一致性是可以的
  • 不能接受数据丢失
  • 5 到 10 秒过滤和排序数百万行的大客户就可以了

我们能想到的解决方案:

  • 从所有服务中加载查询所需的所有数据,并在内存中过滤和排序。
  • 将更新从服务推送到 Elasticsearch(或类似的东西)。 Elastic 处理查询并返回所需实体的 ID,然后从服务中加载。
  • 一个包含所有服务的大型数据库

我们应该注意什么?还有其他方法可以解决我们的问题吗?

【问题讨论】:

    标签: architecture microservices


    【解决方案1】:

    您可以使用CQRS。在这种低级架构中,用于写入数据的模型与用于读取/查询数据的模型分开。写入模型是规范的信息来源,是事实的来源。

    写入模型以最终一致的方式发布由一个或多个读取模型解释/投影的事件。这些事件甚至可以在消息队列中发布并由外部读取模型(其他微服务)使用。从写入到读取没有 1:1 的映射。您可以有 1 个用于写入的模型和 3 个用于读取的模型。每个读取模型都针对其用例进行了优化。这是您感兴趣的部分:速度优化的读取模型。

    优化的读取模型在回答查询时拥有所需的一切。数据完全非规范化(这意味着它不需要连接)并且已经被索引。

    读取模型可以对其数据进行分片。您这样做是为了最小化集合大小(小集合比大集合快)。在您的情况下,您可以按用户分片:每个用户都有自己的统计数据集合(即 SQL 中的表或 NoSQL 中的文档集合)。您可以使用数据库的内置分片,也​​可以手动分片,方法是将其拆分为单独的集合(表)。

    服务没有所有数据。

    读取模型可以订阅许多事实来源(即微服务或事件流)。

    一个非常适合 CQRS 的特殊情况是事件溯源。它的优点是您可以从时间的乞求中获得事件,而无需将它们存储在持久消息队列中。

    附注在给定足够的硬件资源的情况下,当读取模型无法足够快时,我无法考虑用例。

    【讨论】:

    • 然后您可以使用CDC 生成低级更改事件,并在此基础上维护优化的读取模型。 CDC 也被称为 CQRS 的穷人事件溯源
    • CQRS 和事件采购对于一家小公司来说是一笔巨大的投资。不仅在存储要求方面,而且在实施/维护复杂性方面。如果您已经实现了大部分服务,那么以事件源的方式“重写”它们将是一个巨大的问题。此外,将“CQRS / Event-Sourcing”作为低级架构强制执行,有人会说这被认为是反模式:infoq.com/news/2016/04/event-sourcing-anti-pattern。从理论上讲,这似乎是一个很好的解决方案,但我不确定在这种情况下是否值得冒险。
    • @Anton 我正在提议 CQRS,我的答案中仅将事件溯源列为非强制性步骤。另外,请阅读我对 CDC 的评论。
    • @Constantin 我想如果没有事件源和更新读取模型的“异步”方法,您将需要一种反向通道来重建读取模型。消息可能会丢失和跟踪,这可能是一个大问题。
    • @Anton 没有适用于所有情况的 100% 完美解决方案,但有足够好的解决方案。例如,您可以在消息队列之上构建事件日志,并在与写入模型持久性相同的事务中将事件发布到此事件日志。
    【解决方案2】:

    挖掘话题。

    伊莫。事件溯源可能是多余的(它可能需要重写部分应用程序)。

    为什么不创建某种query service 来收集和聚合排序、过滤和分页所需的数据。它只会以所需的顺序和计数返回 id。

    可以使用以下方式收集数据:

    • 消息队列(性能更好,但数据可能不一致)。
    • 直接服务调用(更一致的数据,但您必须注意性能损失 - 写入 query service 的服务的响应时间更长)。

    【讨论】:

      猜你喜欢
      • 2017-03-24
      • 1970-01-01
      • 2014-08-08
      • 2019-12-28
      • 2021-12-12
      • 2021-12-10
      • 2019-04-28
      • 1970-01-01
      • 2019-12-04
      相关资源
      最近更新 更多