刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步     DATE: 2024-04-28 18:22:39

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

导读:今天分享的刘嘉题目是Alluxio元数据和数据的同步,从设计实现和优化的设计实现角度进行讨论。主要包括以下几个方面的和优化角内容 :


01

Alluxio简介

Alluxio是云原生的数据编排平台 ,通过解耦计算和存储层,度浅在中间产生了一个数据编排层 ,元数负责对上层计算应用隐藏底层的据同时间细节。Alluxio提供了统一的刘嘉存储命名空间,在中间层提供了缓存和其他数据管理功能。设计实现在下图可以看到有Spark、和优化角Hive、度浅Map reduce这一类传统的元数Hadoop大数据计算应用、Presto 这种OLAP类型的据同数据分析 ,还有像Tensorflow 、刘嘉Pytorch这样的设计实现AI应用。存储层比较丰富,和优化角包括各种各样的存储 。

刘嘉承:从设计
、实现和优化角度浅谈Alluxio元数据同步

图1 Alluxio简介

下面是Alluxio用户列表 ,这些公司都公开展示了Alluxio的使用场景。通过粗略分类 ,看到非常多的行业,包括互联网、金融  、电子商务、娱乐、电信等 。感兴趣的同学可以关注公众号 ,上面有相关文章的汇总 。

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图2 Alluxio的用户展示

--

02

Alluxio数据挂载

这部分将首先回顾Alluxio如何通过数据挂载实现统一编排层;之后讨论Alluxio如何和底层存储保持一致;介绍元数据和数据同步功能;Alluxio的时间原理和优化;最后对不同场景的推荐配置给出建议 。

1. Alluxio统一的数据命名空间

首先介绍数据挂载这个功能。Alluxio通过把底层存储挂载到Alluxio层上,实现了统一的数据命名空间。

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图3 Alluxio统一命名空间

上图的例子中Alluxio挂载了HDFS和对象存储 。Alluxio的文件系统树就是由左右两棵树合成 ,形成了一个虚拟文件系统的文件系统树 。它可以支持非常多的底层存储系统,统一把它们称作Under File System。称为Under是因为它们都处于Alluxio的抽象层下 。Alluxio支持各种各样不同的底层存储系统,比如不同版本的HDFS ,支持NFS, Ceph, Amazon S3, Google Cloud之类不同的对象存储 。除此之外还支持非常多其他类型的对象存储,比如微软Azure 、阿里、华为、腾讯 ,也包括国内其他供应商,如七牛对象存储。左下图中的例子是在自己的电脑上运行Alluxio  ,可以挂载不同的存储 ,比如挂载HDFS,另外还可以挂载不同版本的HDFS ,挂载对象存储,挂载网盘。

2. Alluxio挂载点

Alluxio的统一命名空间 ,实际就是把挂载合成了一个Alluxio的虚拟层。Alluxio的挂载点可以粗略分成两种 :

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图4 Alluxio挂载点

根挂载点直接挂在根节点上 ,组成了Alluxio的根节点。如果没有根节点 ,无法产生 ,继续形成下面的结构。所以要求在配置文件里面定义根挂载点,系统启动的时候就进行挂载,不挂载就没有办法启动。

嵌套挂载点比较灵活 ,可以通过指令进行挂载。通过这个命令行,发出通知 ,做挂载的操作。同样地,可以挂载,也可以卸载,就是把Mount换成Unmount 。嵌套挂载点是嵌套在目录的下面  ,可以挂在某个部分下面,不一定挂载在根节点下面 。这里有个要求 ,即两个嵌套点的树不能互相覆盖 ,这样带来的好处是比较灵活。如果根挂载点将来需要更换 ,为了避免需要改配置和重启服务 ,可以使用一个dummy的根挂载点,比如就挂载在本地路径下面 ,不使用它 ,且不在它下面创建任何文件 ,它存在的唯一目的就是可以启动Alluxio服务。然后在此基础上,把所有要管理的存储 ,都以嵌套挂载点的方式挂载上去。之后如果要改变,就直接卸载更换为其它挂载点 ,这样就很灵活。所有挂载和挂载操作  ,都会记录在日志里,重启系统  ,并重启服务之后 ,无需再手动操作。

