写点什么

你不知道的开源分布式存储系统 Alluxio 源码完整解析(上篇)

作者:腾源会
  • 2021 年 11 月 15 日
  • 本文字数:5531 字

    阅读完需:约 18 分钟


一、前言

目前数据湖已成为大数据领域的最新热门话题之一,而什么是数据湖,每家数据平台和云厂商都有自己的解读。整体来看,数据湖主要的能力优势是:集中式存储原始的、海量的、多来源的、多类型的数据,支持数据的快速加工及计算。相比于传统的数据仓库,数据湖对数据有更大的包容性,支持结构化/半结构化/非结构化数据,能快速进行数据的落地和数据价值发掘。数据湖的技术体系可以分为三个子领域:数据湖存储、数据湖计算、数据湖统一元数据。


数据湖存储提供海量异构数据的存储能力,支持多类型的底层存储系统,如分布式存储 HDFS、对象存储 AWS S3、腾讯云对象存储 COS 等,除此之外,在数据湖场景中计算和存储分离,使得计算的数据本地性不复存在。因此有必要在数据湖存储和计算之间引入统一的数据缓存层。


Alluxio 是一款基于云原生开源的数据编排技术,为数据计算与数据存储构建了桥梁,支持将数据从原始存储层移动到加速计算的虚拟分布式存储系统。Alluxio 可为数据湖计算提供统一的数据湖存储访问入口,支持跨不同类型的底层存储并抽象出统一的数据访问命名空间,提供数据本地性、数据可访问性、数据伸缩性。


本文将对 Alluxio 底层源码进行简要分析,分上下两篇:主要包括本地环境搭建,源码项目结构,服务进程的启动流程,服务间 RPC 调用,Alluxio 中重点类详解,Alluxio 中 Block 底层读写流程,Alluxio Client 调用流程和 Alluxio 内置的轻量级调度框架。

二、环境准备


2.1. 本地部署

从官方下载安装版本(下载地址),以 2.6.0 安装为例,下载后解压安装包:

tar -zxvf alluxio-2.6.0-bin.tar.gz
复制代码

修改基本的配置文件,(1). 修改 alluxio-site.properties,设置 master 地址,设置默认 Alluxio root 挂载点

cp conf/alluxio-site.properties.template  alluxio-site.properties#放开注释:alluxio.master.hostname=127.0.0.1alluxio.master.mount.table.root.ufs=${alluxio.work.dir}/underFSStorage
复制代码

(2). 修改 masters、workers 配置对应 ip,本地安装,可都设置为 127.0.0.1


vi conf/mastersvi conf/workers
复制代码

修改完配置后,准备启动 Alluxio 服务,执行如下命令操作:

# mount对应磁盘bin/alluxio-mount.sh Mount workers# 进行环境校验bin/alluxio validateEnv masterbin/alluxio validateEnv worker
复制代码

服务启动命令操作,对于所有服务操作包括:master、worker、job_master、job_worker、proxy


# 启动所有服务bin/alluxio-start.sh all# 停止所有服务bin/alluxio-stop.sh all# 启动单个服务bin/alluxio-start.sh -a masterbin/alluxio-start.sh -a workerbin/alluxio-start.sh -a job_masterbin/alluxio-start.sh -a job_workerbin/alluxio-start.sh -a proxy
复制代码

启动后服务成功,也可通过 JPS 查看 Java 进程:AlluxioMaster、AlluxioWorker、AlluxioJobMaster、AlluxioJobWorker、AlluxioProxy。

  • http://localhost:19999,页面查看 alluxio master ui 界面,默认端口:19999

  • http://localhost:30000,页面查看 alluxio worker ui 界面,默认端口:30000


2. IDEA 调试

源码编译可参考官方说明文档:Building Alluxio From Source


mvn clean install -DskipTests# 加速编译mvn -T 2C clean install -DskipTests -Dmaven.javadoc.skip -Dfindbugs.skip -Dcheckstyle.skip -Dlicense.skip -Dskip.protoc
复制代码

