Alluxio在多級分佈式緩存系統中的應用

1. 前言

隨着移動互聯網的發展,越來越多的業務數據和日誌數據需要用戶處理。從而,用數據去驅動和迭代業務發展。數據處理主要包括:計算和查詢。計算主要爲離線計算、實時流計算、圖計算、迭代計算等;查詢主要包括Ahdoc、OLAP、OLTP、KV、索引等。然而,在數據業務中,我們時常聽到數據需求方和數據開發方對性能慢的不滿,所以,如何高效響應海量且迫切的數據需求,是大數據平臺需要面對的一個關鍵問題,本文將介紹如何基於Alluxio建設分佈式多級緩存系統對數據進行計算加速和查詢加速。

2. 離線數據計算查詢加速問題

對於加速組件,結合生態兼容性和系統成熟性的基礎上,我們選擇Alluxio,我們知道,Alluxio是通過UFS思想訪問底層持久化的分佈式數據。通常,我們的數據主要存放在公司私有HDFS和MySQL上。那麼,如何通過UFS思想訪問到私有HDFS數據進行加速是我們面對的主要問題。私有HDFS由於歷史原因,其基於的HDFS版本較低,加上公司對HDFS進行了部分改造,使得開源的計算和查詢組件訪問公司內部的離線數據較爲困難。因此,如何打通Alluxio訪問私有HDFS成爲了系統的關鍵,後面的章節中,我們會做相關介紹。

3. 基於Alluxio的解決方案

整體上,我們當前的多級緩存系統由私有HDFS(PB級別) + MEM(400G) + SSD(64T)共3層組成。 示意如下:

image

系統會根據類似LRU思想對熱點數據進行緩存。我們主要存放熱點部門核心數據。由於資源申請原因,我們的Alluxio在南方,UFS在北方,所以後面的測試數據均爲跨地域性能數據,提供基於Spark、Hive、 Presto、YARN、API等方式訪問數據。

對於多級分佈式緩存系統,我們實現的整體示意圖如下:

image

從上述方案中,我們可以看出,如果通過path路徑方式訪問私有HDFS數據,直接使用alluxio://協議路徑即可;但是,如果要開源的Hive或者開源組件(基於Hive橋接)以數據表方式訪問公司內部的私有HDFS數據,需要進行“表schema映射”,思路如下圖:

image

基於上述方案,可以大致抽象出使用Alluxio的幾個一般性步驟,如下:

image

下面,我們會一一對每個步驟進行相關說明及案例數據分析。

3.1 Alluxio Meta數據同步(load和sync)

由於UFS隨時可能會有變動,導致Alluxio Meta和UFS的Meta不一致,那麼,如何在Alluxio的master中同步UFS文件的Meta十分重要,由於Alluxio Meta的load和sync性能成本較高(對於load和sync區別,本文不贅述),官方不推薦過度頻繁load和sync Alluxio的Meta數據。

3.1.1 同步方案

在我們的集羣中,我們均採用了默認的配置,而對於Aluxio Meta和UFS Meta的狀態主要有以下3種:

image

Meta同步方式 說明
fs ls path 查看文件狀態
fs checkConsistency -r path 檢測Alluxio Meta和UFS Meta的一致性,並進行repair修復

如果通過上面2種方法,Meta無論如何無法同步(大家應該會遇到這類情況),可以考慮fs rm -R --alluxioOnly path從Alluxio中刪除數據(僅刪除Alluxio中的數據,不刪除對應UFS上的數據),然後再fs ls path便可以讓Alluxio中的Meta和UFS的真實Meta同步一致。

3.1.2 Meta同步性能

我們使用Alluxio自帶的fs ls命令進行Meta同步,相關Alluxio設置如下:

alluxio.user.network.netty.timeout=600min
alluxio.user.network.netty.writer.close.timeout=600min
alluxio.user.network.socket.timeout=600min

上面的設置主要是爲了解決網絡超時,Meta同步是非常耗時的操作。

數據同步性能數據如下(請忽略分區大小的合理性):

image

3.2 Alluxio加載數據

3.2.1 數據加載方案

有了緩存系統,那麼,我們需要提前常用數據預加載到緩存系統中,如此,當用戶使用時候,直接從緩存中讀取,加快讀取速度。數據預加載的方式有如下圖的3種方式:

image

加載方式 數據類型 相關說明
Alluxio load命令 path類型數據 alluxio文件系統的基礎shell命令
Spark JAR path類型數據 自己開發,基於分佈式加載,利用yarn模式的jar,傳入path這個參數,來count文件的條數,以達到加載文件的目的。好處在於,可以通過配置spark-submit的相關參數來調整加載的速度
SQL命令 Hive table類型數據 對於Hive表的數據,可以直接利用SELECT COUNT(*) FROM T WHERE condition方式加載。

3.2.2 數據加載性能

我們主要利用Spark RDD count方式來預加載數據,Spark任務參數如下:

