刘嘉承:从设计、实现和优化角度浅谈Alluxio元数据同步 DATE: 2024-05-06 18:13:37
导读:今天分享的刘嘉题目是Alluxio元数据和数据的同步 ,从设计实现和优化的设计实现角度进行讨论。主要包括以下几个方面的和优化角内容 :
- Alluxio简介
- Alluxio的数据挂载
- Alluxio和底层存储的一致性
- Alluxio和UFS的元数据/数据同步
- 元数据同步的实现原理和优化
- 对不同场景的推荐配置
01
Alluxio简介
Alluxio是云原生的数据编排平台 ,通过解耦计算和存储层,度浅在中间产生了一个数据编排层 ,元数负责对上层计算应用隐藏底层的据同时间细节。Alluxio提供了统一的刘嘉存储命名空间,在中间层提供了缓存和其他数据管理功能。设计实现在下图可以看到有Spark 、和优化角Hive 、度浅Map reduce这一类传统的元数Hadoop大数据计算应用、Presto 这种OLAP类型的据同数据分析 ,还有像Tensorflow、刘嘉Pytorch这样的设计实现AI应用 。存储层比较丰富,和优化角包括各种各样的存储 。
图1 Alluxio简介
下面是Alluxio用户列表 ,这些公司都公开展示了Alluxio的使用场景。通过粗略分类,看到非常多的行业 ,包括互联网 、金融、电子商务 、娱乐 、电信等 。感兴趣的同学可以关注公众号,上面有相关文章的汇总 。
图2 Alluxio的用户展示
--
02
Alluxio数据挂载
这部分将首先回顾Alluxio如何通过数据挂载实现统一编排层;之后讨论Alluxio如何和底层存储保持一致;介绍元数据和数据同步功能;Alluxio的时间原理和优化;最后对不同场景的推荐配置给出建议。
1. 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的挂载点可以粗略分成两种 :
- 根挂载点
- 嵌套挂载点
图4 Alluxio挂载点
根挂载点直接挂在根节点上 ,组成了Alluxio的根节点。如果没有根节点 ,无法产生,继续形成下面的结构 。所以要求在配置文件里面定义根挂载点,系统启动的时候就进行挂载,不挂载就没有办法启动。
嵌套挂载点比较灵活,可以通过指令进行挂载 。通过这个命令行 ,发出通知 ,做挂载的操作 。同样地 ,可以挂载 ,也可以卸载,就是把Mount换成Unmount 。嵌套挂载点是嵌套在目录的下面 ,可以挂在某个部分下面,不一定挂载在根节点下面。这里有个要求 ,即两个嵌套点的树不能互相覆盖 ,这样带来的好处是比较灵活。如果根挂载点将来需要更换,为了避免需要改配置和重启服务,可以使用一个dummy的根挂载点,比如就挂载在本地路径下面 ,不使用它,且不在它下面创建任何文件,它存在的唯一目的就是可以启动Alluxio服务。然后在此基础上,把所有要管理的存储,都以嵌套挂载点的方式挂载上去 。之后如果要改变,就直接卸载更换为其它挂载点 ,这样就很灵活。所有挂载和挂载操作,都会记录在日志里 ,重启系统 ,并重启服务之后,无需再手动操作。
3. Alluxio策略化数据管理
图5 Alluxio策略化数据管理
挂载操作有一个进阶版操作 ,目前只包含在商业版本里面 。所做的事情就是让用户可以把两个存储挂载到同一个路径下,可以互相覆盖 。同时通过配置读写策略 ,定义读写文件到哪个存储里,并给出操作的先后顺序。同时Alluxio有一个迁移策略 ,让文件可以自动在Alluxio的管理下,在多个存储之间进行迁移。例如,把HDFS和对象存储同时挂载到同一路径下,上层用户只能看到这样一棵树 ,但是实际上背后有两个不同的存储。通过配置,让Alluxio把HDFS的数据 ,根据一些规则 ,定期迁移进S3 ,例如规定将超过七天的数据 ,认定是不常用到的冷数据之后,把它从HDFS的集群拿出来,迁移到S3 ,节省HDFS的存储空间 。
--
03
Alluxio底层存储一致性
在把底层存储挂载到Alluxio的统一命名空间上之后,如何保持Alluxio和底层存储的一致性?我们在这一部分进行分析 。
图6 Alluxio与一致性
Alluxio和底层存储的一致性,要从Alluxio命名空间中文件的来源说起 。文件的操作分为两类:
- 一类是写,上层应用通过Alluxio创建一个文件,通过Alluxio写入UFS;
- 一类是读,上层应用通过Alluxio读一个文件,当发现自己没有这个文件的时候,Alluxio从UFS进行加载。
一致性可以分为两个部分 :
- Alluxio UFS元数据的一致性
- Alluxio UFS数据的一致性
下面先看写数据的一致性。
1. Alluxio写文件流程
首先Alluxio写文件的流程可以把它抽象成两步 。第一步是客户端到Alluxio ,第二步是Alluxio到UFS。
图7 Alluxio写文件流程
其中的每一步都可以抽象成下面的三个步骤:
- 创建文件
- 写数据
- 提交文件
同样Alluxio到存储系统也可以同样地抽象提取 。
客户端和Alluxio之间,主要流程分三步 :
- 客户端向发请求创建一个文件;
- 找到Alluxio Worker写具体对应的数据;
- 在写完数据之后,提交这个文件 。
同样Alluxio到存储系统也抽象成三步 。不同存储系统的抽象和具备的一致性 ,都不同,此处进行抽象只是为了便于理解。比如要求强一致性保证 ,但是很多对象存储 ,给的一致性保证会弱很多,比如写进去之后不能马上读到这个数据 。在这里,不考虑这种本身的不一致性的问题。假设Alluxio向存储提交了之后 ,就能保证存储端的文件就是需要的样子。
Alluxio为了满足不同的需求 ,设计了几种不同的写策略,下面逐一分析写策略的流程以及带来的数据一致性保证。
2. Must-Catch写模式
图8 Alluxio :MUST_CACHE写模式
首先是常用的MUST_CACHE模式。在这种模式下,只会写Alluxio缓存不写UFS。这个模式分为三步 :
首先客户端会向Alluxio 发出创建文件请求 ,创建的文件只是一个空文件 ,作为一个占位;
之后Alluxio Worker实现具体数据的写操作 ,具体数据会被分割成多个数据块 ,作为Block存在于Alluxio Storage里面。
在缓存写之后,客户端对Master做提交文件的请求 ,告诉Master写了这些数据块,写到Worker,然后更新对应的元数据,也知道了这些数据块和Worker所对应的位置。
在这样的流程之后,Alluxio不会向UFS创建这个文件,也不会写这个文件 ,所以Alluxio和UFS之间的元数据和数据都不一致。
3. Through写模式
图9 Alluxio :Through写模式
THROUGH的写模式有所不同 ,这里同样的 createfile() 发出一个请求 ,然后找Worker写数据 。Worker会做三件事 :
- 创建文件
- 写文件
- 提交文件
在第二步结束后,客户端会向Alluxio 提交这个文件 。因为Alluxio 的提交是发生在文件写完了之后,所以 ,Alluxio和UFS此时的元数据是一致的。因为没有数据缓存,所以也不存在数据一致性的问题 。
Alluxio的缓存是在需要读之后才会产生 ,而这种THROUGH模式是比较适合用来写已知不再会被Alluxio读取的数据。所以在这种情况下 ,元数据是一致的,也不存在数据不一致的问题 。
4. CACHE_THROUGH写模式
下面的CACHE_THROUGH模式就是前面两种模式的结合。
图10 Alluxio :CATCH_THROUGH写模式
唯一的不同点是在第二步 ,写缓存的同时又写了UFS 。在这两个都成功之后,第二步才会成功,之后客户端才会做提交操作。同样的道理,因为Alluxio在UFS更新之后才更新,所以两者的元数据和数据都是一致的。
5. ASYNC_THROUGH写模式
最后是ASYNC_THROUGH异步写模式 ,和前面的模式唯一的区别是第二步中的UFS写变成了异步,放在了第四步。