3. Alluxio策略化数据管理

刘嘉承:从设计
、实现和优化角度浅谈Alluxio元数据同步

图5 Alluxio策略化数据管理


挂载操作有一个进阶版操作 ,目前只包含在商业版本里面。所做的事情就是让用户可以把两个存储挂载到同一个路径下 ,可以互相覆盖。同时通过配置读写策略,定义读写文件到哪个存储里,并给出操作的先后顺序 。同时Alluxio有一个迁移策略,让文件可以自动在Alluxio的管理下 ,在多个存储之间进行迁移。例如 ,把HDFS和对象存储同时挂载到同一路径下 ,上层用户只能看到这样一棵树,但是实际上背后有两个不同的存储 。通过配置,让Alluxio把HDFS的数据  ,根据一些规则 ,定期迁移进S3,例如规定将超过七天的数据,认定是不常用到的冷数据之后 ,把它从HDFS的集群拿出来 ,迁移到S3 ,节省HDFS的存储空间。

--

03

Alluxio底层存储一致性

在把底层存储挂载到Alluxio的统一命名空间上之后,如何保持Alluxio和底层存储的一致性 ?我们在这一部分进行分析 。

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图6 Alluxio与一致性


Alluxio和底层存储的一致性,要从Alluxio命名空间中文件的来源说起。文件的操作分为两类 :

一致性可以分为两个部分 :

下面先看写数据的一致性。

1. Alluxio写文件流程

首先Alluxio写文件的流程可以把它抽象成两步。第一步是客户端到Alluxio ,第二步是Alluxio到UFS 。

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图7 Alluxio写文件流程


其中的每一步都可以抽象成下面的三个步骤:

同样Alluxio到存储系统也可以同样地抽象提取 。

客户端和Alluxio之间 ,主要流程分三步 :

同样Alluxio到存储系统也抽象成三步。不同存储系统的抽象和具备的一致性,都不同,此处进行抽象只是为了便于理解 。比如要求强一致性保证 ,但是很多对象存储,给的一致性保证会弱很多 ,比如写进去之后不能马上读到这个数据。在这里,不考虑这种本身的不一致性的问题 。假设Alluxio向存储提交了之后  ,就能保证存储端的文件就是需要的样子  。

Alluxio为了满足不同的需求 ,设计了几种不同的写策略,下面逐一分析写策略的流程以及带来的数据一致性保证。

2. Must-Catch写模式

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图8 Alluxio:MUST_CACHE写模式


首先是常用的MUST_CACHE模式。在这种模式下  ,只会写Alluxio缓存不写UFS。这个模式分为三步 :

首先客户端会向Alluxio 发出创建文件请求 ,创建的文件只是一个空文件,作为一个占位;

之后Alluxio Worker实现具体数据的写操作 ,具体数据会被分割成多个数据块 ,作为Block存在于Alluxio Storage里面。

在缓存写之后,客户端对Master做提交文件的请求,告诉Master写了这些数据块,写到Worker,然后更新对应的元数据,也知道了这些数据块和Worker所对应的位置。

在这样的流程之后 ,Alluxio不会向UFS创建这个文件,也不会写这个文件 ,所以Alluxio和UFS之间的元数据和数据都不一致 。

3. Through写模式

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图9 Alluxio :Through写模式


THROUGH的写模式有所不同,这里同样的 createfile() 发出一个请求 ,然后找Worker写数据 。Worker会做三件事 :

在第二步结束后 ,客户端会向Alluxio 提交这个文件 。因为Alluxio 的提交是发生在文件写完了之后,所以 ,Alluxio和UFS此时的元数据是一致的 。因为没有数据缓存 ,所以也不存在数据一致性的问题。

