同時支撐8千併發,Alluxio在騰訊遊戲AI的應用與優化實踐!

語言: CN / TW / HK

分享嘉賓:陳壽緯、毛寶龍

編輯整理:張德通

出品平臺:DataFunTalk

導讀: 本次分享由羅格斯大學計算機博士、Alluxio OS核心工程師陳壽緯和騰訊Alluxio OTeam負責人、Alluxio PMC、Apache Ozone commiter毛寶龍一起,介紹Alluxio和Alluxio對AI場景的支援,並對使用與開發Alluxio的業務背景和其中的細節做詳細介紹。

本文圍繞下面五點展開:

  • Alluxio介紹

  • 業務背景介紹

  • 研發調優

  • 對比測試

  • 未來工作

01

Alluxio介紹

1. Alluxio概覽

全球獨創性: 全球首個分散式超大規模資料編排系統。

產學研一體: 孵化於 加州大學伯克利分校AMP實驗室 ,是創始人李浩源博士的論文課題。

全球化開發: 孵化之初即秉承“開源開放”願景,實現了專案在全球範圍內的開源。目前已經有超過 300多個組織機構 以及 超過1100位貢獻者 參與開發。

全面部署驗證: 全球 十大網際網路公司中有八家 已經在生產環境中部署了Alluxio;已經在全球Web規模的現代化資料服務的生產環境中得到驗證。

2. Alluxio介紹

在大資料生態系統中,Alluxio是位於大資料和AI計算框架與分散式儲存系統之間的,Alluxio為上層計算框架提供了統一的客戶端和統一的API全域性名稱空間。在AI場景下,底層儲存使用ceph,上層應用是特徵計算,使用Alluxio作為中間層提供分散式共享快取服務,Alluxio非常適合應用到這個場景。

特徵計算的業務特點是多讀小檔案、高併發。我們針對這個業務特點利用Alluxio的能力進行了優化。 第一是Alluxio提供了很好的雲上支援,可以方便地在算例平臺部署和擴縮容,Alluxio和業務服務部署親和性好,可以部署在同一個節點上,利用本地快取提供IO吞吐量。 Alluxio worker使用記憶體盤可以提供充足的快取空間,通過Alluxio的Distribute load功能把ceph儲存的熱點資料載入到記憶體後,Alluxio即可提供記憶體效能的IO吞吐量,緩解ceph壓力。

3. Alluxio核心功能

(1) 分散式快取

Alluxio最核心的業務是提供分散式快取加速資料應用。Spark、Presto、TensorFlow等資料密集型應用讀取非本地資料來源時,Alluxio載入原始資料檔案,將分片進行打散後儲存在靠近應用的Alluxio節點上,增強資料的本地性。服務上雲後,資料的本地性難以保證,Alluxio通過data orchestration保證資料本地性。

圖中,物件儲存內的檔案一和檔案二分別被分片後儲存到兩臺Alluxio伺服器上。應用端即可就近從對應的資料分片伺服器上讀取資料。當應用讀取熱資料較多時,增加Alluxio快取可以明顯地提升資料處理效率。

(2) 多種 API 適用於不同場景

Alluxio核心功能之二: 對應用提供不同型別的資料介面。

例如Spark和Presto這類資料計算框架支援HDFS介面讀取資料,可以把這些計算框架從HDFS無縫換到Alluxio。除了HDFS介面,我們還我們提供了更多介面,例如Posix。

TensorFlow進行AI模型訓練的場景中,TensorFlow通過Posix讀取資料,通過Alluxio可以很方便地實現分散式的AI訓練。

Alluxio在雲上部署,圖中展示的是Alluxio部署在k8s叢集上。Alluxio通過Posix介面向TensorFlow提供“本地”資料服務支援,其底層可以對接任意Alluxio支援的雲端儲存。我們稱Alluxio支援對接的底層儲存為Under File System。

(3) 統一名稱空間

Alluxio核心功能之三:把使用者的儲存系統以對資料消費者透明的形式統一接入,資料消費者只需要配置資料儲存的具體地址,不需要根據底層儲存系統再進行編碼。

