一、Alluxio 应用场景和背景
Alluxio 跨集群同步机制的设计和实现确保了在运行多个 Alluxio 集群时,元数据是一致的。
Alluxio 位于存储和计算层之间,在不同的底层文件系统(UFS)上层提供高性能缓存和统一的命名空间。虽然通过 Alluxio 对 UFS 进行更新可使 Alluxio 与 UFS 保持一致,但在某些情况下, 例如在运行多个共享某一个或多个 UFS 命名空间的 Alluxio 集群时,结果可能并非如此。为了确保这种情况下的一致性,Alluxio 已经实现了跨集群同步机制,本文将对该机制进行详细介绍。
1. 背景介绍
随着数据量的增长,这些数据的存储和访问方式也变得越来越复杂。例如,数据可能位于不同的存储系统中(S3、GCP、HDFS 等),也可能存储在云上或本地,或是位于不同的地理区域,还可能因为隐私或安全保护,被进一步隔离。此外,这些复杂性不仅体现在数据存储上,还包括如何将数据用于计算,例如,数据可能存储在云上,而计算则在本地进行。
Alluxio 是一个数据编排平台,通过在 UFS 上提供统一的访问接口来降低此类复杂性,并通过提供数据本地性和缓存来提高计算性能。
对于许多组织而言,运行一个 Alluxio 集群可能就足够了,但有些组织需要运行多个 Alluxio 集群。例如,如果计算是在多个区域运行,那么在每个区域运行一个 Alluxio 集群可能会带来更大的优势。此外,某些组织可能出于数据隐私保护的考虑,需要运行独立的集群,或是希望通过运行多个集群来提高可扩展性。虽然部分数据空间可能被隔离在某个集群中,但其他数据可以在多个集群之间共享。例如,一个集群可能负责提取和转换数据,而其他几个集群可能会查询这些数据并进行更新。
由于每个 Alluxio 集群可能会复制(即挂载)UFS 存储空间的某些部分,Alluxio 会负责保持其副本与 UFS 的一致性,以便用户查询到最新的文件副本。在本文中,我们将介绍在一个或多个集群中确保 Alluxio 数据与 UFS 一致所用到的组件。
2.Alluxio 数据一致性
在分布式系统中保持数据的一致性是很复杂的,其中有几十个不同的一致性级别,每个级别都允许不同的用户在特定时间查询和修改数据的不同状态。这些一致性级别形成了一个从弱到强的范围区间,一致性越强限制越多,通常越容易在上面搭建应用程序。Alluxio 也不例外,它会根据配置和使用的 UFS 提供不同的一致性保障(详细信息见 Alluxio 的数据一致性模型)。
为了简化关于一致性的讨论,我们将做如下假设:
● 对于任何文件,UFS 都是文件的 "唯一数据源"。
这意味着 Alluxio 中的每个文件都对应于 UFS 上的一个文件,并且 UFS 中总是有该文件的最新版本。如果 Alluxio 存储的文件副本与 UFS 中的文件不同,那么 Alluxio 中的文件版本是不一致的。(这里我们假设 UFS 本身确保了强一致性,即某种程度的线性一致性(linearizability)或外部一致性(external consistency)。从高层次来看,这允许用户把 UFS(即便系统是由许多分布式部分所组成) 当作类似实时按顺序执行操作的单一的文件系统来访问。
在讨论 Alluxio 和 UFS 的一致性之前,让我们先来看一下 Alluxio 的基本架构。Alluxio 是由 master 节点和 worker 节点组成的。master 节点负责跟踪文件的元数据,例如它的路径、大小等,而 worker 节点负责存储数据本身。如果 client 要读一个文件,必须先从某一个 master 节点上读取元数据,然后用它来定位存储该数据副本的 worker(必要时可以从 UFS 上加载数据)。如果 client 要写一个文件,必须首先在 master 中为该文件创建元数据,然后通过 worker 将该文件写到 UFS,最后在 master 上将该文件标记为完成。当文件正在被写入时,它的元数据会被标记为未完成,从而阻止其他 client 访问该文件。
从这个基本设计中,我们可以看到,只要所有对文件的更新都通过 Alluxio 写入 UFS,那么 Alluxio 中的数据将与 UFS 中的数据保持一致,client 将会始终查询到最新的数据版本。
然而现实情况,并没有这么简单,例如,某些用户可能在更新 UFS 时不通过 Alluxio,或者 client 可能出现故障,只将部分文件写入 UFS,而没有在 Alluxio master 上标记完成,这些都可能导致 Alluxio 和 UFS 中的数据不一致。
那么,这些问题是如何处理的呢?由于我们重点假设了 UFS 是唯一的数据源,要解决这些不一致的问题只需让 Alluxio 与 UFS 同步即可。
3. 元数据同步
元数据同步是用来检查和修复 Alluxio 和 UFS 之间不一致的主要组件。当 client 访问 Alluxio 中的某个路径时,该功能在一定条件下(后面会讨论)可能会被触发。基本程序如下:
● 从 UFS 加载该路径的元数据。
● 将 UFS 中的元数据与 Alluxio 中的元数据进行比较。元数据中包含文件数据的指纹(例如最后修改时间和抗碰撞的哈希值),可用于检查数据不一致情况。
● 如果发现任何不一致,则更新 Alluxio 中的元数据,并标记过时的数据,以便将其从 worker 中驱逐。最新数据会根据需要从 UFS 加载到 worker。