【问题标题】:Micro Services and noSQL - Best practice to enrich data in micro service architecture微服务和 noSQL - 在微服务架构中丰富数据的最佳实践
【发布时间】:2015-12-13 01:09:35
【问题描述】:

我想规划一个解决方案,在我的架构中管理丰富的数据。
更清楚一点,我有几十个微服务。
假设 - 国家、建筑物、楼层、工人。
全部运行在一个单独的 NoSql 数据存储上。

当我从工作人员服务获取数据时,我还想提供楼层名称(工作人员正在工作)、建筑物名称和国家/地区名称。

解决方案 1。
客户端将查询所有微服务。
问题 - 多个请求并让客户了解结构。
我知道多个请求不应该打扰我,但我相信在一次调用中返回描述实体的 json 会更好。

解决方案 2。
创建一个从多个服务中检索数据的编排。
问题 - 如果数据(例如实体名称)未存储在数据库中的同一文档中,则很难按这些字段进行排序和过滤。

解决方案 3。
在保存实体之前,例如工人,调用所有其他服务并填写相关数据(建筑物名称,国家名称)。
问题 - 更改建筑物名称时,它不会反映在工作人员服务中。

解决方案 4。
(这是我能想到的最好的一个)。
创建一个订阅代理并接收所有实体更改的流程。
对于每个实体,它都会更新所有相关实体。
当实体发生变化时,比如建筑物名称发生变化,它会更新所有包含建筑物名称的文档。
问题: 每个服务都必须知道可以更新什么。 当发生尾随更新时,它不应再次更新代理(递归更新),因此这可能会使微服务变得复杂。

解决方案 5。
保持一切正常化。在 ElasticSearch 中过滤和排序。 问题:在 ES 中保存规范化数据在性能方面过于昂贵