例如有一家公司部署了多個HDFS,並在線上接入了不同雲廠商的雲物件儲存服務,這時很適合使用Alluxio的掛載功能,把資料接入到Alluxio這一統一的檔案抽象中。每個路徑都會對應到Alluxio的目錄,很方便地為上層資料引用提供資料快取服務。

4. Alluxio在機器學習場景下的挑戰與優化

  • 訓練資料為海量小檔案(如圖片): 機器學習場景和傳統大資料場景不同,區別主要在於需要讀取的資料檔案特徵不同。 機器學習場景下需要讀取的訓練資料是海量小檔案,例如圖片; 但傳統大資料場景下單個讀取的檔案 大小可能在1G左右。

  • 訓練資料規模超過單機可用儲存容量: 分散式訓練較大規模網路時,訓 練集需要被拷貝到機器上進行訓練。 但資料集大小超過了單機可以承載的容量,拷貝到單機上是一個不可能的挑戰。

  • 高併發度的分散式訓練任務,要求I/O高吞吐: 和傳統大資料儲存引擎場景不同,AI訓練是高併發的分散式訓練,IO吞吐量高。 IO吞吐量高主要消耗是在於AI訓練需要獲取檔案數量多、進行大量檔案請求。

針對以上挑戰,我們進行了以下調優:

(1) 優化設定及調整資源

首先是調整配置,我們可以基於業務場景,靈活選取Heap/Off-heap方式儲存檔案元資料資訊。當使用Alluxio加速單個分散式訓練任務,檔案的數量在百萬到千萬量級的數量級,可以使用Heap metastore做元資料管理。此時元資料保持在記憶體中,一個inode佔用大約2kb記憶體。當業務場景更加複雜,訓練集多且訓練集儲存在Alluxio中,如果檔案數量到達億級別,推薦使用Rocks off-heap metastore進行元資料管理。這種元資料管理方式可以同時使用記憶體和磁碟儲存資料元資訊,滿足更高的元資料管理需求。

第二個資源調整是支援client/worker連線執行緒所需空間。高併發情況下,可能有成千上萬併發的連線執行緒。把每個連結的buffer減少,降低整體記憶體消耗、支援高併發,提高響應速度。

最後,如果發現頻繁GC的問題,可以根據實際監控記憶體使用情況對Java程序記憶體引數進行調整。如果頻繁 GC,則調大數值。如果使用率低,則調小數值。圖中是推薦配置,可以更好地支援高併發client-worker連結執行緒所需的記憶體。

ALLUXIO_MASTER_JAVA_OPTS+=" -Xms256g -Xmx256g "
ALLUXIO_JAVA_OPTS+="-XX:MaxDirectMemorySize=10g "

(2) 在Master端合理快取元資料

Alluxio的master-slave模型中元資料請求會對master造成壓力。在AI分散式訓練場景中,由於小檔案數量多請求大,需要有一種方式合理地在master一側快取元資料。

一種方式是開啟定期全域性元資料同步,例如每隔三十秒從底層儲存系統同步一次所有元資料資訊。如果元資料量大、訓練任務對資料更新不敏感,可以適當把時間間隔加長,例如30s改為5min。元資料同步時間間隔需要根據業務需要進行配置。

alluxio.master.ufs.active.sync.interval=30sec

如果底層儲存使用的是HDFS,可以開啟Alluxio的Active Sync主動地更新元資料,對Alluxio底層檔案系統的壓力更小。

要主動避免元資料同步,使用者可以指定所有檔案每過10分鐘才會同步一次元資料,十分鐘內使用快取處理資料。

alluxio.user.file.metadata.sync.interval=10min

更多關於元資料的優化與調參建議,可以參考Alluxio PMC部落格:

http://www.alluxio.io/blog/metadata-synchronization-in-alluxio-design-implementation-and-optimization/

(3)  FUSE端快取元資料

另一大優化點是在Fuse客戶端做了元資料快取。

FUSE,即Filesystem in userspace,使用者空間檔案系統。

每次進行元資料請求時Alluxio Fuse客戶端不需要再向Alluxio Master請求資料,可以直接利用本地Alluxio Fuse客戶端快取的元資料即可。 我們提供了可配置的引數,如上圖,可以配置最大快取的數量和快取超時時間。

