Alluxio 原始碼完整解析 | 你不知道的開源資料編排系統 (上篇)

語言: CN / TW / HK

前言

目前資料湖已成為大資料領域的最新熱門話題之一,而什麼是資料湖,每家資料平臺和雲廠商都有自己的解讀。整體來看,資料湖主要的能力優勢是:集中式儲存原始的、海量的、多來源的、多型別的資料,支援資料的快速加工及計算。相比於傳統的資料倉庫,資料湖對資料有更大的包容性,支援結構化/半結構化/非結構化資料,能快速進行資料的落地和資料價值發掘。資料湖的技術體系可以分為三個子領域:資料湖儲存、資料湖計算、資料湖統一元資料。

資料湖儲存提供海量異構資料的儲存能力,支援多型別的底層儲存系統,如分散式儲存 HDFS、物件儲存 AWS S3、騰訊雲物件儲存 COS 等,除此之外,在資料湖場景中計算和儲存分離,使得計算的資料本地性不復存在。因此有必要在資料湖儲存和計算之間引入統一的資料快取層。

Alluxio是一款基於雲原生開源的資料編排技術,為資料計算與資料儲存構建了橋樑,支援將資料從原始儲存層移動到加速計算的虛擬分散式儲存系統。Alluxio可為資料湖計算提供統一的資料湖儲存訪問入口,支援跨不同型別的底層儲存並抽象出統一的資料訪問名稱空間,提供資料本地性、資料可訪問性、資料伸縮性。

本文將對 Alluxio 底層原始碼進行簡要分析,分上下兩篇:主要包括本地環境搭建,原始碼專案結構,服務程序的啟動流程,服務間RPC呼叫,Alluxio 中重點類詳解,Alluxio 中 Block 底層讀寫流程,Alluxio Client呼叫流程和 Alluxio 內建的輕量級排程框架。

環境準備

本地部署

從官方下載安裝版本(下載地址),以2.6.0安裝為例,下載後解壓安裝包:
1 tar -zxvf alluxio-2.6.0-bin.tar.gz
修改基本的配置檔案,
(1). 修改alluxio-site.properties,設定master地址,設定預設Alluxio root掛載點:
1 cp conf/alluxio-site.properties.template alluxio-site.properties
2 #放開註釋:
3 alluxio.master.hostname=127.0.0.1
4 alluxio.master.mount.table.root.ufs=${alluxio.work.dir}/underFSStorage

2). 修改masters、workers配置對應ip,本地安裝,可都設定為127.0.0.1
1 vi conf/masters
2 vi conf/workers

修改完配置後,準備啟動Alluxio服務,執行如下命令操作:
1 # mount對應磁碟
2 bin/alluxio-mount.sh Mount workers
3 # 進行環境校驗
4 bin/alluxio validateEnv master
5 bin/alluxio validateEnv worker

服務啟動命令操作,對於所有服務操作包括:master、worker、job_master、job_worker、proxy
1 # 啟動所有服務
2 bin/alluxio-start.sh all
3 # 停止所有服務
4 bin/alluxio-stop.sh all
5
6 # 啟動單個服務
7 bin/alluxio-start.sh -a master
8 bin/alluxio-start.sh -a worker
9 bin/alluxio-start.sh -a job_master
10 bin/alluxio-start.sh -a job_worker
11 bin/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
在這裡插入圖片描述
IDEA除錯

原始碼編譯可參考官方說明文件:Building Alluxio From Source
1 mvn clean install -DskipTests
2 # 加速編譯
3 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引數示例如下:
1 -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 配置環境變數,可增加如下配置屬性
1 export ALLUXIO_WORKER_JAVA_OPTS=“ A L L U X I O J A V A O P T S − a g e n t l i b : j d w p = t r a n s p o r t = d t s o c k e t , s e r v e r = y , s u s p e n d = n , a d d r e s s = 6606 " 2 e x p o r t A L L U X I O M A S T E R J A V A O P T S = " ALLUXIO_JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=6606" 2 export ALLUXIO_MASTER_JAVA_OPTS=" ALLUXIOJAVAOPTSagentlib:jdwp=transport=dtsocket,server=y,suspend=n,address=6606"2exportALLUXIOMASTERJAVAOPTS="ALLUXIO_JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=6607”
3 export ALLUXIO_USER_DEBUG_JAVA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=6609"