Alluxio的缓存是在需要读之后才会产生,而这种THROUGH模式是比较适合用来写已知不再会被Alluxio读取的数据。所以在这种情况下,元数据是一致的,也不存在数据不一致的问题 。

4. CACHE_THROUGH写模式

下面的CACHE_THROUGH模式就是前面两种模式的结合 。

刘嘉承:从设计	、实现和优化角度浅谈Alluxio元数据同步

图10 Alluxio :CATCH_THROUGH写模式


唯一的不同点是在第二步 ,写缓存的同时又写了UFS 。在这两个都成功之后 ,第二步才会成功 ,之后客户端才会做提交操作 。同样的道理,因为Alluxio在UFS更新之后才更新,所以两者的元数据和数据都是一致的。

5. ASYNC_THROUGH写模式

最后是ASYNC_THROUGH异步写模式 ,和前面的模式唯一的区别是第二步中的UFS写变成了异步,放在了第四步  。

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图11 Alluxio :ASYNC_THROUGH写模式


在Alluxio写缓存之后,首先创建了文件之后 ,在第二步写了Alluxio缓存;在第二步缓存写完之后 ,Worker就向客户端返回成功;然后由客户端向Master提交文件。注意在这个时候 ,Worker还没有去UFS创建这个文件 ,也没有向UFS写文件 。在Alluxio向客户端返回请求成功之后,在之后的某个时间 ,由Job Service把这个文件创建到时里面 ,并且持久化 。

需要注意 :在异步的模式下,持久化由于某些原因失败了 ,比如Alluxio成功之后,突然有人直接向里面创建了一个同名的文件,在第四步的时候,由于缓存和之间产生了不一致 ,导致这个文件无法创建 、无法写入 。这个时候 ,Alluxio会有不一致的问题 ,此时需要人工介入来解决这个冲突。

6. 读文件流程

前文介绍以上四种不同的写模式以及一致性保证,现在来看Alluxio的读文件流程。读文件也可以粗略分成两种 :冷读和热读。

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图12 Alluxio :读文件流程


简单来说 ,冷读情况下Alluxio不知道这个文件,需要从加载元数据和数据。热读的时候,缓存命中,不需要加载元数据和数据 。

① 冷读文件

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图13 Alluxio:冷读文件


在冷读流程里 ,客户端向Alluxio请求元数据 ,此时Master还没有这个元数据,所以会向UFS发出一个请求 ,并从UFS加载这个元数据 ,这也称之为元数据同步。

在客户端具体读数据的时候,客户端找到Worker,Worker此时还没有缓存,于是Worker会向UFS做缓存的加载  ,这就是常说的缓存冷读。在做完这两个步骤之后,缓存是和元数据一致的 。

② 热读文件

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图14 Alluxio :热读文件


在热读的情况下,元数据可以在缓存里面找到,数据可以在Worker里面找到;此时不会有对UFS的读请求。

在缓存命中的时候,如何保证缓存与和是一致的 ?这里包括元数据的一致和数据的一致  。这个简单的来说 ,就是通过Alluxio的元数据和数据的同步机制 ,也就是下一部分的内容  。

--

04

Alluxio和UFS元数据和数据同步

1. 检查Alluxio元数据/数据一致性

首先考虑这个问题 :在什么时候需要检查Alluxio的元数据和数据的一致性?

首先在写数据的时候需要检查 。如果这个文件在已经存在了,作为缓存,除了放弃这个操作之外 ,也没有其他的选项。因为不能在用户不知情的情况下  ,覆盖掉用户在里面的数据  。

在读数据的时候,同样需要考虑如果文件在里面已经更新了 ,那缓存也需要对应进行更新,需要UFS考虑里面的文件是否发生了变化。

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图15 检查Alluxio :元数据/数据一致性


2. 保证Alluxio元数据/数据一致性

