当前位置 博文首页 > colorant的专栏:Tachyon架构分析和现存问题讨论

    colorant的专栏:Tachyon架构分析和现存问题讨论

    作者:[db:作者] 时间:2021-08-27 16:13

    作者:刘旭晖 Raymond 转载请注明出处

    Email:colorant at 163.com

    BLOG:http://blog.csdn.net/colorant/


    TachyonAmpLabLi Haoyuan所开发的一个基于内存的分布式文件系统,出发点是作为AMPLABBDAS的一个组成部分

    ?

    总体设计思想

    ?

    Tachyon的设计目标来看,是要提供一个基于内存的分布式的文件共享框架,需要具备容错的能力,还要体现内存的性能优势

    ?

    Tachyon以常见的Master/worker的方式组织集群,由Master节点负责管理维护文件系统MetaData,文件数据维护在Worker节点的内存中。

    ?

    在容错性方面,主要的技术要点包括:

    ?

    • 底层支持Plugable的文件系统如HDFS用于用户指定文件的持久化
    • 使用Journal机制持久化文件系统的Metadata
    • 使用Zookeeper构建MasterHA
    • 没有使用replica复制内存数据,而是采用和Spark RDD类似的Lineage的思想用于灾难恢复(这一点后面再讨论)

    ?

    此外为了兼容Hadoop应用,提供了HDFS兼容的API接口

    ?

    具体实现分析

    ?

    初始化流程

    ?

    Tachyon文件系统的初始化,其实就是创建和清空Master/worker所需的工作目录

    ?

    Master节点来说这些目录包括底层持久化文件系统上的Data/worker/Journal目录,实际上这里的Worker目录是由Worker节点使用的(用于存放一些零时的持久化文件,丢失Meta信息的数据块等),但是放在Master节点来创建,本质上是为了简化创建逻辑(因为放在HDFS上,只创建一次)

    ?

    worker节点来说所需的目录就是本地Ramdisk目录

    ?

    此外,在masterJournal文件夹中,会创建一个特定前缀的空文件用于标志文件系统格式化完毕

    ?

    Tachyon Master的启动过程

    ?

    Tachyon Master的启动过程,首先当然是要读取Master相关配置参数,目前都是通过-D参数传给Java的,理想的是通过配置文件来做。目前这些参数,一部分是在Env文件里设置变量,再通过-D参数设置,也有的直接写死在-D参数中的,也有启动脚本中默认未配置,在MasterConf代码里使用了默认值的

    ?

    通过读取特定的format文件判断文件系统是否格式化

    ?

    接下来就是在内存中重建文件系统信息

    ?

    Tachyon的文件系统信息依靠Journal日志保存,Journal包括两部分,一是meta信息在某个时刻的快照Image,二是增量LogTachyon Master启动时首先从快照Image文件中读取文件系统meta信息,包括各种数据节点(文件/目录/Raw/Checkpoint/依赖关系等)信息,而后再从继续EditLog(可能多个)中读取增量操作记录,EditLog的内容基本对应于Tachyon文件系统Client的一些相关操作,包括文件的添加,删除,重命名,数据块的添加等等

    ?

    需要注意的是,这里的Log记录不包括实际的文件内容数据,只是meta信息,所以如果Cache中的文件内容丢失,如果没有持久化,也没有绑定相关lineage信息,那么对应的文件的具体内容也就丢失了

    ?

    文件系统信息恢复完毕以后,在Tachyon Master正式启动服务之前,Tachyon Master会先把当前的Meta Data写出为新的快照Image

    ?

    在启用zookeepeer的情况下,standbyMaster会定期将Editlog合并并创建StandbyImage,如果没有StandbyMaster则只有在启动过程中,才通过上述步骤合并到新的Image中。这里多个Master并发操作Imageeditlog,没有Lock或者互斥的机制,不知道会不会存在竞争冲突,数据stale或丢失的问题

    ?

    ?

    文件的存储

    ?

    Tachyon存放在RamDisk上的文件以Block(默认为1G)为单位划分,Master为每个Block分配一个BlockIDWorker直接以BlockID作为实际的文件名在Ramdisk上存储对应Block的数据

    ?

    数据的读写

    ?

    Tachyon的文件读写,尽可能的通过Java NIO API将文件直接映射到内存中,做为数据流进行读写操作,目的在于避免在Java Heap中使用大量的内存,由此减小GC的开销,提升响应速度

    ?

    读写过程中,所有涉及到Meta相关信息的,都需要通过调用Tachyon Master经由Thrift暴露的ServerAPI来执行

    ?

    Tachyon的文件读操作支持本地和远程两种模式,从Client API的角度来说对用户是透明的。读文件的实现,其流程基本就是先从Master处获取对应文件Offset位置对应的BlockID

    ?

    而后连接本地Worker取得相应ID对应的文件名,如果文件存在,Client端代码会通知Worker锁定对应的Block,而后Client端代码直接映射相关文件为RandomAccessFile直接进行读操作,并不经由Worker代理读取实际的数据

    ?

    如果本地没有Worker,或者文件在本地worker上不存在,Client代码再进一步通过MasterAPI获取相关Block所对应的Worker,而后通过Worker暴露的DataServer接口读取对应Block的内容,在DataServer内部,同样延续锁定对应Block,映射文件的流程读取并将数据返回给Client

    ?

    另外,基于读数据的时候使用的TachyonFileAPI接口,如果使用的是FileStream的接口,当远程Worker也没有对应文件Block时,RemoteBlockInStream还会尝试从底层持久化文件系统层(如果存在对应的文件的话)去读取数据,而ReadByteBuffer接口则没有对应的流程(个人感觉,应该做到两种方式的行为匹配才对)。

    ?

    Tachyon目前只支持本地写操作,写操作按写入位置可以分为

    ?

    Cache:写到Tachyon内存文件系统中

    Through:写到底层持久化文件系统中

    ?

    具体的类型是以上几种情况的合法的组合,如单cachecache +through

    ?

    还有一个Async模式:异步写到底层持久化文件系统中,这个大概是为了优化那些数据需要持久化,但是又对性能Latency等有要求的场合

    ?

    ?

    读写操作现存问题和并发操作相关

    ?

    前面提到读取数据时Client端会通知WorkerLock对应的Block。需要注意的是这里的Lock实际上并没有互斥的意思,只是一个标志表示当前还有用户在使用相关文件和数据,这样,在Worker需要分配内存淘汰旧的数据的时候,当前正在使用的文件将不会被删除。

    ?

    而在写操作过程中,目前的实现看来对并发处理相关的内容基本没有考虑

    ?

    例如Read操作已经Lock的文件block,依然可以被主动Delete,不考虑lock的状态,当然这一点可能和多数Linux类的Filesystem的设计一致,(但是Windows上显然可能提示无法删除)这个还要再研究一下在大数据分布是环境下其它的设计实现是怎样的

    ?

    而写操作本身的再入也没有很处理好,不能支持并发是一个问题,单线程重写文件也会造成前面的数据块的丢失或者数据块的混合,当然,这也是因为目前还没有考虑到支持这些情况。

    ?

    Write目前不支持Append操作,这个和当前的设计也有很大的关系,block尺寸按文件计算,尺寸固定,所以要Append就需要考虑必须在同一节点上写数据,要不然就要支持远程写数据到当前

    下一篇:没有了