通过 IDEA 启动 Alluxio 各个服务进程,其核心启动类包括:

  • AlluxioMaster:Main 函数入口,设置启动运行 VM Options,alluxio.logger.type=MASTER_LOGGER,RPC 端口:19998,Web 端口:19999;

  • AlluxioJobMaster:Main 函数入口,设置启动运行 VM Options,alluxio.logger.type=JOB_MASTER_LOGGER

  • AlluxioWorker:Main 函数入口,设置启动运行 VM Options,alluxio.logger.type=WORKER_LOGGER,

  • AlluxioJobWorker:Main 函数入口,设置启动运行 VM Options,alluxio.logger.type=JOB_WORKER_LOGGER

  • AlluxioProxy:Main 函数入口,设置启动运行 VM Options,alluxio.logger.type=PROXY_LOGGER

VM Options 参数示例如下:


-Dalluxio.home=/code/git/java/alluxio -Dalluxio.conf.dir=/code/git/java/alluxio/conf -Dalluxio.logs.dir=/code/git/java/alluxio/logs -Dlog4j.configuration=file:/code/git/java/alluxio/conf/log4j.properties -Dorg.apache.jasper.compiler.disablejsr199=true -Djava.net.preferIPv4Stack=true -Dalluxio.logger.type=MASTER_LOGGER -Xmx2g -XX:MaxDirectMemorySize=516M
复制代码

操作示例如下:

在项目根目录 logs 下可查看服务启动的日志文件:

DEBUG 远程调试,在 alluxio-env.sh 配置环境变量,可增加如下配置属性


export ALLUXIO_WORKER_JAVA_OPTS="$ALLUXIO_JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=6606"export ALLUXIO_MASTER_JAVA_OPTS="$ALLUXIO_JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=6607"export ALLUXIO_USER_DEBUG_JAVA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=6609"
复制代码

如下图所示,增加远程的监控端口,监控 Alluxio Worker 6606:

调用 Alluxio Shell 命令时开启 DEBUG 的输出,使用参数:-debug,示例如下:

bin/alluxio fs -debug ls /
复制代码

三、项目结构

Alluxio 源码的项目结构可简化如下几个核心模块:

  • alluxio-core:实现 Alluxio 系统的核心模块,其中 alluxio-core-server 内实现 Alluxio Master、Alluxio Worker、Alluxio Proxy;alluxio-core-client 定义 Alluxio Clien 操作;alluxio-core-transport 实现服务间 RPC 通信;

  • alluxio-job:Alluxio 内部轻量级作业调度实现,alluxio-job-server 内实现 Alluxio Job Master、Alluxio Job Worker;

  • alluxio-underfs:适配对接不同的底层存储,如 hdfs、cephfs、local、s3 等;

  • alluxio-table:实现 Alluxio Catalog 功能,基于 table 引擎读取元数据并支持关联 Alluxio 存储,目前 catalog 的底层 UDB 支持 hive metastore 和 aws glue catalog;

  • alluxio-shell:封装 Alluxio shell 工具;

四、服务进程

Alluxio 服务内部的 5 个核心进程:AlluxioMaster、AlluxioWorker、AlluxioProxy、AlluxioJobMaster、AlluxioJobWorker 都是基于 Process(进程)接口类扩展实现的,定义组件进程的生命周期管理操作。

类图实现继承关系如下所示:


4.1 AlluxioMaster

4.1.1. 启动流程

  • 基于 JournalSystem 维护 Master 元数据持久化信息,便于服务宕机后,从最新的 Journal File 恢复,详见 Journal Management;

  • 进行 AlluxioMaster 选举,Master 选举支持两种方式:ZK、Raft(RaftJournalSystem);

  • 基于 ProcessUtils 进行进程启停管理触发,执行 AlluxioMasterProcess 启动

    JournalSystem 启动/设置主要执行模式(gainPrimacy)

    AlluxioMasterProcess#startMasters:启动所有 Master 相关服务,包括 block master、FileSystem master 等;若是 leader,则调用 BackupManager#initFromBackup 初始化所有注册 master server 组件,若不是 leader 则仅启动 Master 的 RPC/UI 服务

    AlluxioMasterProcess#startServing:启动指标相关服务,包括 Web、JVM、RPC 相关的指标;

启动时序图简化如下所示:

4.1.2. Server 接口类