元数据和数据的一致性分成两步来逐个讨论 。首先讨论如何保证Alluxio元数据和一致。Alluxio通过两种方式来保证:

刘嘉承
:从设计、实现和优化角度浅谈Alluxio元数据同步

图16 保证Alluxio :元数据/数据一致性


① 通过基于时间的假设

第一种是通过基于时间的假设,在里面的文件,在一段时间内它是不变的。判断方法是在每一次文件源信息、元数据请求的时候 ,检查Alluxio的元数据是否足够新。

这个判断分成了两个不同的部分:

这种元数据的同步机制是惰性的 ,只有在请求的时候才会进行检查。这样设计的理念是尽量避免访问慢的操作、昂贵的操作 。这样的事情越少越好  、越懒越好。如果Alluxio所知的文件信息足够新 ,就假设Alluxio和UFS是一致的 。如果不够新,就放弃这个假设再做一次同步;同时更新Alluxio里面的元数据。

② 基于通知

另外一个思路就是抛弃基于时间的假设 ,基于通知,依赖文件更改的告知 。这个不是假设,是一个确定的信息。如果没有通知文件有变化,就确定Alluxio和现在的文件是一致的。

其次是如何保证Alluxio和UFS的数据保持一致 。思路也非常简单:保持数据的一致,只需要确定元数据及是否一致 。这里做出的假设是 :如果UFS的数据,文件内容有所改变 ,那这个改变一定会反映在文件的元数据上 。要么是文件的长度改变,要么是这个文件的Hash,也就是哈希值会发生改变。通过观察这个Alluxio和的元数据,可以发现这些变化点。

如果基于这个假设 ,Alluxio的元数据和UFS保持一致时缓存和UFS也会一致。如果观察元数据发现内容有变化 ,那么就更新元数据并抛弃已有缓存。在下一次读的时候 ,重新加载缓存 。如果发现文件的内容没有变化  ,只做必要的元数据更新 ,不抛弃数据缓存 。

3. 数据同步机制

Alluxio提供两种同步机制,这里先介绍时间戳机制,再介绍基于消息的同步机制  。

① 基于元数据时间戳的同步机制

下面先看一下第一种机制 ,基于元数据时间戳的同步机制 。

刘嘉承	:从设计
	、实现和优化角度浅谈Alluxio元数据同步

图17 基于元数据时间戳同步


时间戳主要是通过配置项alluxio.user.file.metadata.sync.interval ,通常称之为sync.interval或者interval。比较同步数据上次同步的时间戳和配置项 。配置项中有几种不同的配置方式:

刘嘉承:从设计
、实现和优化角度浅谈Alluxio元数据同步

图18 元数据同步的开销


② 同步时间间隔配置

刘嘉承
:从设计、实现和优化角度浅谈Alluxio元数据同步

图19 同步时间间隔配置


这个时间间隔具体配置有三个 ,优先级是由低到高  ,后面的配置可以覆盖前面的配置。

Alluxio还提供一些语法糖指令 ,比如:loadMetadata指令就是专门为了触发元数据同步 。如果加上-F选项 ,实际上的意思就是把sync.interval设成0 ,相当于强制进行一次元数据的刷新。ls和metadata这两个指令的区别:ls把文件展示在面前,ls的RPC有网络开销 , 会把信息发给你,客户端要保存下来,并且展示出来  。这个不是每一次都需要 ,假如只是想要触发一次元数据的同步,只需loadMetadata就可以,返回值只有成功或者失败,可以节约很多网络带宽和的内存开销  。

③ 基于消息的同步机制

以上是基于时间的同步机制 ,下面看一下另外一种思路,就是基于消息同步机制。

刘嘉承:从设计�、实现和优化角度浅谈Alluxio元数据同步

图20 基于消息同步


