共计 3921 个字符,预计需要花费 10 分钟才能阅读完成。
元数据同步(metadata sync)是 Alluxio 的一个外围性能,它能使文件和目录与底层存储系统中的数据源保持一致,便于用户通过 Alluxio 获取最新数据。同时,理解外部过程对于性能调优也非常重要。本文介绍了 Alluxio 元数据同步性能的设计和实现。
在 Alluxio 中,元数据是指 Alluxio 文件系统中的文件和目录信息,包含所有者、组、权限、创立和批改工夫等信息。元数据独立于其内容,即便是空的文件或目录仍然领有关联的元数据。
Alluxio 保护底层存储的文件系统或对象存储命名空间的正本。在 Alluxio 中,元数据的一致性十分重要,尤其是不同的集群在数据工作流中写入或读取数据,对底层存储的文件间接进行批改时,并不通过 Alluxio。
上图是一个典型的场景,该数据工作流同时应用了 Spark ETL 和 Presto SQL。ETL 集群(未部署 Alluxio)写入数据,而后由部署了 Alluxio 的剖析集群读取转换后的数据。因为 Alluxio 保护底层存储中的元数据正本,并对元数据进行治理,所以当底层存储的数据通过 ETL 步骤发生变化时,必须让剖析集群上的 Alluxio 实例感知到并与底层存储系统中的元数据保持一致,只有这样能力持续失常运行。
Alluxio 在一个或多个存储系统下的对立命名空间中提供文件系统形象。通过 Alluxio 拜访文件或目录,会失去与间接拜访底层存储雷同的后果。例如,如果挂载到 Alluxio 根目录的底层存储是 s3://bucket/data,那么在 Alluxio 中列出 ”/” 目录的后果与在 s3://bucket/data 中列出对象的后果雷同,在 Alluxio 中打印 ”/file “ 会返回与 s3://bucket/data/file 同样的后果。
默认状况下,Alluxio 将从底层存储按需加载元数据。在下面的例子中,从空(Empty)开始的 Alluxio master 在启动后不会有任何对于 s3://bucket/data/file 的信息。只有当用户在 Alluxio 中列出 ”/” 目录或试图拜访 ”/file “ 时,这个文件才会被辨认。该“惰性”操作能够缩小不必要的工作并显著进步性能,因为底层存储中的元数据操作可能很慢。
留神,更新元数据能够是双向的。如果对文件系统的所有批改都通过 Alluxio 进行,那么 Alluxio 只须要扫描一次底层存储来检索初始状态,而后作为文件系统 RPC 调用的一部分,在 Alluxio 和底层存储中同步利用该批改,这将为用户提供统一的底层存储视图。但在事实中,对底层存储的批改通常在 Alluxio 外进行。因而,Alluxio master 必须监控底层存储中文件和目录的减少、删除和更新,并在 Alluxio 文件系统中利用这些批改。同步两个命名空间的这一过程称为元数据同步。
当利用程序修改了 Alluxio 文件的元数据,并且该文件被长久化时,该批改总是会同步传输到底层存储,因而不须要触发元数据同步。当应用程序在 Alluxio 无感知的状况下更新底层存储文件时,有两种办法能够治理元数据的同步工夫。
基于工夫的主动同步
咱们能够将同步距离设置到 Alluxio 配置项“alluxio.user.file.metadata.sync.interval”上。
当该值为 -1(以后默认值)时,Alluxio 在初始加载后将永远不会与底层存储从新同步。
当该值设置为 0 时,每次拜访元数据,Alluxio 都将与底层存储从新同步。
当该值为正时(默认单位为毫秒),Alluxio 将(尽力)不在该工夫距离内从新同步门路。
留神,应用这种办法时,如果 Alluxio 中的某个门路从未被拜访过,将不会触发同步。一旦同步工夫距离过后该门路被拜访,Alluxio 将再次与底层存储同步。例如,在 Presto 作业中,查问打算阶段会列出作业所需的所有文件,如果这些门路最近没有被拜访,则会触发同步。然而,该作业在后续阶段将不会同步,除非作业持续时间超过同步间隔时间。
因而,这种状况下,实践上说 Alluxio 可能会比同步工夫距离更频繁地从新同步。
咱们能够应用新的全局默认值(在 alluxio-site.properties 中设置)。或者在目录根底上配置该项,该配置会递归地作用在所有子文件和目录上。
应用 LoadMetadata 标记手动同步
如果因为同步工夫距离而没有进行元数据同步,则大多数 Alluxio 操作会持续应用 Alluxio 文件系统中以后的元数据,有一些例外值得一提:
对于大多数用户来说,Alluxio CLI “loadMetadata “ 是手动触发同步的最简略办法。例如,能够运行 “bin/alluxio fs loadMetadata /path/to/sync “ 来强制更新 Alluxio 门路 ”/path/to/sync “ 的元数据。
对于基于 Alluxio 文件系统 SDK(Java)构建的应用程序,有两个 API 办法 getStatus 和 listStatus 能够检索门路或目录的元数据。在调用这些办法时,每次调用的选项中都会多出一个 LoadMetadataPType 字段,这可能会在被查问的 Alluxio 门路上触发 master 的“loadMetadata”过程。这一过程能够说是同步的简化版,只从底层存储加载文件元数据。但如果文件曾经在 Alluxio 中了,就不会批改文件的元数据。如果 LoadMetadataPType 被设置为 NEVER,则不会加载任何内容,如果文件不存在,则会抛出 FileNotFound 异样。当 LoadMetadataPType 为 ONCE 时,只会为每个目录加载一次元数据。这只会影响两个文件系统的调用,并且仅在未产生同步时此选项才失效。
当 Alluxio master 收到 RPC 申请检索该门路的元数据时,Alluxio master 可能会在 Alluxio 门路上触发元数据同步。此时不会有专用的服务来遍历整个文件系统的节点树(inode tree)并放弃同步,而是由 master 上每个独自的 Alluxio 文件系统操作来摊派这一工作。在 RPC 申请中同步的高级过程为:
步骤 1 :确定给出的 Alluxio 门路是否与相应的底层存储门路统一。如果不统一,意味着底层存储门路不存在,或者有与 Alluxio 不同的元数据。这一部分都是在解决该 RPC 申请的线程实现的。
步骤 2 :将步骤 1 填充到一个同步队列中,而后遍历同步队列,用一个线程池来解决这个队列里的每一个门路。遍历的程序是 BFS(广度优先搜寻)程序,因为在处理过程中咱们会在队列末端不停增加新的门路。这种实现的并发度和 executor(线程池)咱们将在并行度局部具体探讨。咱们有两个线程池解决不同的工作,一组线程叫做同步线程 (“sync threads”),另一组叫做预取线程(“prefetch threads”)。队列的解决是由同步线程(“sync threads”) 实现的,并应用预取线程向 UFS 读取底层存储信息。这样做是为了让网络 I / O 与计算同时进行。同步线程须要操作 InodeTree,一旦咱们确定在之后须要某些文件的信息,就能够启动底层存储预取。预取线程将底层存储中文件的状态信息加载到一个底层存储的状态缓存中,这一过程将在缓存局部探讨。
请留神,如果元数据的同步过程在同步 InodeTree 某一部分的时候会阻塞其余对这一部分 Inode 的操作,这里的开销可能会很大。这是因为同步过程可能会对其正在更新的文件系统的元数据局部加写锁。当同步节点树中的特定门路时,RPC 解决线程将首先获取整个文件门路上的读锁。因为同步线程也须要可能创立门路,因而也必须获取根门路的写锁。同步线程在解决根门路下的各个门路时,都会获取其余的锁。同步线程获取文件门路的写锁,并在门路处理完毕后立刻开释。
调度并行度
咱们能够通过管制三个配置参数来调整元数据同步的并行度。
alluxio.master.metadata.sync.concurrency.level 示意在单个元数据同步申请中(例如,在目录上)最多能够同时同步的文件数量。
alluxio.master.metadata.sync.executor.pool.size 示意所有同步操作的并发线程数。
alluxio.master.metadata.sync.ufs.prefetch.pool.size 示意在所有同步操作中能够执行底层存储预取操作的并发线程数。
缓存后果
为了进一步优化元数据同步的性能,Alluxio 有三类不同的缓存,在元数据同步过程中有着不同的指标和用处。上面对这些缓存进行简略总结。
AbsentCache是负缓存(negative cache),用于防止查看已知不存在门路的底层存储。它应用前缀匹配来确定门路是否在底层存储中。例如,如果门路 /a/ b 在缓存中,咱们就晓得 /a/b/ c 在底层存储中肯定不存在。此外,AbsentCache 条目附有工夫戳,这样咱们就能晓得它在底层存储中最初一次被查看的工夫。如果同步距离为一段时间,则工夫戳十分有用,能够依据它来确定是否须要从新查看底层存储中的文件或目录是否存在。
UfsStatusCache是用于在同步过程中预取底层存储状态的缓存。咱们通常能够在解决当前目录时预取一些文件的状态(应用预取线程),而不是在须要时获取门路信息。
UfsSyncPathCache是蕴含最近与底层存储同步门路的 positive cache(正缓存)。当收到元数据操作时,咱们将查看该缓存,确定是否须要同步某一门路。
元数据同步是 Alluxio 最重要的性能之一,有多种办法能够触发同步,但应用时须要衡量对性能的影响。Alluxio master 外部有一系列对元数据同步的优化。