特别的,初始化并启动的 Server 接口类组件,主要包括 Master 类和 Worker 类,Server 会从线程池获取线程,启动执行各个 Server 定义的操作,server 中定义服务线程的生命周期操作,定义的接口方法如下:

  • getName:获取该 Server 名称;

  • getDependencies:该 Server 依赖的其他前置 Server;

  • getServices:获取 Server 定义的 GrpcService 集合;

  • start:Server 启动;

  • stop:Server 停止;

  • close:Server 关闭;


4.1.3. Master Server

定义 Master 组件中封装的各个线程 Server 服务,包括 Block 元数据管理,文件系统管理等,其细化类图如下所示:

4.1.3.1. DefaultFileSystemMaster

Alluxio Master 处理系统中所有文件系统元数据管理的 Server 服务,基于 DefaultFileSystemMaster 可对文件执行 Lock(加锁)操作,为了对任意 inode 进行读写操作,需要对 inode tree 中的每个独立路径进行加锁。InodeTree 对象提供加锁方法有:InodeTree#lockInodePath、InodeTree#lockFullInodePath,方法返回已被加锁处理的 LockedInodePath 路径对象。

在 DefaultFileSystemMaster 中常用的上下文对象:JournalContext, BlockDeletionContext, RpcContext;用户对文件元数据的访问(方法调用)都有一个独立的线程进行审计日志记录及管理。

备注:当获取 inode path 时,可能存在并发操作对该 path 进行写变更操作,那么读取 inode path 会抛出异常,提示 path 的数据结构已变更。

DefaultFileSystemMaster start 启动流程概述

  • 基于 InodeTree 初始化文件系统根目录(initializeRoot)并判断是否有该文件系统权限;

  • 遍历 MountTable,初始化 MasterUfsManager 并进行文件系统挂载 Mount 操作;

  • 提交不同的 HeartbeatThread(心跳线程) 进行各个检测校验,最终调用 HeartbeatExecutor.heartbeat 方法,其心跳检测包括:

     BlockIntegrityChecker:Block 完整性校验

    InodeTtlChecker:File Inode TTL 生命周期校验

    LostFileDetector:丢失文件探测

    ReplicationChecker:副本数校验

    PersistenceSchedule:持久化调度

    PersistenceChecker:持久化校验

    TimeSeriesRecorder:时间序列记录

    UfsCleaner:UFS 清理器


HeartbeatExecutor 的类图概要


4.1.3.2. DefaultBlockMaster

Alluxio Master 中管理所有 Block 和 Worker 映射元数据的 Server 服务。

为保证并发请求,BlockMaster Server 使用支持并发的数据结构,每个元数据都可以进行独立的加锁操作。在 BlockMaster 中有两大类元数据:block metadata(block 块元数据),worker metadata(worker 节点元数据):

  • block metadata 加锁操作:基于 block 执行任意的 BlockStore 操作,从 mLostBlocks 中移除元素;

  • worker metadata 加锁操作:校验/更新 worker 注册状态,读/写 worker 使用率,读/写 worker 上的 block 管理;


为避免死锁操作,如果 block 和 worker 元数据需要同时加锁,worker 需要在 block 之前加锁,释放锁时则相反,block 需要在 worker 之前释放锁。

start 启动流程概述:提交 HeartbeatThread(心跳线程) 进行检测校验,提交的线程是:LostWorkerDetectionHeartbeatExecutor,对 worker 的心跳进行检测。


4.2. AlluxioWorker

4.2.1. 启动流程

  • 通过 MasterInquireClient.Factory 获取 Alluxio Master 的地址和相关配置信息;

  • 创建 AlluxioWorkerProcess 进程对象,并执行 start 方法,具体如下:

    通过 WorkerRegistry 获取 Worker 上的所有 Worker Server 服务,并启动相应的 Server

    注册 WebServer Handler,并启动,包括通用指标和 Prometheus 指标;

    注册 JvmPauseMonitor,采集 worker 节点相关的 JVM 监控指标信息;

  • 如果 Worker 内嵌 FUSE 服务,则启动 FuseManager


4.2.2. Worker Server


4.2.2.1. DefaultBlockWorker