首先需要Alluxio 2.0版本以上 ,以及Hadoop 2.6.1版本以上,因为HDFS底层的inotify机制是在2.6版本加进去的 。实际上发生的就是从HDFS的namenode直接读取HDFS有哪些文件发生了变化 。实现原理就是维护了一个Alluxio和namenode之间通过HDFS的inotify机制保持了一个信息流 。Alluxio定期心跳从这个信息流里面去读,有哪些文件发生了变化,然后根据这个变化的具体的类型 ,Alluxio决定要不要再去namenode触发一次元数据的同步 。

这样的元数据同步是有的放矢 ,不再是基于时间猜测。每一次同步都是有理有据,知道文件已经改变,称为Active Sync ,也是因为在这里化被动为主动,不再被动去猜 ,而是主动知道了有哪些变化 ,然后主动去触发同步。但是这个inotify只能告诉告诉我们哪些文件发生了变化以及变化是什么类型,包含的信息很少 ,具体要做同步还需要一个元数据同步的机制,所以这一步是绕不开的 。具体的使用也非常简单,可以通过指令来开启它,也可以关闭,或者查看现在有哪些HDFS路径或挂载点开启了这个功能 ,这些指令也受Journal日志保护 ,当开启了Active Sync功能之后 ,就会被记录在Journal日志里面  ,在重启集群之后 ,无需重敲一遍指令。

4. Active Sync性能取舍

Active Sync也不是万能药,它做了一些功能的取舍 。每种设计都有它的取舍,因此也有适合和不适合的场景  。

刘嘉承
:从设计	、实现和优化角度浅谈Alluxio元数据同步

图21 Active Sync性能取舍


Active Sync在确定了文件更改之后,再去做同步操作,它省掉了那些没有变化 、无用的同步操作  。但是每一个文件的更改 ,都会触发同步操作。具体文件的更改并不一定是客户端的请求,虽然是主动加载它 ,但实际上并不一定用到 ,有可能是多余的操作 。

Active Sync和基于时间戳的同步机制 ,各有利弊 。具体选择时需要进行考量 ,在后面的章节会总结分析哪种场景适合的配置 。同时要注意Active Sync只支持HDFS,原因是只有HDFS提供API,其他存储没有机制可以知道有哪些文件发生了变化 ,所以没有办法来实现 。

--

05

元数据同步实现与优化

在了解了机制后 ,现在了解一下元数据同步的实现原理 ,然后再看元数据同步的优化。

1. 元数据同步原理

目前元数据的同步粗略分为左下角的这几个步骤。左上角我们列出了元数据同步的参与者 。包括了RPC线程 ,就是Master端 ,来自于RPC的线程池。第2个参与者称作同步线程池(sync thread pool)  。第3个参与者称作预取线程池(prefetch thread pool)。这里有一个InodeTree ,就是Alluxio里面维护的所有文件的元数据,形成了一个树状的结构 。图中的UFS代表着实际的底层存储 。所有对UFS的连线都是一个对外部系统的RPC ,是比较昂贵的操作。

刘嘉承:从设计
、实现和优化角度浅谈Alluxio元数据同步

图22 元数据同步原理


同步步骤分三步 :

① RPC线程向UFS读取文件的元信息 。在处理请求ls -R 时 ,对根节点全量的文件树进行一次ls操作 。此时基于时间戳 ,需要触发元数据同步 , RPC线程就会读取文件根节点的信息,检查挂载HDFS://alluxio根节点的信息 。如果发现信息有更新 ,就去InodeTree里面找根节点 ,则RPC线程对应地更新/创建/删除Alluxio的Inode元信息 ,并且这个节点进行更新。

② 如果在处理递归的时候,发现下面还有其他目录,整棵树都需要进行一次搜索,此时把递归文件/文件夹提交到同步线程池(sync thread pool) 。用广度优先搜索的方式进行遍历 ,也就是常说的BFS。当提交这个任务后 。会去同步线程池 ,在BFS的过程中 ,按照一定的顺序遍历这棵树,data -> user -> others -> report …

在这个过程中 ,主要是做两件事情 :

