Netflix 构建 Marken:可扩展的注释服务
Netflix 最近发布了其如何构建 Marken,这是一个使用 Cassandra、ElasticSearch 和 Iceberg 构建的可扩展注释服务。Marken 允许存储和查询任意实体的注释或标签。用户可以为他们的注释定义版本化的模式,这些模式包括对时间和空间对象的开箱即用支持。
注释的定义与用途
注释是可以附加到任何领域对象的元数据片段。一个简单的注释示例是“ID 为 1234 的电影实体包含暴力内容”。更复杂的实例包括机器学习算法,它可以识别帧中的角色,并希望以可查询的格式存储该信息。Marken 允许定义注释的模式、存储它们,并通过 CRUD 和搜索操作实时查询,同时使数据可用于离线分析。
技术选型与架构
Netflix 团队选择 Apache Cassandra 作为存储注释的真相源。Cassandra 是一个开源的宽列存储 NoSQL 分布式数据库,提供水平扩展性。他们选择 ElasticSearch 来支持搜索需求,并使用 Apache Iceberg 使数据可用于离线分析。整体架构如下图所示。
/filters:no_upscale()/news/2023/02/netflix-annotations-cassandra/en/resources/1Netflix-Marken-Architecture-1677060209813.png)
来源:Netflix 技术博客
客户端与内部服务
客户端通过多种 API 使用 Marken。机器学习算法通过模式化数据摄取数据,而最终用户应用程序(UI 应用程序和其他服务)使用 CRUD API 和自定义查询 DSL 来操作数据。在内部,Marken 使用多个辅助服务,如 Netflix 内部的模式服务来管理模式,以及 Apache Zookeeper。
数据规模与挑战
Netflix 最初使用 12 节点的 Cassandra 集群,并扩展到 24 个节点以支持当前的数据规模。一些 Netflix 标题有超过 300 万条注释(其中大部分是字幕)。目前,该服务拥有约 19 亿条注释,数据大小为 2.6TB。
数据摄取与系统响应
从机器学习数据管道摄取数据对系统响应能力提出了独特的挑战。Netflix 的高级软件工程师 Varun Sekhri 和 Meenakshi Jindal 描述了这个问题及其解决方案:
机器学习数据管道的摄取通常是批量的,特别是在设计新算法并为完整目录生成注释时。我们设置了一个不同的堆栈(实例群)来控制数据摄取流,从而为消费者提供一致的搜索延迟。在这个堆栈中,我们通过 Java 线程池配置控制对后端数据库的写入吞吐量。
搜索延迟
使用 ElasticSearch 进行文本查询的搜索延迟通常在毫秒级,而更复杂的语义搜索通常在几百毫秒内完成。下图展示了搜索查询的平均系统延迟。
/filters:no_upscale()/news/2023/02/netflix-annotations-cassandra/en/resources/1Netflix-Marken-Average-Latency-1677060209813.png)
*平均搜索延迟
来源:Netflix 技术博客*
/filters:no_upscale()/news/2023/02/netflix-annotations-cassandra/en/resources/1Netflix-Marken-Average-Semantic-Search-Latency-1677060209813.png)
*平均语义搜索延迟
来源:Netflix 技术博客*
离线分析
Marken 将所有数据持久化到 Apache Iceberg,以支持离线分析场景中的批量数据查询。Iceberg 是一个用于大型分析表的高性能格式。它允许像查询 SQL 表一样查询大数据,同时使 Spark、Trino、Flink、Presto、Hive 和 Impala 等引擎能够使用相同的表。通过使用 Iceberg,这些查询不会影响在线客户端(如 UI 应用程序)的延迟,从而在负载下保持整体系统响应能力。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。