我們支援了 Fuse 掛載選項在作業系統層面對元資料進一步快取,attr_timeout = 7200, entry_timeout = 7200 調大檔案屬性,名稱查詢等作業系統快取時間設定更長會對效能優化比較明顯。

(4) Alluxio自建效能測試工具 StressBench

為了更好地幫助使用者在業務中用起來Alluxio,我們提供了一個開源的壓力測試工具,可以在Alluxio repo中找到。這個工具不需要外部元件,只需要一個執行的Alluxio叢集即可進行測試。元件可以通過讀寫和元資料操作對Alluxio的效能做測試。

StressBench可以適應多種場景,既可以是一個Alluxio master和一個Alluxio worker,也可以是多個Alluxio master配合多個Alluxio worker。

下面我們用Fuse客戶端作為示例做StressBench單節點測試。Fuse寫好檔案後我們進行讀操作,在讀測試檔案時我們利用Alluxio的runClass命令啟動測試任務、指定檔案掛載路徑、讀取方式、執行緒數、測試時長、Fuse寫入的檔案、資料夾的數量和檔案大小。在測試過程中為了避免快取的印象、確保測試的正確性,不會對一個資料夾進行讀寫,測試的檔案目錄要用不同資料夾掛載。

下面是測試返回的部分結果,其中展示的資訊有:單節點速率達到了183M/s,指定的引數和測試過程中產生的錯誤也會展示出來。這不是一個標準的測試結果,如果測試時使用的硬體效能更好、CPU數量更多,測試結果的吞吐量也會更高。

5. Alluxio白皮書

白皮書中詳細介紹了Fuse支援,也針對機器學習和深度學習在雲上加速具體提供的支援進行了詳細介紹,歡迎下載。

http://www.alluxio.io/resources/whitepapers/alluxio-for-machine-learning-deep-learning-in-the-cloud/

02

業務背景介紹

1. 遊戲AI

遊戲AI離線業務主要分為監督學習和強化學習兩部分,監督學習場景下主要是特徵計算、特徵生成,模型訓練,模型評估三個步驟。遊戲AI特徵計算中需要將對局資訊進行還原,通過統計和計算生成模型所需的特徵資料。對於資訊的還原過程有依賴,依賴包括遊戲本體、遊戲翻譯器、遊戲回訪工具等。一般遊戲依賴在100M到3G,遊戲的版本性質也決定了遊戲的對局資訊需要特定的版本遊戲依賴才能計算。

下圖中的gamecore就是遊戲依賴,它對應一個遊戲版本的linux客戶端。一種方案是將gamecore放到伺服器本地儲存,雖然可以提升效能和穩定性,但是成本高、受限於單機許可權和儲存容量。

另一種方案是把gamecore放在分散式儲存中,如ceph,部署更簡單,統一的分散式存讓資料更新方便快捷;缺點是ceph的元資料管理服務mds會成為瓶頸。一次特徵計算任務會排程上千容器,單個容器內有若干業務程序。服務啟動初期會有成千上萬程序訪問gamecore,這裡幾乎都是小檔案,此時ceph-mds會承載很大壓力,儲存到業務pod之間的延遲高,儲存到業務如果跨地域部署失敗率升高。

2. 部署架構

在遊戲AI團隊和運營團隊大力支援下,我們引入了Alluxio on Ceph Fs的解決方案,滿足業務的高併發讀寫需求。

下圖中展示了Alluxio對接的業務架構。Alluxio執行在我們稱為算力平臺的k8s平臺上,測試過程中4000cpu、4000併發可以穩定執行。特徵分析任務的每個任務pod配置了4cpu,業務側一共有1000個pod併發。每個pod嵌入了Alluxio Fuse sidecar,業務pod的讀請求之間通過Alluxio Fuse掛載的本地路徑以POSIX形式訪問Alluxio資料。

Alluxio叢集的master節點配置了HA模式,Worker數量達到1000個。我們希望業務pod和Alluxio worker pod可以儘可能親和性部署、儘量執行在同一個節點上,用domain socket 技術提升讀效能。在業務上線前,通過distributeLoad命令把ceph的熱點資料載入到Alluxio worker。

03

研發調優