就把任务提前交给预取线程池 ,告诉它去读HDFS里面相关的这些路径,这也就是称为预取的原因。在真正处理这个路径之前 ,就提前告诉它 ,因为操作会需要很长的时间,保证性能最好的方式就是提前做这个事情;等任务处理到的时候,已经准备好了。这样最高地利用了多线程的并发。

在处理每个节点的时候 ,确认预取线程池准备好的结果;如果有更新 ,就更新自己的InodeTree。

③ 预取线程池负责从读取文件或者文件夹信息 ,把结果交给这个同步线程池 ,来加速这个具体的同步过程。

2. 性能优化-缓存

在这个时间原理的基础上 ,进行了一系列的优化 。

刘嘉承:从设计
、实现和优化角度浅谈Alluxio元数据同步

图23 性能优化-缓存


首先就是做了缓存的优化。主要的设计理念就是因为UFS操作非常贵 、非常慢,希望尽可能多的地缓存结果,节省的操作。

缓存优化涉及下面这几种缓存 :

3. 算法优化-锁优化

在缓存优化之外 ,基于Alluxio的版本迭代 ,也做了各种各样的元数据同步优化 ,其中比较大的就是算法的优化。

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图24 算法优化-锁优化


在Alluxio2.3版本之前 ,所有的RPC线程是自己进行元数据的同步。如果递归基于DFS自己遍历这棵树,从头到尾都持有路径的写锁 。如果是递归 ,实际上是写锁锁住了整个子树。在锁住子树的过程中 ,其他线程就无法读取子树里的内容,并发度低 ,由于是单线程 ,做了非常多需要Block时间长的操作。

在Alluxio2.3里面非常大的优化 ,就是把它改成了多线程并发同步的算法,更多利用线程池操作 ,DFS改成了BFS。根据需要,读锁升级,而非从头至尾持有写锁。读写锁的好处就是让不同的线程之间有了更高的并发度 。这样在同步某一棵子树的过程中,其他线程还有机会可以读到这里面的内容 ,所以整体的并发会更高 。

4. 性能优化-调整并行度

第三个优化来自于用户对线程池的配置。

刘嘉承�:从设计�、实现和优化角度浅谈Alluxio元数据同步

图25 性能优化-并行度


在Alluxio 2.3里面加入了线程池之后,可以通过配置参数调整元数据同步的并行度 。之前单线程没有配置可言。调整并行度一般是通过这三个参数 。

两个线城池的大小 ,建议配置成CPU数的倍数 ,具体比例以及系统应该配多大,取决于这两个线程所做工作的时间,以及中间的配合方式。所以没有给出统一建议,建议根据具体程序运行的时候,CPU比如可以做一些火焰图、分析延迟以及inodetree更新的延迟 ,做一个更加合理的配比 。默认的配比都是CPU的倍数  ,如果没有在无数据同步看到非常明显的瓶颈 ,不需要进行特别细粒度的调节。

--

06

对不同场景的推荐配置

最后针对不同的场景具体分析问题,推荐比较好的配置。

1. 场景1

刘嘉承
:从设计、实现和优化角度浅谈Alluxio元数据同步

图26 场景一配置


最简单的场景就是:所有的写和读全都经过了Alluxio 。无疑Alluxio所有的元数据都是最新 ,此时无需做元数据同步 。可以关闭元数据同步 ,提升性能 。

2. 场景2

第二个场景稍微复杂一些。大部分的操作经过Alluxio ,但是不排除还有一些场景 ,会绕过Alluxio直接改动原来里面的文件。

刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步

图27 场景二配置


在这种场景下,为了保证Alluxio和UFS元数据和数据的一致,还是要保留一部分元数据同步的操作。在这里分HDFS和非HDFS进行考虑 ,主要是因为这些HDFS比别人多一个选项Active Sync。

