一、前言
目前數據湖已成為大數據領域的最新熱門話題之一,而什么是數據湖,每家數據平台和雲廠商都有自己的解讀。整體來看,數據湖主要的能力優勢是:集中式存儲原始的、海量的、多來源的、多類型的數據,支持數據的快速加工及計算。相比於傳統的數據倉庫,數據湖對數據有更大的包容性,支持結構化/半結構化/非結構化數據,能快速進行數據的落地和數據價值發掘。數據湖的技術體系可以分為三個子領域:數據湖存儲、數據湖計算、數據湖統一元數據。
數據湖存儲提供海量異構數據的存儲能力,支持多類型的底層存儲系統,如分布式存儲 HDFS、對象存儲 AWS S3、騰訊雲對象存儲 COS 等,除此之外,在數據湖場景中計算和存儲分離,使得計算的數據本地性不復存在。因此有必要在數據湖存儲和計算之間引入統一的數據緩存層。
Alluxio 是一款基於雲原生開源的數據編排技術,為數據計算與數據存儲構建了橋梁,支持將數據從原始存儲層移動到加速計算的虛擬分布式存儲系統。Alluxio 可為數據湖計算提供統一的數據湖存儲訪問入口,支持跨不同類型的底層存儲並抽象出統一的數據訪問命名空間,提供數據本地性、數據可訪問性、數據伸縮性。
本文將對 Alluxio 底層源碼進行簡要分析,分上下兩篇:主要包括本地環境搭建,源碼項目結構,服務進程的啟動流程,服務間 RPC 調用,Alluxio 中重點類詳解,Alluxio 中 Block 底層讀寫流程,Alluxio Client 調用流程和 Alluxio 內置的輕量級調度框架。
二、環境准備
2.1. 本地部署
從官方下載安裝版本(下載地址),以 2.6.0 安裝為例,下載后解壓安裝包:
修改基本的配置文件,(1). 修改 alluxio-site.properties,設置 master 地址,設置默認 Alluxio root 掛載點
(2). 修改 masters、workers 配置對應 ip,本地安裝,可都設置為 127.0.0.1
修改完配置后,准備啟動 Alluxio 服務,執行如下命令操作:
服務啟動命令操作,對於所有服務操作包括:master、worker、job_master、job_worker、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
通過 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 參數示例如下:
操作示例如下:

在項目根目錄 logs 下可查看服務啟動的日志文件:

DEBUG 遠程調試,在 alluxio-env.sh 配置環境變量,可增加如下配置屬性
如下圖所示,增加遠程的監控端口,監控 Alluxio Worker 6606:

調用 Alluxio Shell 命令時開啟 DEBUG 的輸出,使用參數:-debug,示例如下:
三、項目結構
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-源碼簡析》下篇更精彩哦,已同步更新。