近年來,基於雲原生架構的新一代訊息佇列和流處理引擎 Apache Pulsar 在大資料領域發揮著愈發重要的作用,其應用場景和客戶案例也在不斷地豐富與擴充。
火山引擎是位元組跳動的企業服務品牌,主要面向 To B 業務場景。火山引擎中 Stateless 雲原生開源大資料平臺 E-MapReduce(簡稱 EMR)為使用者提供了雲上的端到端的大資料解決方案。與此同時,Apache Pulsar 的一個十分重要的特性也是雲原生。先進的存算分離的架構使其非常適合在雲化的環境中部署、運維,而 Topic 資料的儲存方式也使其擴容操作大為簡化,不需要資料的 rebalance 過程。於是,將 Pulsar 整合到火山引擎 EMR 的生態系統中便是一件水到渠成且極具價值的事情。
本文介紹火山引擎 EMR 中 Apache Pulsar 的整合情況和應用場景,按照如下結構來編排:
業務背景
詳解Apache Pulsar 在EMR的整合方案;
Apache Pulsar 典型應用場景、問題與解法;
火山引擎 EMR 整合 Pulsar 的未來規劃。
一、業務背景
火山引擎是位元組跳動旗下的雲服務平臺,將位元組跳動快速發展過程中積累的增長方法、技術能力和工具開放給外部企業,提供雲基礎、影片與內容分發、數智平臺 VeDI、人工智慧、開發與運維等服務,幫助企業在數字化升級中實現持續增長。
火山引擎 EMR 是火山引擎資料中臺產品體系的基座。資料中臺是火山引擎中的一類重要產品,服務於使用者的大資料體系,支撐使用者構建端到端的資料鏈路。火山引擎資料中臺產品體系如下圖所示。
資料中臺的大資料生產、服務體系,資料來源於交易系統、日誌、IoT、訊息、檔案等,透過資料整合進入到資料湖中,然後經過資料開發、治理過程,進入到專題集市,最後透過資料分析平臺提供給資料的終端使用者,包括 BI 報表、離線分析、實時分析、即席查詢、資料探勘等。以上是使用者搭建大資料體系的一條完整的資料鏈路。在這條資料鏈路上的各個環節都有火山引擎資料中臺的產品來對接。火山引擎 EMR 產品在資料中臺整個的產品體系全景圖中,處於基座的位置(如上圖中黃色框所示),對於使用者構建端到端的資料鏈路起著重要的支撐作用。火山引擎 EMR 基於火山引擎的 IaaS 能力,提供底層基礎的大資料體系的計算引擎和儲存引擎,並向上對接資料開發治理工具 DataLeap。
如果用一句話來定義火山引擎 EMR 這個雲產品,那就是“Stateless 雲原生開源大資料平臺”。使用者可以在 EMR 產品中建立自己的叢集,並使用 EMR 叢集中配置好的服務,進行大資料的計算與儲存。
這裡重點分析一下火山引擎 EMR 產品定義中的幾個關鍵詞。雲原生、開源、大資料平臺這些概念相信都是讀者們耳熟能詳的。
雲原生是指雲上資源的池化、使用者的彈性按需使用、資源的成本攤薄和利用率提升等。開源大資料平臺則是 EMR 這類雲產品的共有定義。接下來重點講一下 Stateless 這個概念。
Stateless 指的是“無狀態”。在 EMR 中建立的使用者叢集的“狀態”指的是什麼呢?以有狀態場景下的 Hadoop 叢集型別為例,叢集的狀態包括使用者的 HDFS 中的資料(屬於使用者的核心資料資產)、Hive Metastore 中的後設資料、Ranger 中的許可權配置、各個服務的日誌、歷史作業執行統計資訊、叢集的配置資訊等等。這些狀態資訊都是儲存在使用者叢集內部的,是使用者叢集的一部分。在這樣的情形下,使用者的叢集是一個有狀態的(Stateful)叢集。在 EMR 的場景下,狀態資訊無處不在,叢集內部包含大量狀態資訊並不稀奇,且這些狀態資訊的量級較重。
然而,使用者叢集富含狀態資訊,會給使用者帶來額外的一些成本和困擾。例如,如果使用者想升級自己的叢集版本,或者對自己的叢集做一些其他的運維操作(例如服務的啟停、執行定製化的運維指令碼等),就會有一些顧慮:使用者的資料、後設資料、配置等資訊都在叢集內部,在執行叢集升級或運維操作的時候,會不會對叢集內部的狀態資訊造成影響。事實上,如果狀態資訊內建在使用者叢集內部,使用者在對叢集進行運維操作的時候,是需要做仔細的評估的,確保運維操作不會對叢集內部的狀態資訊產生預期外的影響。這會給使用者對叢集的運維操作帶來額外的顧慮和成本。
從上面的討論不難看出有狀態的叢集會給客戶帶來一系列痛點問題,而火山引擎的 Stateless 的 EMR 叢集則針對以上問題,為使用者提供瞭解決方案。如果我們把叢集的資料、後設資料、配置、歷史作業資訊等狀態透過一些方案放置在使用者叢集的外部,而在使用者叢集的內部不再持有狀態資訊,這樣使用者的叢集就是一個無狀態的叢集,此時使用者如果需要對叢集執行升級或者其他運維操作,就不會有“叢集狀態資料受影響”相關的顧慮了,減少了運維的風險與成本。
在 Stateless 叢集的場景下,使用者甚至可以選擇按需去持有叢集,即:需要使用計算資源的時候,建立一個叢集;不需要使用計算資源的時候,將叢集釋放。例如如果使用者的資料生產 ETL 作業集中在凌晨執行,那麼可以在當日的資料生產任務執行前將叢集建立出來,然後用這個叢集執行一系列的 ETL 作業,而在所有作業都成功執行完成後,再把這個叢集釋放掉。而到第二天凌晨,新一輪的資料生產作業執行之前,再建立出一個叢集,待資料生產完成後再釋放叢集。如此迴圈往復。這樣使用者可以只為叢集真正被使用的那段時間付費,而在不需要使用叢集的時段,使用者不需要持有叢集,不存在使用者持有的資源閒置的問題,使用者也就不需要為閒置資源付費。這樣可以給使用者帶來極大的成本最佳化,並提升雲上資源的利用率。Stateless 的EMR 叢集為這樣的使用方式提供了可能。
上面介紹了火山引擎 EMR 的核心定義。針對火山引擎 EMR 的核心功能,進一步展開講一下,就是提供了企業級的大資料生態元件,例如:Hadoop、Spark、Flink、Hive、Presto、Kafka、ClickHouse、Hudi、Iceberg 等,100% 開源相容,快速構建企業級大資料平臺,降低運維⻔檻。
火山引擎 EMR 的核心特性包括以下幾點:
開源相容 & 開放環境:大資料元件來自開源社群,與開源版本相容。EMR 提供半托管的環境。EMR 託管在火山引擎的基礎設施之上,透過管控面將使用者在控制檯上的操作傳遞到使用者叢集內部。但是這個意義上的託管並不是“全託管”,而是“半托管”——使用者有足夠的自主性、靈活性,可以登入到自己叢集的節點的命令列環境中,執行靈活的運維操作,如指令碼執行、軟體安裝與部署等,以滿足使用者的個性化需求。也就是說,“半托管”一方面可以透過雲託管、白屏化來解決使用者實際運維中的痛點問題,降低使用者的運維成本,另一方面又不失靈活性,使用者可以自主控制自己叢集內的節點,有極大的自由度。
Stateless 雲原生湖倉:Stateless 的概念在上文已有詳述。火山引擎 EMR 透過存算分離把叢集內部的資料外接到雲端儲存中,如火山引擎物件儲存 TOS,不再依賴使用者叢集內部的 HDFS。此外,透過外接 Hive Metastore、Public History Server、作業管理、配置中心等產品和技術方案,進一步把叢集內部的狀態資訊外接。另外,透過彈性伸縮,支援使用者在雲上合理地調配資源,實現資源利用的最大化和成本的節約。Stateless 的架構也使得彈性伸縮的擴縮容過程更加輕量化,運維成本和風險得以降低。另外,火山引擎 EMR 也支援 Lakehouse(湖倉)這一近年來興起的資料開發理念。
引擎企業級最佳化:可以分兩方面來看。一方面是火山引擎 EMR 針對開源的大資料元件在功能和效能上做了一些增強,後續也會將一些增強回饋社群。另一方面是給引擎增加了一些企業級的特性,例如許可權相關的功能。
雲上便捷運維:複用了雲上 EMR 的通用的管控底座能力,各個型別的叢集的建立等操作複用 EMR 的公共管控底座。支援按量付費和包年包月的計費模式。支援叢集的按需建立和釋放。支援叢集內服務的操作、引數配置、監控、報警、日誌等運維能力。使用者在購買 EMR 後可以直接在控制檯對接使用這些功能,開箱即用,十分方便。使用者可以把大量的運維操作交給雲,或者藉助雲上提供的能力大大降低使用者的運維成本。很多原本需要透過命令列和運維流程操作的運維動作,在火山引擎 EMR 中可以透過控制檯介面白屏操作。這樣使用者可以專注於自身的業務邏輯、增長邏輯,而把大資料平臺的構建和運維交給雲平臺。這也是雲上的 EMR 產品能夠給使用者提供的核心價值之一。
下圖為火山引擎 EMR 的功能架構圖。
火山引擎 EMR 建構在火山引擎的基礎設施底座上,由火山引擎提供雲伺服器、公網 IP、雲端儲存、VPC 等基礎設施。在基礎設施底座上,建構出資料儲存引擎(如 HDFS、CloudFS、表格式等)、資料排程引擎(如 YARN 等)、各種面向不同場景的大資料計算、儲存元件以及貫穿整個 EMR 服務端到端的管控面。EMR 向上可以對接火山引擎的大資料研發治理套件 DataLeap,支援使用者構建資料倉儲,賦能百行百業,助力企業決策,幫助業務成長,體現資料價值。
從 EMR-1.3.0 版本開始,火山引擎 EMR 支援 Pulsar 叢集型別的建立。下面我們來具體看一下火山引擎 EMR 整合 Apache Pulsar 的情況。
二、Apache Pulsar 在EMR的整合方案
本節內容重點討論 Apache Pulsar 整合火山引擎 EMR 的原因和方案。
火山引擎 EMR 是一個雲上的大資料平臺,覆蓋大資料開發領域各個場景,包括離線計算、實時計算以及儲存、資料排程、工具鏈等。
除此之外,還有一類元件不可或缺的,即訊息佇列,至少有兩類不同的場景依賴訊息佇列:
第一個場景是資料攝入(Data Ingestion),即從業務系統(也就是整個 大資料 體系的外部)把源頭資料接入到大資料體系中,涉及到一個資料從業務系統向大資料體系傳輸的過程。
以客戶端埋點日誌為例,埋點日誌被上報到訊息佇列,該訊息佇列為大資料鏈路的第一站。從該訊息佇列開始,資料會繼續向下遊的離線 Hive 表或者實時數倉的下游訊息佇列流動。在此場景下,作為整個大資料體系的源頭,訊息佇列連通業務系統和資料倉儲,將大資料體系外面的資料上報到訊息佇列後,訊息佇列作為一個溝通的紐帶,訊息會流向下游的資料倉儲的各層儲存中,進入大資料體系內部。
不光是埋點日誌資訊,使用者的業務資料庫的資訊,也可以透過把資料庫 binlog 上報到訊息佇列,由計算任務消費訊息佇列中的 binlog 並把資料寫入下游表,實現業務資料庫的資料向數倉的同步,在數倉中重建出業務庫的副本。
此外,像監控、日誌型別的資料也可以上報到訊息佇列,再透過訊息佇列將對應的資料傳導到大資料體系的內部。
第二個典型應用場景是 實時數倉 。
資料接入到資料倉儲後,可以繼續透過 ETL 過程構建離線表,也可以構建實時資料鏈路,使用實時處理邏輯將資料寫到下游的訊息佇列中,而這個訊息佇列可以再進入下一級的實時處理邏輯,或做 mapping,或做聚合,進入到下一級的訊息佇列中。
以上訊息佇列相當於實時數倉的實時表,存放 ODS、DWD、DWS、ADS 等層級的實時數倉資料。在這裡,是使用訊息佇列作為實時數倉各層資料的儲存。
在最終資料應用的時候,根據應用場景的實際需要和查詢特點,可以將實時數倉訊息佇列中的資料匯出到像 Redis 這樣的 K-V 儲存中,或者像 StarRocks、Doris、ClickHouse 這樣的 OLAP 引擎中。
實時數倉的資料鏈路的中間層依賴訊息佇列的,因為實時資料的處理主要是流處理,而訊息佇列的儲存與計算模式與流處理的模式是天然契合的。
從上面的討論可以看出,訊息佇列至少在資料接入和實時數倉中間層兩個大資料體系的場景中扮演著不可或缺的作用,因此是大資料體系離不開的一類元件。所以火山引擎 EMR 將訊息佇列整合進來也就成為了一件水到渠成的很自然的事情了。
而在訊息佇列領域中,近年來發展迅速、表現優異、備受關注的一個佼佼者便是 Apache Pulsar。以上是我們選擇將 Apache Pulsar 整合到火山引擎 EMR 的原動力之一。
當然除了這一點之外,還有以下的一些其他的原因。讓我們來看一下 Apache Pulsar 的基本情況,以及一些核心的特性和優勢。正是這些特性和優勢,促成了我們將 Apache Pulsar 整合到火山引擎 EMR 中,並相信這樣做會給使用者帶來很大的價值。
Apache Pulsar 是一個開源的基於釋出 / 訂閱模式的分散式、雲原生、多租戶的高效能訊息與流平臺,提供訊息佇列和計算服務,解決伺服器間的訊息傳輸與佇列問題。
Pulsar 具有很多令人矚目的特性和優勢,下面選取了其中的一部分,主要是與把 Pulsar 整合到 EMR 最相關的一些關鍵要素。正是這些關鍵要素,使得我們相信把 Pulsar 整合到火山引擎 EMR 中確定會給使用者帶來很大的價值。這些關鍵要素列舉如下:
彈性:支援使用者無感知的動態擴縮容,提供更好的彈性,為使用者節省硬體成本,更好地契合了雲上產品的特徵。這是雲上產品的基礎特性,也是一個產品想要上雲所需要具備的特性,能夠給客戶帶來上雲的實際價值。
雲原生:採用先進的雲原生架構,將有狀態的儲存與無狀態的計算分離在不同的架構層級中,非常適合在雲化的基礎設施中部署、使用和運維。這個也是被大家常常提到的 Pulsar 的核心特性,無論是基於 Kubernetes 部署,還是透過 Bare metal / ECS 部署,都可以利用到存算分離的架構特點,更好地利用雲上資源池化、彈性的特點,實現更好的雲原生。
易擴容:存算分離以及資料的分散儲存的架構特點極大減少了使用者對計算或儲存能力進行擴容時的成本與風險,使用者可以對計算或儲存節點分別擴容,特別是在擴容的時候不需要做繁重的資料遷移、rebalance,對系統的可用性、穩定性、可運維性和運維成本最佳化大有裨益。這也是大家津津樂道的 Pulsar 的一個非常令人矚目的優秀特徵。
與使用者既有系統(如 Kafka)相容:透過 KoP (Kafka on Pulsar),提供與 Kafka 的在使用層面上的相容性,便於使用者直接複用已有的基於 Kafka 的程式碼體驗 Pulsar 的特性。這一點也是非常重要的,能夠帶來很大的使用者價值。Kafka 也是非常流行且在業內被廣泛使用的一個訊息佇列元件,使用者可能也會有很多基於 Kafka 開發的業務程式碼。如果使用者希望把這些業務程式碼在 Pulsar 上面進行試用與體驗,那麼如果 Pulsar 與使用者既有的一些系統(如 Kafka)相容,就可以零成本或者低成本地把既有的業務程式碼放到 Pulsar 上來體驗,更易於使用者去體驗 Pulsar 的各種令人矚目的特性和功能。這一點對使用者的價值很大。假設 Pulsar 沒有提供與 Kafka 協議的相容性,那麼如果使用者想體驗 Pulsar,把既有的一些程式碼放到 Pulsar 上面試用、體驗,可能需要對既有業務程式碼做一些修改、適配和遷移,這些工作也是有成本的,且遷移工作能夠給使用者在業務層面帶來的價值有限,只是相當於在技術實現層面把程式碼進行了系統之間的遷移和適配,但是會給使用者帶來一些痛點和運維成本。所以如果能夠做到和使用者既有系統的相容,可以幫使用者省去一些很繁重的遷移工作,會帶來很大的使用者價值。
基於以上這幾點, Pulsar 可以很好地為客戶提供價值、增值,這也促成Pulsar 整合到火山引擎 EMR 中。
下面針對上文中提到的 Pulsar 的雲原生架構和易擴容的特性,再展開講一下技術細節。
Pulsar 的雲原生架構,如下圖所示:
具體來講,有以下幾點要素:
計算和儲存分離,訊息資料儲存在 BookKeeper 的 Bookie 中,由 Broker 提供服務。
Broker 節點和 Bookie 節點可分別運維、擴縮容。
支援資料 offload 到雲上的物件儲存。
此外,Pulsar Client 與 Pulsar Broker 進行對接。ZooKeeper 節點與 Broker、Bookie 互動,處理後設資料以及分散式系統中的協調。
Pulsar 的另一個重要特性是易擴容。Pulsar Topic 資料的儲存模式使得節點擴容時不需要 rebalance。這個的原因是 Pulsar 採用了 Topic - Ledger - Fragment - Entry 的多級結構來儲存 Topic 的訊息資料。如下圖所示:
一個 Topic 下會有多個 Ledger,一個 Ledger 下面會有一個或多個 Fragment,每一個 Fragment 下面會有多條訊息(多個 Entry)。每個 Fragment 的實際資料的儲存位置是在一組 Bookie 上面,不同的 Fragment 對應的 Bookie 的集合都是不一樣的。這樣的一個結構使得每一個 Topic 的訊息天然分佈在不同的 Bookie 節點中,而不同的 Fragment 的資料儲存在不同的 Bookie 集合中。
如果使用者擴容一個新的 Bookie 節點,只需要把 Topic 的新的 Ledger / Fragment 的資料寫入新 Bookie。舊 Bookie 的資料不用 rebalance。Pulsar 中的 Topic 和具體的儲存節點並沒有耦合、繫結。假設一個 Topic 的資料繫結在某一個固定的儲存節點上,那麼如果單純地擴容儲存節點,且如果 Topic 的數量不變,那麼新的儲存節點是不會有 Topic 的資料寫進去的。為了讓新擴容出來的儲存節點能夠被利用到,能夠被寫入 Topic 的資料,就需要更改一部分 Topic 與儲存節點的繫結關係,這樣就涉及到了資料的搬遷,即 rebalance。
而 Pulsar 不存在這個問題,因為 Pulsar 天然就是一個 Topic 的資料分散在不同的 Bookie 節點中儲存,所以在新擴容出一個 Bookie 節點後,一個 Topic 中的新的資料是可以寫入到新的 Bookie 節點中的,新的 Bookie 節點也不用擔心沒有資料寫進去。而 Topic 中的一些歷史存量資料仍然存放在原來的地方,不用做存量資料的搬遷、rebalance。
這樣的話,對於使用者來說,在擴容時的運維成本、風險和複雜性都大大降低了。這是 Pulsar 給客戶提供的核心價值之一。
相比於其他訊息佇列元件,Pulsar 也提供了一些差異化價值。下面這張表對比了 Pulsar 與 Kafka 的部分特性。