HDFS的情况下,需要考虑这几个点 :如果HDFS更新非常频繁,就是绕过Alluxio的更新非常频繁,或者HDFS的namenode的压力比较大,不建议使用Active Sync,而是使用基于时间的被动同步。使用被动同步的原因是Active Sync是基于Alluxio心跳 ,去namenode拉取具体有哪些文件发生了改动,每一次拉取都是一次RPC,给namenode施加的压力 。同时如果文件发生了改动,Alluxio就又会向namenode发起RPC去同步这些文件。因此希望尽量减少这些操作来降低namenode的压力  。

如果基于时间的被动同步,能给予减少元数据同步操作的机会 ,则使用基于时间的被动同步;反之要使用Active Sync ,因为更加主动,时效性更高。如果不会带来性能负担 ,完全可以去尝试一下 。

如果不是HDFS ,只能用基于时间的被动同步 。

建议尽量节约元数据同步的操作 ,具体做法考虑每个数据  、每个路径更新的频率大概是如何。基于这样的考量,尽量给sync interval设一个比较大的值  ,尽量减少元数据的触发。

3. 场景3

第三个场景稍微有些不同 。大部分或全部更新都不经过Alluxio ,而更新又非常频繁。

刘嘉承:从设计

、实现和优化角度浅谈Alluxio元数据同步

图28 场景三配置


在这种情况下 ,使用HDFS而且时效性又非常重要,使用Active Sync是唯一方案 。因为如果把sync interval调到一个特别低的值  ,甚至可能触发比Active Sync更多的同步。如果把它设成零之后,每一次都不会触发同步,会进一步加大同步的操作开销。

如果时效性并不十分重要,建议使用这个基于时间的被动同步 。通过节省开销 ,减少元数据同步的操作,就能提升系统的性能。同样如果不是HDFS,则使用基于时间的被动同步。

以上是三个场景的分析 ,也是今天分享的全部内容  。

--

07

答疑

Q :在ASYNC_THROUGH mode当中,因UFS原因导致ASYNC上传始终失败  ,这种情况怎么优雅地处理 ,以避免不一致?

A:这个问题非常好,问到了痛点。目前没有一个特别优雅的解决方案  。

在异步方式下没有call back ,或者hook的自动介入,只能人为介入。Alluxio2.4商业版中加入了一个job service dashboard查看异步任务的状态 。如果异步持久化失败了,这个地方可以看到所有失败的异步任务。目前只能通过这个方式观察究竟有哪些东西失败了 ,然后再人为进行干预 。

我们已经注意到job service的问题,打算重新设计整个job service,从几个方向 ,可扩展Scalability, Fault-tolerance ,包括monitoring, failure mode, 恢复等 。未来版本里面会做出更好的设计,有很多场景 ,并加入人工干预模式 。通过开放一些接口  ,可以自动化地读到这些东西,或是可能会增加界面  ,让用户定义一些方式 。

Alluxio到了一个新的阶段 ,要好好思考  ,用更加scalable的方案去解决这些问题 。这些异步的操作已经提上了议事日程 。

Q :和HDFS可以不同路径设置不同的同步时间吗?

A :可以用配置参数的方法去实现 。

今天的分享就到这里,谢谢大家  。

阅读更多技术干货文章 、下载讲师PPT ,请关注微信公众号“DataFunTalk”。


分享嘉宾 :刘嘉承 Alluxio 核心组研发工程师

编辑整理:曾新宇 对外经贸大学

出品平台:DataFunTalk


分享嘉宾 :

刘嘉承
:从设计、实现和优化角度浅谈Alluxio元数据同步

关于我们:

DataFun:专注于大数据、人工智能技术应用的分享与交流。发起于2017年 ,在北京  、上海、深圳  、杭州等城市举办超过100+线下和100+线上沙龙 、论坛及峰会,已邀请超过2000位专家和学者参与分享 。其公众号 DataFunTalk 累计生产原创文章700+ ,百万+阅读,14万+精准粉丝。


欢迎转载分享评论,转载请私信 。