由 Esha Palta,Ankur Khetrapal,Shannon Heh,Isabell Lin,和Shunfei Chen 编著
介绍Netflix 开创了云端工作室(Studio in the Cloud)的理念,让艺术家能够从世界各地创作故事和资产来娱乐全世界。数据从摄像机产生之后,它会经历许多阶段,其中一些阶段如下所示。在这一过程的每个阶段中,媒体都会经历全面的备份,频繁上传和下载。为了支持这些流程和工作室应用,我们需要提供一个分布式、可扩展的和高性能的媒体云存储系统。
图1:内容创作过程(或流程)(Studio)
转向资产存储,所有这些媒体文件都通过亚马逊的简单存储服务(S3)安全传输和存储。Netflix 维护这些对象的身份信息,以便存储基础设施层能够引用这些对象,并附带有关这些对象的其他重要元数据。
在边沿,艺术家们处理资产时,无论是艺术家的应用程序还是艺术家本人,都期望有一个文件/文件夹界面,以便能够方便地访问这些文件,而不需要额外的转换工具——我们希望艺术家在使用工作室软件时能有一个无缝流畅的体验。这不仅适用于艺术家,还包括工作室的整个工作流程。一个很好的例子就是在内容渲染过程中,资产会发生转换。
我们需要一个系统,能存储和管理数十亿个媒体文件,并提供一个用户熟悉的文件夹接口,让用户可以自由上传文件,并进行诸如创建、更新、移动、复制、删除、下载、共享和获取任意树形结构等操作。
为了有效、可靠和安全地满足云管理的全球分布式工作室的需求,我们的媒体存储平台团队构建了这样一个高度可扩展的元数据存储服务——内容引擎。
内容驱动 (或简称 CDrive) 是一种云存储方案,提供了文件和文件夹接口,可以以可扩展且安全的方式存储、管理和访问奈飞的媒体资产的目录。它使应用程序(如内容中心UI)能够上传媒体内容到S3、管理其元数据、应用生命周期策略,并提供内容共享的访问权限控制。
在这篇帖子中,我们将介绍CDrive服务。
特点- 存储、管理和跟踪数十亿个文件和文件夹,同时保留文件夹结构。提供一个类似 Google Drive 的界面,让用户可以上传自由格式的文件,并提供创建、更新、移动、复制、删除、下载、共享和获取任意树状结构等操作的管理功能。
- 提供文件和文件夹的查看、上传和下载的访问权限。
- 协作/共享 — 共享未完成的工作文件。
- 数据传输清单和令牌生成 — 在验证授权的情况下,为请求的文件或文件夹生成下载清单和令牌。
- 文件和文件夹通知 — 提供文件和文件夹的更改通知。这不仅支持实时共享和协作场景,还可以帮助依赖后端应用围绕数据摄取完成业务流程。
CDrive 的组件
- 提供创建和管理文件/文件夹、管理文件/文件夹共享以及获取文件/文件夹上传/下载授权端点的 REST API 和 DGS(图数据查询语言)层。
- CDrive 服务层执行实际创建和管理树状结构的工作(实现创建、更新、复制、移动、重命名、删除、校验和验证等文件/文件夹结构操作)。
- 提供基于用户和应用程序的文件/文件夹访问控制功能。
- 数据传输层负责传输跟踪和生成传输令牌,在授权后。
- 持久层负责执行文件/文件夹在 CDrive 中的元数据读取和更新事务。
- 事件处理程序生成事件通知,供用户和应用程序消费并采取行动。例如,CDrive 会在文件夹上传完成后生成一个事件。
图3所示:CDrive使用示例
图3显示了CDrive的一个使用示例。我们可以看到,不同的用户通过自己的用户凭证访问他们各自的工作区,并且可以在自己的工作区中执行所有文件和文件夹的操作,包括上传和下载。
设计和理念CDrive 存储和管理文件及文件夹的详细信息,按照层级树结构。它允许用户和应用程序将文件放入文件夹中,将文件和文件夹放入工作区中,并支持创建、更新、删除、移动和复制等操作。
树形结构属于独立的工作区(或分区),其中包含文件夹作为分支节点,文件作为叶节点,文件夹本身也可以成为叶节点。
CDrive 用 CockroachDB 用来存储其元数据和目录结构。选择 CockroachDB 的原因有几点:
- 为了确保操作的强大一致性保证,数据的类型和正确性非常重要。CDrive 维护每个文件/文件夹的 不变性,即每个文件路径唯一标识一个 CDrive 节点。这意味着在任意时刻,每个文件路径都对应一个唯一的 CDrive 节点。
- 复杂查询的需求。CDrive 需要支持各种复杂的文件/文件夹操作,例如创建、合并、复制、移动、更新元数据、批量获取等操作,这需要持久层能够以优化的方式执行连接查询。
- 分布式事务的需求。CockroachDB 的内部分片架构支持分布式事务。CDrive 的数据模型允许其高效地执行元数据操作。
每个文件、文件夹或工作区在 CDrive 中都由一个节点结构表示。文件路径始终对应一个唯一的 CNode。这意味着任何修改文件路径的元数据操作都会生成一个新的 CNode,而旧的 CNode 将被标记为已删除。例如:每次复制文件时,CDrive 会为该文件路径创建一个新的 CNode。
一个 CDrive 节点可以是以下类型中的任意一种:
- 根/工作区:这是使用CDrive创建应用程序和项目文件/文件夹层次结构的顶级分区。它类似于操作系统中的磁盘分区概念。
- 文件夹:用于包含其他容器或文件的容器。
- 文件:指向特定数据位置的独立文件。
- 序列:序列是CDrive中的特殊文件夹容器,可以容纳数百万个文件。它被创建来表示如离机拍摄素材这样的特殊媒体文件,这些文件由一系列帧组成,形成一个简短片段。序列中的所有帧文件都以相同的前缀和后缀开头,但根据帧号有所不同,例如 frame.##.JPG。序列可以包含任意范围的帧列表(起始索引和结束索引)。序列可以提供数百万帧的概要,而无需查看每个文件。CDrive提供在获取操作时可扩展序列的API选项。每当上传文件夹时,CDrive服务器都会检查文件夹中的序列文件,并将它们归类为一个序列。
- 快照:快照是一种特殊的CNode容器,确保其子树是不可变的。不可变子树是从一个不可变的文件夹中浅复制的元数据。通常,应用程序创建快照来“锁定”文件或文件夹,防止进一步更改,以表示一个资产的状态。
图4. CDrive节点层级结构表示图
CNode 的元数据(即关于 CNode 的数据信息)每个 CNode 包含与该节点相关的属性值。每个节点的基本元数据包括 UUID、名称、父节点 ID、路径、大小、校验和、状态和数据存放位置。为了效率,CNode 还包含其目录路径(以节点 UUID 和目录文件路径的形式表示)。
基于亲子层级的关系所有的CNodes都维护对其父节点ID的引用。这就是CDrive保持层级树结构的方法。父节点表示文件夹关系,根节点没有父节点。
数据存放位置每个 CNode 文件包含一个链接或 URL,指向该文件的实际数据字节存储位置(例如,在 S3 中)。即使移动了 CNode,其数据位置也不会改变。如果 CNode 用于复制操作,多个 CNode 可以引用同一个数据位置。一个文件 CNode 可以出现在多个物理位置。CDrive 提供了这些位置的文件传输状态信息(未知/新建/可用/失败),使读者更容易理解。
图5. 节点和数据位置的表示法
并发和一致CDrive 允许多个用户或应用程序同时访问共享文件或文件夹。CDrive 利用 CockroachDB 的可序列化事务来支持这一点,并确保每个节点在 CDrive 中都有一个唯一的文件路径。
复制或移动这样的操作会将更改传播到被修改的子树中的所有子节点。这会更新所有这些节点的元数据,如父节点、文件路径和分区等。
如果任何操作出现路径冲突,CDrive 让用户选择合并,让用户决定是否用新信息替换旧路径,或者保留现有路径,或放弃该操作。
访问权限:在 CDrive 中,授权是基于分区或工作区类型进行的,正如前面提到的工作区部分所述。由应用程序管理的工作区可以通过集成 CDrive 的授权回调来控制对这些文件/文件夹的访问。相比之下,用户对其个人工作区内的文件和文件夹拥有完全的控制权。
CDrive 通过共享文件/文件夹来协作,可以设置任意权限或基于用户的访问控制。如果一个文件夹或顶级 CNode 以一组权限共享,例如读取和下载权限,那么此访问控制将应用于该子树中的所有文件或文件夹。CDrive 还支持创建团队文件夹,让不同地理位置的艺术家可以协作。一个艺术家的更改会在其他艺术家的最新共享文件夹中可见。
CDrive 在云端充当其他 Netflix 服务的代理层,因为它为文件和文件夹提供用户级别的权限验证。对于每次操作,CDrive 从请求中获取初始的用户或应用环境,并验证该用户或应用是否有相应的权限来操作这些 CNodes。
工作台CDrive 中的所有树形结构都属于一个唯一的 工作区。CDrive 中的 工作区 是一个隔离的文件/文件夹逻辑分区。工作区 定义了该分区中的文件和文件夹的授权模型、可变性和数据生命周期。工作区 可以是以下几种类型。
个人工作区/用户工作区用户工作区用于存储每个生产项目中的进行中文件。因此,用户工作区内的文件和文件夹被认为是可变的。个人工作区中的所有文件和文件夹的数据保留时间较短,在项目启动后,可以对这些临时文件应用简单的清理策略,因为这些临时文件就不再需要了。它使用了一个简单的授权模型,只有该用户可以访问这些文件。用户还可以通过共享功能让其他人访问这些节点。
应用/项目的 工作空间应用或项目工作区用于存储已经完成且不需要进一步修改的资产。因此,这些工作区具有不可变的树状结构。它使用了一个联邦式的授权模型,将权限委托给与该工作区关联的所有者应用。因为这些资产需要永久保存,所以不能在整个工作区层面应用数据生命周期策略。对于归档或删除的数据生命周期决策是针对单个文件或文件夹进行的。我们有一篇博客文章详细介绍了智能数据生命周期管理方案,详情请参阅这里。
共享/团队空间共享工作区在可变性上与用户工作区类似。唯一的区别在于它由 CDrive 所有并用于项目中的用户协作。共享工作区下任何文件或文件夹的访问权限基于与节点相关的访问控制列表。在这些工作区,数据生命周期管理遵循和用户工作区相似的规则。所有属于共享工作区的文件或文件夹都仅在项目制作期间保留,被视为临时文件。
数据和统计信息- 截至2024年10月为止:CDrive 大约存储了约142亿个文件和文件夹的元数据
- 848000个工作空间:其中70%是用户,27%是项目,3%是团队
- 每周平均新增大约5000万个CDrive节点
按其功能类型分类的CNodes总数
- 基于内容驱动的ContentHub界面每周访问总数
- 各工作室和制作部门浏览UI页面进一步强调了内容主导对业务的重要性。
- 该图表提供了一天内服务器级每步请求数量和总体P90延迟的快速概览。
我们将陆续分享我们正在研究的一些有趣问题。
- 搜索——CDrive 提供了根据分区下的文件路径进行搜索的 API,但我们还没有提供基于任意属性的节点搜索功能。对于机器学习和用户相关流程而言,应用程序或项目中的用户搜索能力非常有用。
- 分片——随着数据呈指数级增长,CDrive 正面临一个新的挑战,即为包含数百万文件/文件夹的容器服务读取查询。CDrive 计划通过增加分片支持来解决这一问题。其想法是将巨大的容器分割成多个分片。这可以降低容器的检索成本。
- CDrive 版本控制——Studio 应用程序需要支持“艺术家文件会话”的能力,即艺术家可以查看他们工作区中文件和文件夹的更改、接收更改通知、刷新艺术家的工作站,并恢复到某个时间点的版本。为满足这一新需求,CDrive 需要提供类似云文件系统的版本控制和更改跟踪功能。
特别感谢我们这些优秀的同事们Rajnish Prasad, Jose Thomas, Olof Johansson, Victor Yelevich, Vinay Kawade, Shengwei Wang。