騰訊內部實踐分享 | 千節點Alluxio 叢集助力遊戲 AI 業務
圖片來源:Pexels
本文作者:鄭兵、毛寶龍、潘致錚
Alluxio 是一個面向 AI 以及大資料應用,開源的分散式記憶體級資料編排系統。隨著大資料和 AI 業務向 Kubernetes 等容器管理平臺遷移,將 Alluxio 作為中間層,為資料查詢及模型訓練等場景加速,成為各廠商的首選方案。
Alluxio 在遊戲 AI 離線對局業務中解決的問題可以抽象為:分散式計算場景下的資料依賴問題,傳統的資料依賴的解決方式有:
- 映象打包,這種方式隔離性比較好,但使用映象快取能力有限,資料更新頻繁,每次都要重新打包部署映象,停服務更換容器;
- 即用即下,整體架構簡單,但每次訪問資料,都需要從遠端拉取,效能較差;
- 本地部署,資料本地性好,但解決許可權問題和運營困難。
這幾種方式,都有著各自的優缺點。引入 Alluxio,可以在成本沒有增加太多的情況下,顯著提升 AI 任務的併發上限,同時 AI 任務程式仍使用原有的 POSIX 方式訪問 Alluxio,因此業務對儲存系統的改變無感知。
本文主要介紹 Alluxio 在算力平臺上與遊戲 AI 特徵計算業務的適配和優化。
背景
遊戲 AI 離線訓練業務分為監督學習與強化學習兩種場景。其中在監督學習場景下,一般分為特徵計算、模型訓練與模型評估。在強化學習的部分場景下,也會有特徵計算的需求。遊戲 AI 場景的特徵計算中,需要將對局資訊進行還原,進而通過統計與計算,生成模型訓練所需的特徵資料。而對局資訊的還原必須通過相應的遊戲依賴(遊戲本體、遊戲翻譯器、遊戲回放工具等),一般情況下,遊戲依賴的大小在 100MB - 3GB 不等。而遊戲的版本性決定了特定的對局資訊需要特定版本的遊戲依賴才能計算。
儲存端的 gamecore 即遊戲依賴,對應一個遊戲版本的 linux 客戶端。將 gamecore 放到伺服器的本地儲存中,可以得到更好的讀取效能和穩定性,但是成本高,並且需要本機許可權。
另一個方案是把 gamecore 儲存在分散式儲存中,例如 ceph,這樣資料更新更快, 部署更簡單,缺點是 cephfs 的元資料管理服務 MDS 可能會成為瓶頸,通常一次特徵計算任務中會排程上千個容器,每個容器會啟動若干業務程序,在任務初期會有數千至上萬程序對同一個 gamecore 並行訪問,每分鐘儲存端有數百 GB 的讀資料量,由於都是小檔案,MDS 將承載所有的元資料壓力,另外,儲存與業務之間的延遲通常較高, 特別是不在同一地域時,有可能導致任務失敗率的提升。
綜合考量後,我們引入 Alluxio on Ceph 的方案解決業務現狀的痛點,在這個過程中,要感謝騰訊遊戲 AI 團隊和運管團隊給予的大力支援,遊戲 AI 團隊給我們介紹了整體業務背景,並協調準線上環境和現網環境,讓我們可以對方案進行充分測試後落地到生產環境, 運管團隊也在部署架構問題以及資源協調方面提供了大量幫助。
業務支援
在大資料生態系統中,Alluxio 位於資料驅動框架或應用和各種持久化儲存系統之間。Alluxio 統一了儲存在這些不同儲存系統中的資料,為其上層資料驅動型應用提供統一的客戶端 API 和全域性名稱空間。在我們的場景中,底層儲存是 cephfs, 應用是特徵計算,將 Alluxio 作為中間層提供分散式共享快取服務,非常適合對特徵計算業務這種一寫多讀,小檔案高併發訪問場景進行優化, 主要體現在幾個方面:
- Alluxio 提供很好的雲上支援,可以方便的在算力平臺上對 Alluxio 叢集進行部署和擴縮容。
- Alluxio 可以貼近業務部署,將業務和 Alluxio worker 親和到同一個 node,通過本地快取提升 I/O 吞吐。
- Alluxio 的 worker 使用算力平臺節點的記憶體盤,可以提供比較充足的快取空間,通過 distributedLoad 將底層儲存 cephfs 熱點資料載入到 worker 中,部分業務直接通過 Alluxio 訪問 gamecore,緩解底層儲存 cephfs 的壓力。
下圖展示了 Alluxio 對接業務的架構,本次上線中我們希望支援 4000 核併發的任務穩定執行, 對局特徵計算業務每個任務 pod 配置了四核 cpu, 在業務側提供了 1000 個 pod 的併發,每個 pod 嵌入了 alluxio-fuse sidecar 容器作為客戶端,業務的資料讀請求直接通過 alluxio-fuse 掛載出來的本地路徑,以 POSIX 的形式訪問 Alluxio 的資料。
Alluixo 叢集的 master 節點配置為 HA 模式,worker 的規模為1000 個,我們希望將業務的 pod 和 worker pod 儘可能對應的親和到一個 node 上,這樣做的好處是我們可以儘可能利用 domain socket ,進一步提升讀取效能。在業務上架之前,通過 distributedLoad 將 cephfs 中的熱點版本的 gamecore 版本資料預先載入到 Alluxio worker 進行預熱。
研發調優
目前承接特徵計算業務的 Alluxio 叢集在 AI 和機器學習場景中,屬於大規模部署案例(1000 + worker nodes)。業務側這麼大的併發訪問對 master 節點的承壓能力也是一個挑戰, 在上線過程中也經歷了多次的調優和新的特性開發達到最佳效果。
開發工作
- 針對本次特徵計算 + Cephfs 的使用場景,設計實現了基於 HCFS + cephfs-hadoop + libcephfs 的 cephfs 底層儲存實現以及直接基於 libcephfs 的底層儲存實現。
- 與 Alluxio 社群共同設計實現了 HA 切換 leader 到指定 master 節點的功能。
我們將 ratis 相關功能抽象為一個單獨的 ratis-shell 工具,利用 ratis-shell,可以向直接 ratis server 傳送 setConfiguration請求,來設定每個 master 的 priority,緊接著傳送 transferleader 請求,確認 leader 切換到了指定的節點上。ratis-shell 適用於Alluxio和 Ozone 以及其它所有利用 ratis 的應用。
- 新增動態更改配置的功能, 可以線上的修改某些叢集引數,在儘量不影響業務的情況下優化配置。
如上圖所示,在 Client 和 Master 之間,增加了 updateConf API,通過該 API,可以向 Alluxio Master 傳送配置的變更請求,master 把配置更新後,其內部的 config hash 也會變化。其它 client、worker 等與 Alluxio Master 連線的服務會週期性與master 同步config hash,也會感知到配置變化,從而同步變化的配置。
- 在 Alluxio fuse client 端,針對業務的這種幾乎全讀場景,開啟 kernel cache 和 Alluxio client 端的 metadata cache 進一步提升提升讀效能, 同時對於 metadata cache 的也做了優化, 例如當底層儲存元資料改變了,可以主動 invalid metadata cache,重新cache,增加靈活性。另外,對 Alluxio FUSE 開啟 LocalCache 後,出現的若干bug進行了修復。
- 增加 master 訪問繁忙度指標、ratis 指標、OS、JVM、GC、快取命中率等等許多有價值的指標,豐富了Alluxio的指標系統。
- 開發檢視 Alluxio 關鍵程序的 stacks 功能, 方便我們跟蹤叢集狀態。
- 充分利用distributedLoad預熱功能,期間修復了 Alluxio Job Service 在執行大量 distributedLoad 時出現 OOM 的問題。
配置優化
- worker block 副本數的調整, Alluxio 預設打開了被動快取功能alluxio.user.file.passive.cache.enabled=true,客戶端如果發現數據塊不在本地 worker, 則會從遠端 worker 拷貝副本到本地,每個 worker 要儲存很多副本。這個配置在 1000 個 worker 規模的場景下,會給 Alluxio master 增加巨大的元資料壓力,而測試結果表明,這種本地性帶來的效能收益實際上很小,因此關閉了這個配置,減輕 master 的壓力。
- 使用騰訊內部 kona jdk11,並對 master, worker 的 jvm 引數進行了調優,運行同樣 workload,使用 konajdk11 + g1gc 沒有過出現因為 fullgc 導致的 leader master 切換問題。
- 通過騰訊 jvm 團隊的幫助下,我們定位了 auditlog 開啟成為了我們純讀場景的瓶頸,通過設定 alluxio.master.audit.logging.enabled=false 關閉審計日誌後,吞吐提升7 倍。通過 kona-profiler 抓取的火焰圖,發現了使用 ROCKSDB 的元資料管理方式會增加效能開銷,下一步我們計劃將Alluxio 改用 HEAP 元資料管理方式。
對比測試
我們將某 moba 遊戲,特徵計算業務分別對接 Alluxio(UFS為cephfs)和 cephfs 進行對比測試。測試中 Alluxio 的叢集資訊如下:
- alluxio master: 3 個 master 的 High Availability 方式部署。
- alluxio worker: 1000個 worker, 約 4TB 的儲存空間。
- 業務 pod: 1000個,每個 pod 是4個核的並行任務。
- 測試業務:某 moba 遊戲 AI 特徵計算任務(包含 250000個對局)。
從測試結果看,兩個方案都能滿足業務的需求,失敗率均在可接受範圍內,使用Alluxio + cephfs 的方案後,業務的失敗率更低。
觀察Alluxio 和 cephfs 的元資料壓力指標(rpc count 和 mds 的 qps), 在任務初期會有一個衝擊,之後 master 元資料壓力逐漸降低。在使用Alluxio 來承接業務的情況下,ceph mds 的 qps 幾乎為 0,說明 Alluxio 抵擋了大部分業務壓力。
通過 Read Remote, Read UFS, Read Domain 指標觀察資料的本地性,可以看到,Remote Read 和 Read Domain 佔主要部分, 大部分讀流量是 worker 之間的遠端讀以及本地domain socket讀,從 UFS 讀的情況非常少。
上圖為使用了 kona jdk11 後任務執行過程中的heap memory 變化曲線,kona jdk11, 在之前使用官方版本時, master 會出現因為 gc 時間過長,導致 leader 切換問題,在更換 kona jdk11 之後,這種現象沒有發生, master 更平穩。
未來工作
吞吐上限提升
目前 Alluxio master 在 7000 核併發壓力,已經發現 master 的 callqueue 有積壓,而且通過 masterStressBench 工具壓出每秒接近 21 萬次 rpc 請求的吞吐能力,需要突破上限,最終希望能夠提供業務 20000 核的併發。
為了實現 alluxio 叢集支援 業務無止境的併發訪問要求,只做單叢集的調優是不夠的,還需要設計能夠支援更高併發訪問的整體架構。
利用 Alluxio CSI 解耦業務和 Alluxio FUSE
目前 Alluxio FUSE 是以 sidecar 的形式和業務位於同一個 pod,這樣業務方可以獨立維護 業務 pod 以及對應的 yaml,需要和業務團隊共同管理業務 pod 中的業務容器和 Alluxio-FUSE 容器。
建設 kubernetes 上的 Alluxio 叢集管理系統
我們基於 Alluxio 提供的 helm chart 模板,維護了一套用於運維 Alluxio 叢集的方案,但是我們希望更進一步,基於kubenetes API,可以操作每一個 pod 和容器,可以互動式執行需要執行的命令,基於此,我們可以實現底層儲存mount、umount 操作, job service 視覺化管理,load free 服務化建設。
總結
在 Alluxio 與遊戲 AI 特徵計算業務落地過程中,我們支援了業務側 4000 核併發的穩定執行,從使用效果上看,Alluxio 為底層分散式儲存抵擋了絕大部分元資料壓力,任務的失敗率降低到業務比較滿意的範圍。另外,業務的高併發大規模場景也暴露出 Alluxio 核心的諸多問題,我們也全部貢獻到 Alluxio 開源版本里,同時也增強了 Alluxio 核心的穩定性和可運維能力,可以在未來適配更多場景落地。
- 萬字長文!深度剖析《資料安全法》下多方資料協同應用和隱私計算髮展趨勢
- 智慧計算時代 | SuperSQL基於監督學習模型的自適應計算提效能力
- 新版本釋出:Apache InLong(incubating) 進入1.0 時代
- Firestorm 0.2.0釋出:首個支援混合儲存的開源Remote Shuffle Service
- Firestorm - 騰訊自研Remote Shuffle Service在Spark雲原生場景的實踐
- 騰訊內部實踐分享 | 千節點Alluxio 叢集助力遊戲 AI 業務
- 騰訊內部實踐分享 | 千節點Alluxio 叢集助力遊戲 AI 業務
- 自研Java協程在騰訊的生產實踐
- 聯邦學習在騰訊微視廣告投放中的實踐
- 騰訊Angel Graph團隊重新整理GNN最強榜單OGB世界紀錄!
- 北大騰訊聯合共建Angel4.0,自研深度學習框架“河圖”融入生態
- Angel 3.2.0新版本出爐!圖計算能力再次加強
- Hadoop Ozone如何巧妙利用Multi-Raft機制優化資料節點吞吐量