如下圖所示,增加遠端的監控埠,監控Alluxio Worker 6606:
在這裡插入圖片描述
呼叫Alluxio Shell命令時開啟DEBUG的輸出,使用引數:-debug,示例如下:
1 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(程序)介面類擴充套件實現的,定義元件程序的生命週期管理操作。

類圖實現繼承關係如下所示:
在這裡插入圖片描述

AlluxioMaster

啟動流程

基於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相關的指標;

啟動時序圖簡化如下所示:
在這裡插入圖片描述
Server介面類
特別的,初始化並啟動的Server介面類元件,主要包括Master類和Worker類,Server會從執行緒池獲取執行緒,啟動執行各個Server定義的操作,server中定義服務執行緒的生命週期操作,定義的介面方法如下:
getName:獲取該Server名稱;

getDependencies:該Server依賴的其他前置Server;

getServices:獲取Server定義的GrpcService集合;

start:Server啟動;

stop:Server停止;

close:Server關閉;
在這裡插入圖片描述
Master Server
定義Master元件中封裝的各個執行緒Server服務,包括Block元資料管理,檔案系統管理等,其細化類圖如下所示:
在這裡插入圖片描述
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的類圖概要
    在這裡插入圖片描述
    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的心跳進行檢測。

AlluxioWorker

啟動流程

通過MasterInquireClient.Factory 獲取Alluxio Master的地址和相關配置資訊;

建立AlluxioWorkerProcess程序物件,並執行start方法,具體如下:

  • 通過WorkerRegistry獲取Worker上的所有Worker Server服務,並啟動相應的Server

  • 註冊WebServer Handler,並啟動,包括通用指標和Prometheus指標;

  • 註冊JvmPauseMonitor,採集worker節點相關的JVM監控指標資訊;

如果Worker內嵌FUSE服務,則啟動FuseManager
在這裡插入圖片描述
Worker Server
在這裡插入圖片描述
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:校驗儲存地址;

AlluxioProxy

啟動流程

基於ProxyProcess.Factory 建立對應的程序物件:AlluxioProxyProcess;

建立AlluxioProxyProcess程序物件後,執行start方法,呼叫ProxyWebServer執行start方法,啟動Proxy Web服務;
在這裡插入圖片描述
AlluxioJobMaster

啟動流程

基於AlluxioJobMasterProcess.Factory建立對應的程序物件:AlluxioJobMasterProcess;

AlluxioJobMasterProcess執行start方法,呼叫細節如下:

  • 啟動AlluxioJobMaster關聯的JournalSystem,並獲取Master Leader;

  • 啟動Job的Server服務,呼叫JobMaster start;

  • 分別啟動JobMaster的Web Server和RPC Server,提供對外通訊服務;
    在這裡插入圖片描述
    JobMaster

Alluxio內建輕量級的作業排程框架,JobMaster處理AlluxioJobMaster中所有job管理相關操作。

start啟動流程概述:基於PlanTracker獲取上一次排程系統中遺留的所有執行中執行計劃並停止,提交HeartbeatThread(心跳執行緒) 進行監測,提交的程序是:LostWorkerDetectionHeartbeatExecutor,用於檢測心跳丟失的Worker節點;

AlluxioJobWorker

啟動流程

通過MasterInquireClient.Factory 獲取Alluxio Master的地址和相關配置資訊;

建立AlluxioJobWorkerProcess程序物件,並執行start方法,具體如下:

  • 註冊WebServer Handler並啟動JobWorkerWebServer,提供Web服務;

  • 啟動JobWorker的Server服務 JobWorker,註冊job worker節點,並提交心跳檢測執行緒CommandHandlingExecutor;

  • 啟動RPC服務於外部通訊。
    在這裡插入圖片描述
    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-原始碼解析》下篇更精彩哦,敬請期待。

想要獲取更多有趣有料的【活動資訊】【技術文章】【大咖觀點】,請關注[Alluxio智庫]