特徵計算業務的Alluxio叢集在AI和機器學習場景中在業界已經是一個比較大的叢集。 業務側的高併發對worker形成的壓力可以通過擴充套件規模解決,但是master節點的壓力是一個比較難解決的問題,在上線過程中經歷了很多調優和特性開發,達到了比較好的效果。  

1. cephfs ufs支援

我們實現了兩種ceph fs底層儲存適配模組。

第一種方案是實現了cephfs底層儲存適配模組。通過HCFS ( Hadoop Compatible File System ) 的Hadoop儲存系統相容API,呼叫適配層ceph-hadoop。ceph-hadoop是一個開源實現,可以被Alluxio外的系統呼叫,通過它配合libcephfs訪問ceph。雖然這個方案的呼叫棧看上去比較深,但ceph-hadoop呼叫libcephfs的邏輯可以被社群維護起來。

第二種實現邏輯全部維護在cephfs2-ufs內,在Alluxio社群只有騰訊維護,維護程度不會很高。

通過儲存適配模組,十行以內程式碼即可以實現ceph對接。它可以mount、unmount cephfs底層儲存,能夠為Alluxio提供更好的上雲支援、讓Alluxio更貼近業務部署,Alluxio的worker使用記憶體盤快取cephfs熱點資料。

2. ratis-shell

在搭建基於Ratis的Alluxio HA集群后,我們為了能方便地把leader切換到其他master和獲取leader在哪個master上的詳細資訊,我們設計和實現了通過Alluxio控制Ratis server的運維命令。

我們與Alluxio、Ratis社群配合,實現了一些Alluxio shell,通過client訪問master的rpc請求。Alluxio master作為ratis client和ratis server進行通訊,比較曲折地實現了運維叢集的相關請求、穩定性差。例如,操作切換leader的請求必須傳送給leader,但是切換成功與否不能準確地返回,也不能知曉操作失敗的原因。

我們瞭解到Ozone社群也實現了類似的功能,這時我們思考如果每個依賴Ratis的專案都需要維護一套對應邏輯,是否可以把這些重複程式碼進行抽象後統一維護?仔細分析了ratis的rpc協議後我們發現根本不需要把請求傳送給Alluxio或Ozone,請求直接發給ratisserver即可。

我們在github上開源了opendataio/ ratis-shell專案。為了方便更多開發者參與到這個專案中來,我們在ratis社群提了issue:

http://issues.apache.org/jira/browse/RATIS-1412

該issue中的task接近完成。 目前ratis-shell程式碼作為模組形式加入ratis倉庫。

執行maven命令後會獲得打包好的可以獨立執行的ratis shell程式。

ratis-shell專案可以被Alluxio、OZone等其他專案使用,Ratis的貢獻者們和Alluxio、Ozone這些社群的開發者共同維護ratis-shell功能。 Ratis-shell得到了ratis專案維護者的肯定與合力維護,形成了可以被Alluxio、Ozone和其他任何基於ratis的專案呼叫的通用功能,動員了Ozone社群開發者一起維護該專案。

這個過程中我們得出了一個方法論: 做功能,思考問題不要侷限於眼前維護的軟體專案。更要放大視野,看到更多專案共同點,與更多社群和專案協同共建共同需要的功能。

3. Fuse Shell

Alluxio Fuse為了達到不修改核心、對上層應用保持一致的資料訪問介面,就在使用者態提供了一個自定義的檔案系統實現。我們在Alluxio Fuse client端針對幾乎全讀的業務場景打開了kernel cache, metadata cache和log cache進一步提升讀效能,對client端metadata cache做了優化,在底層儲存元資料變更時可以主動地把metadata快取標記為無效,清空無效快取。

實現方案上我們考慮了多種方案,一種是Alluxio Fuse作為rpc server或是unix domain socket實現輕量級服務,但這些實現後會增加Alluxio Fuse服務的負擔,與設計初衷不符。最終我們採用了另一種方案,利用POSIX本身的介面給Fuse服務傳遞訊號,在實現上我們採用對特定目錄進行解析的方式實現一定語義達到傳遞資訊的目的。

圖中是實現的具體架構,我們在Alluxio Fuse的基礎上進行了修改後實現了這部分功能。

