如何从多个微服务中过滤和排序数据?

时间:2018-01-26 09:27:49

标签: architecture microservices

我们有微服务,可以处理不同但相关的数据。例如,广告及其统计信息。我们希望能够为UI过滤,排序和聚合这些相关数据(而不仅仅是为了它)。例如,我们希望向用户展示具有' car'在他们的文本中,点击次数超过100次。

挑战:

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

要求:

  • 几秒钟内的最终一致性是可以的
  • 数据丢失是不可接受的
  • 对数百万行的大客户进行5到10秒的过滤和分类是可以的

我们可以想到的解决方案:

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

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

1 个答案:

答案 0 :(得分:5)

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

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

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

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

  

服务没有所有数据。

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

与CQRS非常合作的一个特殊情况是事件采购;它的优势在于您可以从乞讨时间获取事件,而无需将它们存储在持久性消息队列中。

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