PART ONE
目前数据湖已成为大数据领域的最新热门话题之一,而什么是数据湖,每家数据平台和云厂商都有自己的解读。整体来看,数据湖主要的能力优势是:集中式存储原始的、海量的、多来源的、多类型的数据,支持数据的快速加工及计算。相比于传统的数据仓库,数据湖对数据有更大的包容性,支持结构化/半结构化/非结构化数据,能快速进行数据的落地和数据价值发掘。数据湖的技术体系可以分为三个子领域:数据湖存储、数据湖计算、数据湖统一元数据。
数据湖存储提供海量异构数据的存储能力,支持多类型的底层存储系统,如分布式存储 HDFS、对象存储 AWS S3、腾讯云对象存储 COS 等,除此之外,在数据湖场景中计算和存储分离,使得计算的数据本地性不复存在。因此有必要在数据湖存储和计算之间引入统一的数据缓存层。
Alluxio是一款基于云原生开源的数据编排技术,为数据计算与数据存储构建了桥梁,支持将数据从原始存储层移动到加速计算的虚拟分布式存储系统。Alluxio可为数据湖计算提供统一的数据湖存储访问入口,支持跨不同类型的底层存储并抽象出统一的数据访问命名空间,提供数据本地性、数据可访问性、数据伸缩性。
本文将对 Alluxio 底层源码进行简要分析,分上下两篇:主要包括本地环境搭建,源码项目结构,服务进程的启动流程,服务间RPC调用,Alluxio 中重点类详解,Alluxio 中 Block 底层读写流程,Alluxio Client调用流程和 Alluxio 内置的轻量级调度框架。
PART TWO
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。
2.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各个服务进程,其核心启动类包括:
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 /
PART THREE
Alluxio源码的项目结构可简化如下几个核心模块:
PART FOUR
Alluxio服务内部的5个核心进程:AlluxioMaster、AlluxioWorker、AlluxioProxy、AlluxioJobMaster、AlluxioJobWorker 都是基于Process(进程)接口类扩展实现的,定义组件进程的生命周期管理操作。
类图实现继承关系如下所示:
4.1 AlluxioMaster
启动时序图简化如下所示:
特别的,初始化并启动的Server接口类组件,主要包括Master类和Worker类,Server会从线程池获取线程,启动执行各个Server定义的操作,server中定义服务线程的生命周期操作,定义的接口方法如下:
定义Master组件中封装的各个线程Server服务,包括Block元数据管理,文件系统管理等,其细化类图如下所示:
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启动流程概述:
附:HeartbeatExecutor的类图概要
Alluxio Master中管理所有Block和Worker映射元数据的Server服务。
为保证并发请求,BlockMaster Server使用支持并发的数据结构,每个元数据都可以进行独立的加锁操作。在BlockMaster中有两大类元数据:block metadata(block块元数据),worker metadata(worker节点元数据):
为避免死锁操作,如果block和worker元数据需要同时加锁,worker需要在block之前加锁,释放锁时则相反,block需要在worker之前释放锁。
start启动流程概述:提交HeartbeatThread(心跳线程) 进行检测校验,提交的线程是:LostWorkerDetectionHeartbeatExecutor,对worker的心跳进行检测。
4.2. AlluxioWorker
负责管理Worker节点中最高层级的Block抽象操作,包括:
start启动流程概述:通过BlockMasterClientPool获取BlockMaster RPC地址并注册,基于ExecutorService提交Worker节点的HeartbeatThread线程,包括:
4.3. AlluxioProxy
4.4. AlluxioJobMaster
Alluxio内置轻量级的作业调度框架,JobMaster处理AlluxioJobMaster中所有job管理相关操作。
start启动流程概述:基于PlanTracker获取上一次调度系统中遗留的所有运行中执行计划并停止,提交HeartbeatThread(心跳线程) 进行监测,提交的进程是:LostWorkerDetectionHeartbeatExecutor,用于检测心跳丢失的Worker节点;
4.5. AlluxioJobWorker
负责管理Worker节点中执行任务相关的所有操作,通过CommandHandlingExecutor 心跳检测执行进程实现。
start启动流程概述:向JobWorkerIdRegistry注册当前worker节点信息,提交HeartbeatThread(心跳线程) 进行监测,提交的线程是:CommandHandlingExecutor,处理JobWorker节点所接受的Command命令。
PART FIVE
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-源码简析》下篇更精彩哦,已同步更新。
欢迎关注「腾源会」公众号,期待你的「在看」哦~👇