spark.executor.cores 4
spark.executor.instances 200
spark.executor.memory 20g
spark.speculation true
spark.speculation.interval 1000ms
spark.speculation.multiplier 5
spark.speculation.quantile 0.95 

可以注意到上面開啓了比較嚴格的探測執行,因爲在實際應用中,我們經常發現極少個別part的load非常慢。所以,在嚴格條件下開起探測執行,既保證了計算執行效率,又不太會影響到集羣性能。

image

3.3 Alluxio數據的讀取

3.3.1 數據本地化

本地化數據,相信大家都比較清楚,使用本地數據可以有效地提到數據讀取效率,具體可以將每個worker節點的alluxio.worker.hostname設置爲對應的$HOSTNAME,熟悉Spark的同學知道,這個設置類似Spark中的SPARK_LOCAL_HOSTNAME設置。

3.3.2 讀取性能數據1(私有HDFS->Alluxio->Hive/Presto)

image

上圖中,介詞through和on的區別是,前者爲首次從UFS上加載數據(即直接從私有HDFS上讀取數據),後者爲直接從Alluxio緩存中讀取數據。

3.3.3 讀取性能數據2(私有HDFS->Alluxio->Hive->Cube)

image

3.3.4 讀取性能數據3(私有HDFS->Alluxio->Spark)

image

3.4 寫入數據性能

3.4.1 通過alluxio://寫入

根據Alluxio官方介紹,寫數據方式主要有3種:

Default write type when creating Alluxio files. Valid options are MUST_CACHE (write will only go to Alluxio and must be stored in Alluxio), CACHE_THROUGH (try to cache, write to UnderFS synchronously), THROUGH (no cache, write to UnderFS synchronously).

本文僅測試CACHE_THROUGH, 數據爲150G,8000個part,由於性能不佳,推測主要由於Meta同步導致,所以後放棄此方法,由於任務結算結果數據通常不大, 改用MUST_CACHE或者直寫HDFS。

3.4.2 通過hdfs://直接寫入

當結果數據無需緩存到Alluxio時,我們同樣可以選擇直接將數據寫入到HDFS,此方案也無需進行Alluxio和UFS之前的Meta同步。

4 Alluxio集羣建設

4.1 打通私有HDFS

4.1.1 增加模塊

由於公司內部的私有HDFS系統和開源最新版本的HADOOP生態難以直接融合,有些接口不支持,於是想到辦法就是增加1個UFS存儲支持。借鑑公司Spark對於私有HDFS訪問思路,基於公司基礎部門訪問私有HDFS的動態庫及JNI的思想,實現對私有HDFS的打通。

4.1.2 遇到的libstdc++.so.6及libc.so.6版本過低問題

關於libstdc++.so.6和libc.so.6的關係,本文不贅述。由於我們增加的UFS是利用java通過jni調用so庫,而使用的so文件依賴的libstdc++.so.6版本較高,提示錯誤如下:

java.lang.UnsatisfiedLinkError: /tmp/libxxx5420953064508929748.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found

或者