负责管理 Worker 节点中最高层级的 Block 抽象操作,包括:

  • 周期性的 BlockMasterSync,将当前 Worker 节点的 Block 信息周期定时上报同步给 Master;

  • 维护当前 Worker 所有 Block 信息与底层存储操作的逻辑关系;

start 启动流程概述:通过 BlockMasterClientPool 获取 BlockMaster RPC 地址并注册,基于 ExecutorService 提交 Worker 节点的 HeartbeatThread 线程,包括:

  • BlockMasterSync:将 Worker 节点 Block 信息定时同步 BlockMaster 进行统一 block 元数据管理;

  • PinListSync:维护 Alluxio 与底层 UFS 的联通地址;

  • StorageChecker:校验存储地址;


4.3. AlluxioProxy

4.3.1. 启动流程

  • 基于 ProxyProcess.Factory 创建对应的进程对象:AlluxioProxyProcess;

  • 创建 AlluxioProxyProcess 进程对象后,执行 start 方法,调用 ProxyWebServer 执行 start 方法,启动 Proxy Web 服务;


4.4. AlluxioJobMaster

4.4.1. 启动流程

  • 基于 AlluxioJobMasterProcess.Factory 创建对应的进程对象:AlluxioJobMasterProcess;

  • AlluxioJobMasterProcess 执行 start 方法,调用细节如下:

    启动 AlluxioJobMaster 关联的 JournalSystem,并获取 Master Leader;

    启动 Job 的 Server 服务,调用 JobMaster start;

    分别启动 JobMaster 的 Web Server 和 RPC Server,提供对外通信服务;

4.4.2. JobMaster

Alluxio 内置轻量级的作业调度框架,JobMaster 处理 AlluxioJobMaster 中所有 job 管理相关操作。

start 启动流程概述:基于 PlanTracker 获取上一次调度系统中遗留的所有运行中执行计划并停止,提交 HeartbeatThread(心跳线程) 进行监测,提交的进程是:LostWorkerDetectionHeartbeatExecutor,用于检测心跳丢失的 Worker 节点;

4.5. AlluxioJobWorker

4.5.1. 启动流程

  • 通过 MasterInquireClient.Factory 获取 Alluxio Master 的地址和相关配置信息;

  • 创建 AlluxioJobWorkerProcess 进程对象,并执行 start 方法,具体如下:

    注册 WebServer Handler 并启动 JobWorkerWebServer,提供 Web 服务;

    启动 JobWorker 的 Server 服务 JobWorker,注册 job worker 节点,并提交心跳检测线程 CommandHandlingExecutor;

    启动 RPC 服务于外部通信。



4.5.2. JobWorker

负责管理 Worker 节点中执行任务相关的所有操作,通过 CommandHandlingExecutor 心跳检测执行进程实现。

start 启动流程概述:向 JobWorkerIdRegistry 注册当前 worker 节点信息,提交 HeartbeatThread(心跳线程) 进行监测,提交的线程是:CommandHandlingExecutor,处理 JobWorker 节点所接受的 Command 命令。

五、RPC 框架

Alluxio 是分布式存储缓存系统,服务之间的通信经过 RPC 调用,其内部采用了 grpc 框架实现,在子项目 alluxio-core-transport 中定义 RPC 的 proto 文件。以 AlluxioMaster 为例,详述 RPC 启动调用流程:AlluxioMaster 进程启动的时候,会启动 grpc server 对外提供接口服务,其中 Server(Master 服务)中定义各个 Server 待注册启动的 RPC 服务,所有 RPC 服务注册到 GrpcServerBuilder 后,基于 GrpcServerBuilder.build 生成 GrpcServer 并启动。

Master RPC 和 Worker RPC 注册服务,都是基于 Handler 实现 grpc 定义的方法,如下所示:

《Alluxio-源码简析》下篇更精彩哦,已同步更新。

用户头像

腾源会

关注

Believe in Open Source 2021.08.04 加入

腾源会是腾讯云成立的汇聚开源项目、开源爱好者、开源领导者的开放社区,致力于帮助开源项目健康成长、开源爱好者能交流协助、开源领导者能发挥领袖价值,让全球开源生态变得更加繁荣。

评论

发布
暂无评论
你不知道的开源分布式存储系统 Alluxio 源码完整解析(上篇)