好的數(shù)據(jù)編排怎么做?平安壹錢包大數(shù)據(jù)重構(gòu)實踐
一、Alluxio 介紹
1、背景介紹
當前計算引擎越來越多樣化,存儲系統(tǒng)和部署環(huán)境也越來越復雜。不同的計算和存儲適用于不同的場景。比如 Presto 的即席查詢性能比較好,比 Spark 要快很多,而 Spark 又更適合于批量處理。存儲系統(tǒng)也是一樣的,常用的 HDFS 是一個可以存取海量數(shù)據(jù)的存儲系統(tǒng),但有些場景下又希望能夠使用存儲密度更高的存儲系統(tǒng)。與此同時,部署方式也在不斷變化,比如之前一般使用的是 CDH,將來可能會用 Ambari 這樣一個開源的方式,還可能會考慮使用容器化的部署,為將來的云化做一個鋪墊。
環(huán)境的日趨復雜化,帶來了很多問題與挑戰(zhàn)。比如我們在實踐過程中,為了建設數(shù)據(jù)湖倉,必須要引入 Iceberg,但是已有的 HDFS 是 2.6.x,Spark 是 1.6.x,對 Iceberg 是不支持的。為了引入 Iceberg,HDFS 要升級到 3.x,Spark 也要升級,才能建設成一個整體。
在這樣一個過程中,我們面對了四點比較突出的問題:
- 高耦合:計算引擎與存儲系統(tǒng)已經(jīng)形成了一個整體,任意一方的升級或者變更,都意味著需要重新考慮兼容性的問題。
- 難迭代:計算引擎需要使用不同 API 去訪問不同的存儲系統(tǒng),數(shù)據(jù)的跨存儲系統(tǒng)遷移往往需要兼顧計算機應用,甚至需要重新開發(fā)。
- 難遷移:從本地集群的部署方式平滑遷移為云部署的難度高,不僅維護成本高,還很難適應混合云環(huán)境。
- 持續(xù)性的迭代壓力:任何方案都會過時,想要追逐技術前沿,就需要面對持續(xù)性的迭代壓力。
2、數(shù)據(jù)編排概覽
Alluxio 是一種基于數(shù)據(jù)編排技術的開源組件。
數(shù)據(jù)編排技術是位于存儲層與計算層之間的一個抽象層。它可以將復雜多樣的底層存儲進行包裝,向上提供統(tǒng)一的訪問路徑,兼容多種訪問協(xié)議,以應對多樣化的存儲需求與應用計算之間的矛盾。為數(shù)據(jù)驅(qū)動的應用程序提供數(shù)據(jù)可訪問性、數(shù)據(jù)本地性和數(shù)據(jù)可伸縮性。
Alluxio 可以帶來如下一些好處:
- 標準 API
Alluxio 可以跨存儲系統(tǒng)將數(shù)據(jù)訪問抽象出來,計算引擎只需使用標準 API 就可以訪問不同存儲系統(tǒng)中的數(shù)據(jù)。
- 解耦計算與存儲
Alluxio 允許掛載多個不同的存儲系統(tǒng)以及不同版本的相同存儲系統(tǒng),解耦計算與存儲,方便存儲系統(tǒng)的升級和引入過程。
- 緩存
Alluxio 具有緩存功能,加速訪問熱數(shù)據(jù)。
- 云原生
Alluxio 是云原生的,可以在任何云中快速搭建數(shù)據(jù)編排層。
Alluxio 為數(shù)據(jù)驅(qū)動型應用和存儲系統(tǒng)構(gòu)建了橋梁,使得應用程序能夠通過一個公共接口連接到多種存儲系統(tǒng)。與此同時,Alluxio 內(nèi)存至上的層次化緩存架構(gòu)使得數(shù)據(jù)的訪問速度比現(xiàn)有方案快幾個數(shù)量級,非常適合 IO 成為瓶頸的存算分離場景。
Alluxio 的最上層是計算層,最底層是存儲層,中間是數(shù)據(jù)編排層。計算層通過多種標準數(shù)據(jù)訪問 API 來訪問數(shù)據(jù)編排層。編排層負責對多種存儲系統(tǒng)的訪問。
3、Alluxio 架構(gòu)設計
計算應用通過 Alluxio Client從Alluxio Master 獲取 AlluxioWorker 節(jié)點與默認配置,并與 Worker 建立連接進行數(shù)據(jù)讀寫。在這個過程中,Alluxio Client 會將計算應用的 API 進行自動轉(zhuǎn)換,讓整個過程對于計算應用是透明的。
Alluxio Master 基于 zookeeper 或者內(nèi)嵌的 Raft 服務實現(xiàn) HA,并負責維護默認配置、協(xié)調(diào) Worker 節(jié)點、接收請求、塊位置等工作。
Alluxio Worker 的職責包括:
- 跨存儲系統(tǒng)的數(shù)據(jù)讀寫:Alluxio Worker 主要負責與底層存儲系統(tǒng)進行交互,它不僅實現(xiàn)了不同存儲系統(tǒng)的 API,還可以自動轉(zhuǎn)換,實現(xiàn)了跨存儲系統(tǒng)的數(shù)據(jù)讀寫。
- 多級緩存:Alluxio Worker 維護了一個多級緩存,用以加速熱數(shù)據(jù)的訪問,減少讀取底層存儲的次數(shù)。而基于塊注釋的緩存設計,不僅可以為熱數(shù)據(jù)提供最佳性能,還能在緩存空間不足時自動釋放較冷的數(shù)據(jù),以非常自然的方式實現(xiàn)了數(shù)據(jù)的冷熱分離。
- 訪問短路:當計算應用與 Alluxio Worker 處于同一節(jié)點時,還可以直接通過 NIO 進行短路交互,進一步優(yōu)化數(shù)據(jù)的訪問鏈路,減少響應時間。
- 彈性部署:Alluxio Worker 在啟動時會主動向 AlluxioMaster 注冊自己,并通過心跳機制維持存在,而基于數(shù)據(jù)易失性的設計,可以讓用戶根據(jù)需要,靈活的進行水平拓展或者縮容。
4、Alluxio 核心功能
(1)統(tǒng)一命名空間
- 靈活掛載
Alluxio 的根掛載點需要在啟動時指定,綁定 Alluxio 的根目錄。嵌套掛載點則可以在任意 Alluxio 子目錄上通過命令行指定。嵌套掛載點的數(shù)量沒有限制,可以分別掛載不同的存儲系統(tǒng),或者相同存儲系統(tǒng)的不同版本。 - 訪問控制
用戶通過 Alluxio 訪問底層存儲時,只能訪問掛載在 Alluxio 上的目錄,同時 Alluxio 也可以將掛載點設定為 read-only,進一步限制用戶對底層存儲的訪問。這是區(qū)別于用戶權(quán)限管理的強制限制。 - 訪問透明
用戶通過 Alluxio 訪問底層存儲時,并不需要感知底層存儲系統(tǒng)的類別、版本,也不需要關注掛載點(某些情況除外)。在大部分場景中,通過 Alluxio,用戶可以無感知地訪問掛載其上的底層存儲。
(2)緩存
- 緩存讀寫策略
讀:NO_CACHE(Alluxio 僅作為代理,不做緩存),CACHE_PROMOTE(盡量放到緩存最上層),CACHE。
寫:THROUGH(Alluxio 僅作為代理,不做緩存),CACHE_THROUGH(寫入存儲時備份到緩存空間中,適合于寫入后還需要讀的場景),ASYNC_THROUGH(異步寫),MUST_CHACHE(僅寫入緩存空間)。 - 緩存管理
塊注釋策略:根據(jù)塊注釋策略為數(shù)據(jù)塊進行排序,位于序列尾部的數(shù)據(jù)塊將作為優(yōu)先的空間釋放對象。
最少最近策略
基于權(quán)重的最少最近策略
緩存分層:數(shù)據(jù)塊可能已配置存儲層中,基于塊注釋策略,Alluxio 會在各存儲層中移動數(shù)據(jù)塊,包括塊對齊、塊升級、遷移任務退后等。
緩存驅(qū)逐:當 Alluxio 的存儲空間不足時,無法接受新數(shù)據(jù)的寫入,會基于注釋策略釋放存儲空間,這個過程叫做緩存驅(qū)逐。它保證了 Alluxio 總是存儲著熱數(shù)據(jù),但也會在某些場景下造成緩存命中率降低的問題。 - 緩存生命周期
數(shù)據(jù)操作:LOAD(加載數(shù)據(jù)到緩存空間),PERSIST(緩存空間中的數(shù)據(jù)回寫到底層存儲),F(xiàn)REE(只清除緩存空間中的數(shù)據(jù),不動底層存儲數(shù)據(jù)),DELETE(緩存空間和底層存儲的數(shù)據(jù)都清除)
TTL:Alluxio 可以為文件和目錄設置生存時間,當生存時間到達時,執(zhí)行一種數(shù)據(jù)操作,默認為 DELETE。這樣可以對緩存空間進行策略化管理。
元數(shù)據(jù)同步:Alluxio 可以為文件和目錄設置元數(shù)據(jù)檢查周期,當緩存過期時,會自動從 UFS 重新加載。如果每次訪問都同步底層存儲,開銷會比較大,因此可以根據(jù)應用場景進行定制。如果對數(shù)據(jù)時效性比較敏感,底層存儲的任何更新,在通過 Alluxio 去訪問時都希望能感知到,這時就可以設置每次讀之前同步元數(shù)據(jù)。而大多數(shù)情況下,對數(shù)據(jù)時效性沒有那么敏感,那么就可以根據(jù)需要設置同步的時間間隔。
二、Alluxio 實踐分享
1、長鏈計算任務的遷移需要兼顧上下游依賴關系
建設湖倉一體化,不可避免的一個問題就是如何去做數(shù)據(jù)遷移,以及生成這個數(shù)據(jù)的長鏈任務的遷移。如果沒有數(shù)據(jù)編排層去做遷移,需要兼顧上下游的數(shù)據(jù)關系。有了編排層,如圖所示,首先將舊集群中的數(shù)倉和新的湖倉進行元數(shù)據(jù)同步,可以看到舊的數(shù)倉和新的湖倉均含有兩張表,但實際上從底層來看,這兩張表的數(shù)據(jù)只維護了一份,好處是不需要在兩個集群里面都維護相同的數(shù)據(jù),減少了存儲的壓力,同時可以避免數(shù)據(jù)不一致的問題。通過 Alluxio 將元數(shù)據(jù)同步,做遷移時就可以只遷移該任務所依賴的數(shù)據(jù)本身,這樣任務遷移就變得非常靈活。
2、利用高速的緩存空間加速數(shù)據(jù)的讀寫
在加速場景里面,我們根據(jù)不同的應用場景,使用不同的 Alluxio 集群。
- 將 Trino 和 Alluxio 混合部署在 SSD 集群上(混合部署時性能最佳),利用 Alluxio 緩存空間加速熱數(shù)據(jù)的加載。
- 對于熱度不高的數(shù)據(jù)也可以通過直連底層存儲進行訪問。
- Spark shuffle 加速主要基于 Spark RSS 這邊的接口,每個公司使用不同的產(chǎn)品,Alluxio 集群可以整合空閑的內(nèi)存或是零散的 SSD 空間,把這些空間充分地利用起來。
- 利用 Alluxio 可以將 RSS 產(chǎn)生的 IO 占用限制在指定集群、節(jié)點或者磁盤上,減少集群的 IO 競爭帶來的任務時長波動。
3、提供數(shù)據(jù)本地性,將需要單點部署的應用與大數(shù)據(jù)存儲直接連通
(1)痛點:
- 有些 AI 計算需要部署在裝有 GPU 的特定機器上,與大數(shù)據(jù)集群環(huán)境天然隔離;
- 算法工程師需要學習并實現(xiàn)特定存儲系統(tǒng)的 API 才能去讀寫數(shù)據(jù);
- 部分計算應用需要將原始數(shù)據(jù)拉取到本地才能進行計算,但是本地節(jié)點的磁盤空間有限。
(2)優(yōu)化:
- Alluxio 支持 POSIX API,它可以直接 mount 到本地節(jié)點的目錄上,連通大數(shù)據(jù)存儲與本地節(jié)點。
- 算法工程師可以像讀寫本地文件一樣讀寫大數(shù)據(jù)存儲上的數(shù)據(jù),而不必關注遠端存儲系統(tǒng),從而節(jié)省學習和開發(fā)成本。
- 為本地節(jié)點提供集群級別的存儲空間,并提供最高內(nèi)存級別的數(shù)據(jù)讀寫速度。
4、兩種實現(xiàn)冷熱分離的架構(gòu)
Alluxio 實現(xiàn)冷熱分離有兩種方式,一種方式是可以在存儲層做冷熱分隔。如果一個集群性能比較高,主要是熱數(shù)據(jù),另一個集群數(shù)據(jù)都是冷數(shù)據(jù),但是存儲密度高。當數(shù)據(jù)變冷時,需要人工將數(shù)據(jù)從高性能的集群遷移到高存儲密度的集群,從而實現(xiàn)冷熱分離,這樣對于上層應用不太友好,底層數(shù)據(jù)在遷移的時候,目錄、命名空間不一樣,用 Alluxio 就可以避免這些問題。在此過程中 Alluxio 僅需要作為一個代理,不需要緩存空間,僅需要滿足 IO 計算。這種方式對 Alluxio 本身的緩存能力沒有很高的要求。
第二種方式是利用 Alluxio 直接做一個上下層的冷熱分離,在此過程中 Alluxio 作為編排層,直接放熱數(shù)據(jù),存儲層直接放冷數(shù)據(jù)。冷數(shù)據(jù)可以通過預加載的方式暖起來,把數(shù)據(jù)寫進緩存空間。這種方式需要 Alluxio 提供一個較大的緩存空間。
實踐中,我們綜合使用了兩種方式。整體上是以第一種方式為主,我們有一個高性能的集群和一個高存儲密度的集群。與此同時,也為 Alluxio 配置了一些緩存空間,來進一步提升性能。
5、大數(shù)據(jù)架構(gòu)演變
Alluxio 帶來的大數(shù)據(jù)架構(gòu)演變過程如上圖所示。
- 引入Alluxio,實現(xiàn)緩存加速。
- Alluxio 掛載多個存儲系統(tǒng),助力存儲升級和數(shù)據(jù)遷移,數(shù)據(jù)在邏輯層面實現(xiàn)存算分離。
- 將計算應用做容器化改造,與 Alluxio 一起遷移到 K8s 中,完全實現(xiàn)存算分離,具備上云的條件。
- 根據(jù)業(yè)務需求,為不同的計算應用單獨定制 Alluxio 集群,滿足個性化需要。
三、展望
最后來分享一下未來的規(guī)劃。
1、更輕:輕量部署無負重
通過引入 Alluxio,我們可以將計算應用與存儲系統(tǒng)解耦,進而減少大數(shù)據(jù)架構(gòu)迭代的難度和成本。Alluxio 的部署已經(jīng)足夠靈活簡單,但我們?nèi)匀幌M懈p量、更無侵入的部署方式或配置項:
- 更靈活的邏輯域名配置項,避免修改 core-site.xml
- 客戶端級別的可配置化的訪問映射,避免修改 HMS
- 集成度更高的服務端進程
2、更快:讓快變得更快
通過利用 Alluxio 的緩存空間,計算應用可以獲得最高內(nèi)存級別的讀寫加速,并減少與底層存儲的 I/O 吞吐,獲得全方位的數(shù)據(jù)加速體驗。但在復雜的部署環(huán)境中,我們希望獲得一些新的特性,讓快變得更快。
- 更豐富的緩存請求分配策略(例如給 LocalFirst 增加備選策略)
- 跨集群數(shù)據(jù)讀寫的 I/O 限流
- 基于客戶端的 UFS 讀寫(例如客戶端從 worker 獲取掛載信息和配置后自己去讀)
3、更穩(wěn)定:穩(wěn)定可靠控風險
通過引入 Alluxio,我們將存儲系統(tǒng)置于更底層,由 Alluxio 與計算應用進行交互,這帶來了許多穩(wěn)定性上的好處,例如審計日志、Metrics、訪問控制等等,但也帶來了一些新的挑戰(zhàn),等待我們?nèi)ヌ剿鞲€(wěn)定的集群環(huán)境:
- 基于 tag 或者用戶組的緩存配額
- AlluxioWorkerJVM 與 RAM 緩存的內(nèi)存統(tǒng)一
- 本地緩存數(shù)據(jù)的故障載入