【问题讨论】:

    标签: microservices


    【解决方案1】:

    我看到 Netflix 做的一件事(我喜欢)就是为这样的东西创建中介服务。所以也许是一个新的中介服务,它可以调用其他服务来收集所有数据,然后用 Country、Building、Floor、Worker 创建统一的输出。

    您甚至可以更进一步,尝试提出一种方案,以提供您想要包含在输出中的资源作为输入。

    所以我想这与您的解决方案 2 非常匹配。我注意到您在解决方案 2 中提到数据库中的排序/过滤存在问题。我认为,如果您使用 NoSQL,那一定是有原因的,而且更多时候不是出于性能的原因。我认为如果这样做是错误的,那么是的,你会遇到问题,但如果所有可搜索的适当字段都正确键入和索引(正如@Roman Susi 在他的要点 1 和 2 中提到的那样),那么我不认为这是一个问题。是的,这项服务只会与您的其他服务和数据存储的高潮一样快,因此它们必须快速。

    现在您可以保持各个微服务保持原样,让客户端继续调用一个服务,并封装将数据合并到这个新服务中的复杂性。

    这是我在 (https://www.youtube.com/watch?v=StCrm572aEs) 中看到的视频……视频很长,但信息量很大。

    【讨论】:

      【解决方案2】:

      解决方案 N 级别的建议很难,但以下建议可以避免某些问题:

      1. 对实体使用全局唯一标识符。例如,通过为键值分配某种 URI。

      2. 全局 ID 还简化了更新,因为您可以跟踪实际更改的内容、名称或实体。 (实体与全局 URI 是一对一的关系)

      3. CAP 定理说您只能从 CAP 中选择两个。你想要一个 CA 架构吗?还是CP?或者也许是AP?这将严重影响您分发数据的方式。

      4. 对于“排序和过滤”,有 MapReduce 方法,它可以分配找出这些东西的负载。

      5. 仔细考虑规范化/非规范化的平衡。如果您的服务在 URI 上运行,您可以拥有将 URI 转换为标签(名称、描述等)的服务,但您不需要在任何地方保留冗余信息并对其进行更新。不做初步优化,但尽量保持数据标准化。这样,worker 甚至可能不需要建筑物名称,而是全局 ID。微服务从另一个微服务中查找元数据。

      6. 换句话说,作为关注点分离的一部分,尽量减少服务之间共享的密钥数量。

      7. 关注底层模型,而不是往返的 JSON。对系统中的数据进行正确建模比节省 JSON 调用更能获得好处。

      至于 NoSQL,看看 Riak 数据库:它具有可调整的 CAP 属性,IIRC。即使您不这样使用它,阅读它的文档也可能有助于为您的分布式微服务系统提出合适的架构。 (当然,这适用于您基本上具有并行系统的情况)

      【讨论】:

      • 谢谢。您能详细说明 mapReduce 方法吗?目前在标准化方法中,我必须对我的 elasticSearch 进行多次查询。
      • 您说的是每个服务的 NoSQL 存储。 MapReduce 是关于在这些存储之间分配计算(以防负载很大并且有很多数据)。 ES 是中心化的解决方案,如果它适合你的需要,那为什么还要去中心化和 NoSQL?一切都可以在一个地方(RDBMS、NOSQL 或其他)+ 正确复制。不知道运营规模很难说。
      • 我不想提及它,但从一开始我就认为 RDF / SPARQL 解决方案也可能适合您,因为您不需要特别费心从您的服务中联合数据:有几个来源可以组合在一个 SPARQL 查询中。 ES 来索引文本数据。
      【解决方案3】:

      首先,感谢您的提问。它类似于文档数据库的主要问题:如何按字段从另一个集合中对集合进行排序?我对此有自己的答案,所以我会尝试评论您的所有解决方案:

      解决方案 1:如果客户想要独立使用 Country/Building/Floors,那就太好了。但是,它不能解决您在解决方案 2 中提到的问题 - 通过构建来分类 10k 工人会很慢

      解决方案 2:与解决方案 1 类似,如果所有客户想要的是一个丰富的工人列表而不知道如何将多个部分组合起来

      解决方案 3:如您所说,由于数据不一致而无法接受。

      解决方案 4:大部分时间都可以工作。但是:

      • 大量数据重复。如果您有 20 个实体,您将拥有 x20 数据。
      • 复杂度高。 20 个实体 -> 20 种不同的程序来更新相关数据
      • 高内聚力。您的所有服务必须相互了解。由于更新过程,数据模型更改将传播到每个服务
      • 最终一致性存疑。可以这样做,以便在失败后数据保持一致,但这并不容易

      解决方案 5:答案类型 :-)

      但是 - 你并不想要一切。保留服务于分离实体的分离服务,并在它们之上构建其他服务。

      如果客户想要丰富的数据 - 构建返回丰富数据的服务,如解决方案 2 中所示。

      如果客户想要通过过滤和排序显示丰富数据的列表 - 构建一个提供过滤和排序功能的丰富数据的服务!很可能,此类服务的实现将包含 ES 实例,其中包含来自较低级别服务的缓存和索引数据。这里的重点是 ES 不必包含所有内容或在每个服务之间共享 - 由您决定更好地平衡性能和基础架构资源。

      【讨论】:

        【解决方案4】:

        这是Linked Data可以帮助你的一个案例。

        基本上,worker 的 Floor 属性是指向楼层本身的 URI(链接)。并且任何其他链接数据也应表示为 URI。

        用一些 JSON-LD 建模,它看起来像这样:

        worker = {
          '@id': '/workers/87373',
          name: 'John',
          floor: {
            '@id': '/floors/123'
          }
        }
        
        floor = {
          '@id': '/floor/123',
          'level': 12,
          building: { '@id': '/buildings/87' }
        }
        
        building = {
          '@id': '/buildings/87',
          name: 'John's home',
          city: { '@id': '/cities/908' } 
        }
        

        这样,客户端所要做的就是将 BASE URL(如 api.example.com)附加到 @id 并进行简单的 GET 调用。

        为了消除客户端的额外调用负担(如果它是一个速度较慢的移动设备),我们将网关模式与微服务一起使用。网关可以毫不费力地扩展这些链接并增加返回对象。它还可以并行执行多个调用。

        因此网关将发出 GET /floor/123 调用并用回复替换工作人员上的楼层对象。

        【讨论】:

          猜你喜欢
          • 2019-10-25
          • 2020-04-07
          • 2016-05-24
          • 1970-01-01
          • 2017-11-30
          • 1970-01-01
          • 1970-01-01
          • 2014-01-08
          相关资源
          最近更新 更多