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

Art*_*nko 10 architecture microservices

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

挑战:

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

要求:

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

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

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

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

Con*_*enu 5

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

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

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

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

服务没有所有数据。

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

一个与CQRS很好配合的特殊情况是事件源。它的优点是您可以从时间开始获取事件,而无需将其存储在持久消息队列中。

PS:在足够的硬件资源的情况下,无法快速建立读取模型时,我无法考虑用例。

  • CQRS 和事件溯源对于小公司来说是一笔巨大的投资。不仅在存储要求方面,而且在实施/维护复杂性方面。如果您已经实现了大部分服务,那么以事件源方式“重写”它们将是一个巨大的问题。此外,强制“CQRS / Event-Sourcing”作为低级架构,有些人会说这被认为是一种反模式:https://www.infoq.com/news/2016/04/event-source-anti-图案。从理论上讲,这似乎是一个很好的解决方案,但我不确定在这种情况下是否值得冒这个风险。 (4认同)