GraphQL在微服务查询中实现聚合器与搜索索引的作用 -Netflix TechBlog

19-11-07 banq
                   

展示了Netflix如何利用GraphQL和Kafka和Elasticsearch来建立索引,通过总的查询聚合器以跨多个松耦合服务搜索数据。如何使用GraphQL中定义的关系和架构自动构建和维护搜索数据库。

Netflix的营销技术

我们的目标是在全球推广Netflix的内容。Netflix在该服务上拥有数千个节目,在190多个国家/地区运营,并支持大约30种语言。对于这些节目,国家和语言,我们需要找到与每个潜在观众产生共鸣的合适广告素材。我们的团队构建了在全球范围内制作和分发这些营销创意的工具,每个月为数十亿次的展示提供动力!

为了使我们的营销利益相关者能够管理这些创意,我们需要将分布在许多服务中的数据汇总在一起-GraphQL使这种聚合变得容易。

举例来说,我们的数据以广告素材服务为中心,以跟踪我们制作的广告素材。每个广告素材都会通过其所推广的节目的更多信息得到增强,并且该节目在全球范围内的排名也得到了进一步的提高。此外,我们的营销团队可以在需要调整时对广告素材发表评论。我们维护着更多的关系,但在本篇文章中,我们将重点关注这些关系。

搜索分散数据的挑战

显示一个广告素材的数据很有帮助,但是我们有很多广告素材可供搜索。如果我们为Netflix支持的每个节目,语言和国家/地区仅制作少量变体,则将产生超过 5,000万个广告素材。我们需要一个合适的搜索解决方案。

问题源于我们试图跨松散耦合的多个独立服务搜索数据的事实。没有任何一项服务可以完全了解系统的工作方式。每个服务都可能实现其自己的搜索数据库,但是我们仍然需要一个聚合器。该聚合器将需要执行更复杂的操作,例如即使排名数据存储在另一服务中处,也可以通过排名搜索创意。

如果我们有一个包含所有信息的数据库,那么搜索将很容易。我们可以编写几个join语句和where子句:问题已解决。但是,单体数据库有其自身的缺点,主要是围绕允许团队独立工作的有限灵活性和大规模的性能限制。

另一种选择是使用自定义聚合服务,该服务将构建自己的数据索引。该服务将了解每个数据的来源,了解所有数据的连接方式,并能够以多种方式组合数据。除了索引部分之外,这些特征还完美描述了GraphQL中的实体关系。

索引数据

由于我们已经使用GraphQL,我们如何利用它来索引数据? 我们可以稍微更新GraphQL查询以检索单个广告素材及其所有相关数据,然后对数据库中的每个广告素材调用一次该查询,将结果索引到Elasticsearch中。通过批量处理和并行化请求以通过对GraphQL服务器的单个查询来检索许多广告素材,我们可以优化索引构建过程。

当为数据建立索引时,Elasticsearch有很多自定义选项,但是在许多情况下,默认设置可以提供很好的结果。至少,我们从GraphQL查询中提取所有类型定义,并将它们映射到可供Elasticsearch使用的模式。

使用GraphQL查询生成模式的好处是,任何依赖于此数据的现有客户端都将获得相同形状的数据,无论它来自GraphQL服务器还是直接来自搜索索引。

索引完数据后,我们可以对任意字段进行排序,分组和过滤;向我们的用户提供提前建议;显示构面以进行快速过滤;并逐步加载数据以提供无限的滚动体验。最棒的是,由于所有内容都已缓存在Elasticsearch中,因此我们的页面可以加载得更快。

保持一切最新

仅索引一次数据是不够的。我们需要确保索引始终是最新的。我们的数据不断变化-营销用户对广告素材进行编辑,我们的推荐算法会刷新以提供最新的标题受欢迎程度排名等。幸运的是,我们有Kafka事件,每次数据变化时都会发出该事件。第一步是听这些事件并采取相应的行动。

当我们的索引器听到更改事件时,它需要找到所有受影响的广告素材并重新索引它们。例如,如果标题排名发生变化,我们需要找到相关的节目,然后找到其对应的广告素材,并重新为其编制索引。我们可以对所有这些规则进行硬编码,但是随着数据的发展以及针对我们构建的每个新索引,我们都需要使这些规则保持最新。

幸运的是,我们可以依靠GraphQL的实体关系来找到需要重新索引的对象。我们的搜索索引器通过访问共享的GraphQL模式或使用自省查询来检索模式来理解这些关系。

设置

我们建立了所有这些逻辑,用于建立索引,与GraphQL进行通信以及将更改处理到搜索索引器服务中。为了设置搜索索引器,有一些要求:

  1. 卡夫卡。索引器需要知道何时发生更改。我们使用Kafka来处理更改事件,但是任何可以将数据更改通知索引器的系统都足够。
  2. GraphQL。为了应对变化,我们需要一个支持自省的GraphQL服务器。该图有两个要求。首先,每个顶点必须具有唯一的ID,以使其易于在搜索步骤中识别。其次,为使扇出正常工作,图中的边缘必须是双向的。
  3. Elasticsearch。数据需要存储在搜索数据库中以便快速检索。我们使用Elasticsearch,但还有许多其他选项。
  4. 搜索索引器。我们的索引器结合了以上三个项目。它配置有GraphQL服务器的终结点,与搜索数据库的连接以及从Kafka事件到图形顶点的映射。

具体详细点击标题见原文