把getattr方法用鉤子函式繫結到程式裡,即圖中的jnifuse_oper_getattr。getattr方法是ls檢視目錄時會被呼叫的方法。當在匹配的目錄中呼叫ls命令,此時呼叫getattr,jnifuse_oper_getattr指向的getattr_wrapper會被觸發,反向呼叫Java程式碼中相應的FS實現函式檢查目錄和檔案。此時根據檔案metadata判斷資料夾是否符合預定義的語義,如果是則執行預定義的功能,否則訪問Alluxio中快取的檔案。

當前該框架支援了metadata cache相關的三個命令如圖,感興趣的開發者可以對Fuse shell擴充套件,開發更多命令。

4. 動態引數配置

生產環境中,一些引數起初配置得並不合理,需要進行調整,又不能停止Alluxio服務;其他運維繫統需要在保證Alluxio執行得情況下,根據時間等業務執行情況調整配置。

如圖所示,client和master之間增加了updateConf API,通過該API讓線上叢集修改動態地反映到叢集中,儘量不影響線上業務。該API可以向master傳送變更請求,master更新配置後內部的config hash也會變更。Alluxio proxy、fuse、shell和client,此時都可以被看作client,其中的ConfHashSync會週期性地同步config hash,在配置有變更時同步配置。我們基於通知的機制實現配置變更同步,與變更相關的服務可以在程式碼邏輯內註冊監聽器監聽配置的變更。

5. 可觀測性、日誌、易用性

在落地Alluxio的過程中我們也建設建全了可觀測Alluxio系統,增加了二十多個監控指標,包括Total.Blocks、RpcOps、Ratis 指標、OS,JVM, GC 指標、Cache hitrate 指標、PendingQueue、Lock pool 大小、block Remover 的刪除塊的數量等;我們建設了中心化的日誌系統,監控報警運營,能夠全面地瞭解Alluxio執行情況。

我們提升了Alluxio系統的易用性,充分利用distributedLoad預熱功能,修復了 Alluxio Job Service 在執行大量 distributedLoad 時出現 OOM 的問題;增加了stacks頁面展示執行緒資訊、掛載表視覺化功能、下線節點、支援配置使用 IP 作為通訊 host、支援域名作為 host、通用的打包指令碼,支援整合指定內部 hadoop 版本、避免死鎖等嚴重問題潛在原因修復。

6. 配置調優,吞吐提升

在落地Alluxio的過程中我們也對Alluxio配置進行了調優。Alluxio提供了700多個配置項,需要使用者根據自身場景進行調優。在我們的業務場景中通常把Alluxio的jdk修改為騰訊內部 kona jdk11。使用 konajdk11 + g1gc,Alluxio master平滑運行了數個月,沒有過出現因為 full GC 導致的 leader master 切換問題。

Alluxio worker 的block副本數我們進行了調整。 Alluxio 預設打開了被動快取功能,

alluxio.user.file.passive.cache.enabled=true

客戶端如果發現數據塊不在本地 worker, 則會從遠端 worker 拷貝副本到本地,每個 worker 要儲存很多副本。 在 1000 個 worker 規模的場景下就會給 Alluxio master 增加巨大的元資料壓力,測試結果表明,這種情況下本地性帶來的效能收益實際上很小,我們關閉了這個配置,減輕 master 的壓力。

通過騰訊 jvm 團隊的幫助下,我們定位了 auditlog 開啟成為了純讀場景下的瓶頸,設定:

alluxio.master.audit.logging.enabled=false

關閉審計日誌後,吞吐提升7倍。這一效能瓶頸是通過 kona-profiler 抓取的火焰圖定位到的。此外,我們發現關閉auditlog後,火焰圖顯示效能瓶頸變為對 RocksDB 的讀取,後需我們將會在檔案數量小的情況下繼續嘗試改用Heap元資料管理方式,提升效能。

由於特徵生成任務在剛啟動的十分鐘內是一起拉取資料的,此時Master的壓力非常大,QPS達到系統支援的上限。 為了實現吞吐提升的目標,我們在client端做了多master叢集支援,共同分擔讀請求壓力。 同時我們也在單叢集效能方面做了調優,優化後單機群讀吞吐可以支撐22w QPS。 我們在效能優化的工作上選擇同時在多個方向上進行優化的嘗試,不孤注一擲: 單機群不能優化,多叢集也可以共同承擔壓力。