glibc/libc.so.6: version `GLIBC_2.14' not found (required by /usr/lib64/libstdc++.so.6)

可利用如:strings /usr/lib64/libstdc++.so.6 | grep "GLIB"查看libstdc++.so.6和libc.so.6的符號庫版本。

其本質原因主要是,因爲我們環境使用的java目錄內部的so庫依賴的libstdc++.so.6的路徑有問題,可通過命令scanelf -F "%F %r" -BR $JAVA_HOME中的so對於libstdc++.so.6的搜索路徑,同樣也可以利用命令patchelf --set-interpreterpatchelf --force-rpath --set-rpath去修改優先搜索路徑。

4.1.3 無法連通的問題

在測試連通公司私有HDFS集羣的過程中,我們遇到了一個表現個比較奇怪的問題,就是啓動master後,Alluxio前端web頁面菜單"Browse"點擊無響應,debug代碼發現,某個reentrantLock的讀計數沒有正確降爲0(Master啓動過程中出現,所以debug時候需要設置suspend=y,同時可從AlluxioMaster的main函數開始入手),導致一直處於死鎖狀態,這個問題排查了很久,近乎把Alluxio啓動代碼邏輯都看完了,代碼上沒有發現問題,後來無意發現是因爲各節點(master和workers)上沒有安裝Agent,因爲前文提到JNI使用的so庫需要通過類似代理的方式先訪問Agent, 利用本地的Agent去訪問私有HDFS。

4.1.4 recoverLease函數

由於私有HDFS和和最新HDFS的差異,不存在recoverLease, 這個函數主要在XXXUnderFileSystem.java中,主要用戶當Alluxio的journal文件非正常關閉下進行恢復。目前,由於時間比較緊,這個功能暫時被跳過。

4.2 集羣部署

相關機器配置和組件版本如下:

CPU 56core、MEM 192G、SSD 1.6T、Disk XT
CentOS 6.3
Alluxio 1.8
hadoop-2.6.0-cdh5.14.0
spark-2.3.2-bin-hadoop2.7

4.2.1 用戶

Alluxio集羣使用alluxio用戶創建,便於遷移及維護。如果是root賬戶部署,可能會減少不少權限問題,但是和root賬號耦合度太高。所以,不推薦直接用root賬號安裝Alluxio。

4.2.2 部署常見問題

4.2.2.1 日誌顯示

Alluxio啓動(bin/alluxio-start.sh)、關閉(bin/alluxio-top.sh)等腳本中的日誌顯示不夠友好,都是用echo方式顯示,它的啓動關閉日誌沒有日期,對於新手來說,安裝部署問題很多,而日誌又沒有時間,造成無法區分日誌對應哪次操作,造成效率低下。

4.2.2.2 集羣啓動

目前的./bin/alluxio-start.sh [workers|master|all] [NoMount|SudoMount],它會默認不給任何提示,先殺死進程後再啓動進程,而且不是類似hadoop,提示進程運行中,需要先人肉殺死再啓動,我們進行了改造。不然,對於緩存在內存中的數據丟失。

4.2.2.3 RAM內存申請

爲了保證速度,我們可能設置MEM作爲一級緩存如下

alluxio.worker.tieredstore.level0.alias=MEM
alluxio.worker.tieredstore.level0.dirs.path=/mnt/ramdisk
alluxio.worker.tieredstore.level0.dirs.quota=${alluxio.worker.memory.size}
alluxio.worker.tieredstore.level0.reserved.ratio=0.1

那麼在執行./bin/start-alluxio.sh workers SudoMount時會提示出錯,因爲申請內存申請沒有權限,解決方案,可以在/etc/sudoers文件中增加一行: alluxio ALL=(ALL) ALL

5 未來計劃

5.1 更多應用場景

本文中的多級緩存系統(BigCache)除了可以加速訪問熱數據外,還變相起到了橋接作用。

讓原本無法直接訪問公司存儲系統數據的新生代開源計算查詢組件,可以通過訪問alluxio協議變相訪問私有HDFS數據,從0到1開啓了訪問公司私有HDFS數據的可能!

另外,多級緩存系統不但在離線數據加工方面能有效加速,同時它亦可在對象存儲系統中得到較好的應用潛力。

5.2 Hive表映射自動探測更新

如上面第3章節提到,現在我們如果要讓一些開源組件(基於Hive訪問數據)訪問到公司內部Hive(私有HDFS)的數據,我們需要人工建設表的schema進行映射,然後利用腳本進行表的partition加載,這一類通用工作,後續計劃web化、自動化。

5.3 HA的支持

這個問題在整個新增UFS模塊開發中,耽誤了非常多的時間,主要原因是因爲我們底層是通過JNI利用公司基礎部門的.so動態庫訪問公司底層的私有HDFS,在我們配置了HA後,重啓過程中,會出現core dump,參考了公司相關wiki,定位成本比較高,所以後續需要對core的問題進行進一步排查,支持系統的HA。

5.4 容器化部署

近年來,公司物理機器的配置越來越好,很多機器上都配置有SSD硬盤,而很多線上服務可能只用到了HD部分,對SSD的需求不大,所以如果能夠通過混部的方式,將各臺機器的SSD利用起來,形成一個巨大的多級緩存池,用來加速離線數據計算和查詢,帶來時效提高收益的同時,也大大提高了機器的利用率,降低成本。

5.5 易用性與性能

如上文一些章節提到,目前易用性還需要進一步提高,比如對於In Alluxio Data的搜索,某些數據緩存過期時間的設置,集羣的維護等等都較爲不便,同時,對於Meta同步、數據加載、數據讀取等性能提高也有較大需求。

6 參考資料

  1. https://www.alluxio.org/docs/1.8/en/reference/Properties-List.html
  2. https://www.alluxio.org/docs/1.8/en/compute/Hive.html
  3. https://www.alluxio.org/docs/1.8/en/deploy/Running-Alluxio-On-Yarn.html
  4. https://www.alluxio.org/docs/1.8/en/compute/Presto.html
  5. https://www.alluxio.org/docs/1.8/en/compute/Spark.html
  6. https://www.alluxio.org/docs/1.7/en/DevelopingUFSExtensions.html
  7. https://www.alluxio.org/docs/1.8/en/operation/Troubleshooting.html
  8. https://www.alluxio.org/overview/performance-tuning
  9. https://hortonworks.com/blog/resource-localization-in-yarn-deep-dive/

作者介紹

王冬,軟件研發工程師,2012年北京理工大學計算機本碩畢業,從事大數據領域7年多,先後負責大數據組件研發、大數據平臺架構、大數據研發等工作,對大數據整體生態較爲熟悉瞭解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章