其他優化包括: alluxio.debug=true 時可以在Alluxio master看到更多資訊。 調大更新間隔時長可以減輕master負擔,如:

alluxio.master.cluster.metrics.update.interval=2min
alluxio.master.file.access.time.journal.flush.interval=1d
alluxio.user.conf.sync.interval=10min

但是1000個worker、上萬client同時更新依然會對master產生很大壓力。

04

對比測試

為了評估引入Alluxio帶來的收益,我們將某 moba 遊戲的特徵計算業務分別對接 Alluxio(UFS為cephfs)和 cephfs 進行對比測試。

測試叢集資訊如下:

  • master: 3 個 master 的 HighAvailability 方式部署。

  • worker: 1000個 worker, 約 4TB 的儲存空間。

  • 業務 pod: 1000個,每個pod 是4個核的並行任務。

  • 測試業務:某 moba 遊戲 AI特徵計算任務(包含 250000個對局)。

測試結果如下,ceph-fuse總時長僅供參考,ceph-fuse如果失敗,每個失敗的子任務會立刻標記為完成,總時長更低;失敗率資料比較準確。

引入Alluxio後承載4000併發的業務場景下沒有壓力,瓶頸不再是元資料訪問端,業務已經可以支撐到8000併發,後續計劃擴充到2w併發。業務的訪問量和併發數是無限擴充的。

下面是兩張在對比測試中的指標截圖。觀察Alluxio和 cephfs 的元資料壓力指標(rpc count 和 mds 的 qps), 在任務初期會有一個高峰:任務啟動後一起拉資料,隨時間增長QPS逐漸降低,這是業務模式決定的。

在使用 Alluxio 來承接業務的情況下,ceph mds 的 qps 幾乎為 0,說明 Alluxio 抵擋了大部分業務壓力。後半段是未使用 alluxio 的情況,cephfs 的 mds 的 qps 高峰達 5000多。

05

未來工作與開源貢

未來關於Alluxio工作的規劃包括提升吞吐的上限,利用 Alluxio CSI 解耦業務和 Alluxio FUSE,Alluxio localcache + Alluxio metadatacache 優化,通過類似負載均衡的功能分攤負載壓力,智慧讀寫排程策略等。

在開源貢獻這方面,騰訊有20+ contributor、1個PMC和2個commiter,釋出的相關文章數量在十篇以上,十多場直播分享,被merge的pr數400+。騰訊是Alluxio社群除Alluxio公司外貢獻數量最多的公司,我們主張團結一切可以團結的力量,尋求互利共贏,不閉門造輪。

經常有人問到騰訊內部的Alluxio版本與開源Alluxio的區別是什麼?我們會實現一些功能特性,經過內部生產驗證後推向開源社群。除了騰訊內部功能如認證鑑權、內部系統對接等不會推給社群外,都會貢獻給社群、和社群共建,與從特定版本拉出分支後獨立維護、不貢獻開源的模式相比,我們更願意與社群一起設計功能,code review和交流經驗,這樣的模式會有更長遠的收益。

▌引用

  • Ratis-shell

http://github.com/opendataio/ratis-shell

  • HCFSFuse

http://github.com/opendataio/hcfsfuse

  • 千節點 Alluxio 助力騰訊遊戲 AI 業務

http://cloud.tencent.com/developer/article/1889789

  • Alluxio執行緒池結構與吞吐量調優 (點選Alluxio公眾號,可檢視對應文章)

今天的分享就到這裡,謝謝大家。

在文末分享、點贊、在看,給個3連擊唄~

分享嘉賓:

Alluxio 最新白皮書下載:

關於我們:

DataFun: 專注於大資料、人工智慧技術應用的分享與交流。發起於2017年,在北京、上海、深圳、杭州等城市舉辦超過100+線下和100+線上沙龍、論壇及峰會,已邀請近1000位專家和學者參與分享。其公眾號 DataFunTalk 累計生產原創文章500+,百萬+閱讀,12萬+精準粉絲。

分享、點贊、在看 ,給個 3連擊 唄! :point_down: