1. 程式人生 > >阿里如何實現秒級百萬TPS?搜尋離線大資料平臺架構解讀

阿里如何實現秒級百萬TPS?搜尋離線大資料平臺架構解讀

什麼是搜尋離線?

一個典型的商品搜尋架構如下圖所示,本文將要重點介紹的就是下圖中的離線資料處理系統(Offline System)。

何謂離線?在阿里搜尋工程體系中我們把搜尋引擎、線上算分、SearchPlanner等ms級響應使用者請求的服務稱之為“線上”服務;與之相對應的,將各種來源資料轉換處理後送入搜尋引擎等“線上”服務的系統統稱為“離線”系統。商品搜尋的業務特性(海量資料、複雜業務)決定了離線系統從誕生伊始就是一個大資料系統,它有以下一些特點:

1. 任務模型上區分全量和增量

1)全量是指將搜尋業務資料全部重新處理生成,並傳送給線上引擎,一般是每天一次。這麼做有兩個原因:有業務資料是daily更新;引擎需要全量資料來高效的進行索引整理和預處理,提高線上服務效率。

2)增量是指將上游資料來源實時發生的資料變化更新到線上引擎中。

3)效能方面有較高要求。全量需要極高吞吐能力,確保數以億計的資料可以在數小時內完成。增量則需要支援數萬TPS秒級的實時性,還需要有極高的可用性。

2. 需要支援多樣化的輸入和輸出資料來源,包括:Mysql,ODPS,TT等各種資料庫和訊息佇列作為輸入,搜尋、Ranking、圖、推薦等各種引擎作為輸出。

3. 需要提供一定能力的資料處理能力,例如多表Join、UDTF支援等,以方便搜尋業務的開發和接入。

在後續的段落中我們會看到離線系統架構圍繞著這些特點,針對搜尋業務的變化,做出的各種演進和發展。

發展簡介

阿里商品搜尋體系肇始於淘寶搜尋,大約在2008年初第一代搜尋系統誕生,離線系統隨之上線。搜尋離線系統經歷多年發展,技術架構幾經迭代,資料處理能力、業務支援能力不斷提升。下面會分階段介紹搜尋離線的主要技術架構和特點。

★ 淘寶搜尋階段

在2008-2012這個階段,我們重點支援淘寶搜尋的業務發展,隨著淘寶商品量的不斷增加,逐步引入Hadoop、Hbase等開源大資料計算和儲存框架,實現了搜尋離線系統的分散式化,有力地支援了淘寶搜尋業務的發展。但是在這個階段,我們支援的業務線只有淘系合計不到5個業務線,為此投入了大約10名開發人員,整體效率不高。另一方面相關係統框架程式碼與淘系業務高度耦合,量身定製了很多特殊程式碼,不利於架構的推廣和其它業務的支援。

★ 元件&平臺化階段

2013年底以來,特別是最近兩年,隨著集團技術業務線的梳理以及中臺化戰略的推行,搜尋離線系統需要為越來越多的不同業務團隊(飛豬、釘釘、1688、AE、Lazada等等)提供支援,技術框架複用、開發效率提升和平臺化支援的需求越來越強烈。另一方面隨著大資料計算、儲存技術的發展,尤其是流計算引擎的飛速發展,離線系統技術架構上的進一步演進也具備了絕佳的土壤。

我們可以看到整個搜尋離線系統的演進是沿著效能和效率兩條主線,以業務和技術為雙輪驅動,一步一個腳印的走到今天。這是一個技術與業務高度融合互動,互相促進發展的典型樣例。

離線平臺技術架構

上一節我們簡要介紹了離線系統的發展歷史,也簡要提到技術架構的演進,下面將會把離線平臺的技術架構展開介紹,主要分為平臺流程以及計算和儲存架構等幾個方面。

平臺元件和任務流程

上圖描述了離線平臺技術元件結構,其中部分元件的簡介如下:

  • Maat:分散式任務排程平臺,基於Airflow發展而來,主要改進點是排程效能優化、執行器FaaS化、容器化、API及排程功能擴充套件等四個部分,在保持對Airflow相容的基礎上,大幅提升效能,提高了穩定性。 一個離線任務的多個Blink job會通過Maat建立依賴關係並進行排程。

  • Bahamut:執行引擎,是整個離線平臺的核心,負責離線任務的建立、排程、管理等各種功能,後文會詳細介紹。

  • Blink:Flink的阿里內部版本,在大規模分散式、SQL、TableAPI、Batch上做了大量的優化和重構。離線平臺的所有計算任務都是Blink job,包括stream和batch。

  • Soman:UI模組,與Bahamut後端對接,提供任務資訊展示、狀態管理等視覺化功能,也是使用者建立應用的開發業務邏輯的主要入口。

  • Catalog: 儲存表資訊管理,提供各種資料來源表的DDL能力,負責離線平臺儲存資源的申請、釋放、變更等各種功能。

  • Hippo:阿里搜尋自研的分散式資源管理和任務排程服務,類似於Yarn,提供Docker管理能力,主要服務於線上系統。

  • Swift:阿里搜尋自研高效能分散式訊息佇列,支援億級別訊息吞吐能力,儲存後端為HDFS,儲存計算分離架構。

下圖則描述了一個離線任務從資料來源到產出引擎服務資料的整個過程,流程圖分成三層:

  • 資料同步層:將使用者定義的資料來源表的全量和增量資料同步到Hbase內部表,相當於源表的映象。這個映象中我們包含cf和d兩個列族,分別儲存資料庫的映象和Daily更新的資料。

  • 資料關聯計算層:按照資料來源中定義的各種關係,將不同維度的資料關聯到一起,把資料送到自定義的UDTF中進行處理,產出引擎所需的全量和增量資料。

  • 資料互動層:提供全量和增量資料的儲存資訊,與線上服務build模組進行互動。

全增量統一的計算模型

那麼如何實現對使用者遮蔽離線平臺內部的這些技術細節,讓使用者只需要關注業務實現呢?回顧第一節介紹的離線任務概念,離線任務包含全量和增量,它們業務邏輯相同,但是執行模式上有區別。為了讓使用者能夠專注業務邏輯的開發,遮蔽離線平臺技術細節實現全增量統一的計算邏輯,我們引入了Business Table(業務表)的概念。

Business Table(業務表):Business Table是一個抽象表,由一個全量資料表和/或一個增量流表組成,全量/增量表的Schema相同,業務含義相同。

基於業務表和資料處理元件,使用者可以開發出一個描述離線處理流程的業務邏輯圖,我們稱之為Business Graph。下圖就是一個Business Graph的樣例,其中上側紅框標識的就是隻包含ODPS全量資料來源的Business Table,最下方紅框中標識的是包含Hdfs+Swift的Business Table,除此之外我們還支援Mysql+DRC/ODPS+Swift等多種業務表的組合。圖中還可以看到Join、UDTF等常用的資料處理元件,業務表與處理元件結合在一起就能夠描述常見的離線業務處理邏輯。

那麼如何把這個Business Graph轉化為真正的離線任務呢?Bahamut作為離線平臺的執行引擎,會按照Business Graph->APP Graph->Job Graph->(Blink Job/Maat Job)的順序把一個業務描述轉化為可執行的離線任務,具體如下:

1. Business Graph->APP Graph:在這個環節中我們主要有2個重要的工作:

1)正確性校驗:根據BG中的節點資訊,校驗節點間連線的合法性(例如兩個輸入源節點不能直接連線)、節點配置的正確性(資料庫配置/ODPS的配置是否正確)、Schema推導是否正確。

2)任務分層優化:為了用Blink Stream模式來統一完成全量和增量的執行,我們需要將輸入源資料存入內部Hbase,直接使用Blink維表Join功能來完成資料的連線。於是在節點遍歷過程中遇到Join、Merge元件時,需要在AppGraph中插入一個內部的HTable節點,將Merge或者Join上游的資料同步進入Hbase。

2. APP Graph->Job Graph:JobGraph是一個Blink/Maat任務的配置DAG,其中每個節點包含配置資訊,可以在後續的過程中直接轉化為計算或者排程任務。

1)Blink JobGraph:從資料來源業務表節點開始遍歷AppGraph,每當碰到一個內部HTable節點時,會生成兩個(增量/全量)同步層的Blink JobGraph。所有同步層Blink JobGraph生成後,以所有的內部HTable/queue為輸入,生成兩個(增量/全量)關聯處理層的Blink JobGraph。

①同步層:採用Business Table中的全量/增量表配置,分別生成全量和增量的Blink任務配置,描述把資料從資料來源同步到內部HTable過程。例如對於Mysql+DRC的表,全量階段將會從mysql中拉取全表資料並轉化為HFile bulkload到HTable中,增量階段則是從DRC中拉取變化資料,直接寫入HTable,並根據需求寫入驅動queue。

②關聯處理層:關聯多個HTable,生成大寬表後呼叫UDTF處理,產出最終的進入引擎的資料。同樣需要分別生成全量和增量任務配置

2)Maat JobGraph:基於Maat的排程任務描述DAG,主要目的是將各個層次的Blink任務按照依賴進行排程,同時執行特定的指令碼完成與外部系統的互動等職責。一般來說一個離線任務會生成Build/Publish/Stop/Release等多個Maat JobGraph。

3. Job Graph->Blink/Maat Job:遍歷JobGraph,呼叫Translator將JobGraph轉換為Blink/Maat的任務程式碼。引入JobGraph的目的是將底層的計算引擎與計算任務描述解耦,例如:我們底層的計算引擎曾經是MapReduce +Blink-1.4-TableAPI,最近剛完成了Blink-2.1 基於SQL的升級,我們所有的工作基本上是重寫了一套Translator,對上層的程式碼結構沒有任何變動。

經過了上述的三個步驟,我們完成了BusinessGraph(業務描述)到Blink/Maat job的轉化,生成了若干資料同步/處理的Blink job,以及將這些Blink job進行依賴排程的完成不同功能的Maat  job。特別的針對搜尋離線的場景,在排程流程中加入了大量與下游引擎互動的邏輯,包括24小時不間斷增量、觸發引擎消費資料、切換引擎消費增量queue等重要的業務流程。

儲存與計算

★ 基於Hbase的儲存架構

搜尋離線大約在2012年即引入了Hbase作為資料的儲存引擎,有力的支援了搜尋業務從淘寶主搜到離線平臺的整個發展歷程,歷經多次雙11考驗,穩定性和效能都得到明確的驗證。從功能層面,搜尋離線引入Hbase的原因主要是以下幾點:

  1. 通過Scan/Get可以批量/單條的獲取資料,通過bulkload/put可以批量/單條的匯入資料,這與搜尋的全量/增量模型完全吻合,天然適合支援搜尋離線業務。

  2. 底層儲存基於HDFS,LSM-Tree的的架構能夠確保資料安全性,計算儲存分離的架構保證了叢集規模水平可擴充套件,易於提高整體的吞吐。通過單機效能優化(Async、BucketCache、Handler分層、Offheap)和叢集的擴容,確保了業務大幅增長時,儲存從來沒有成為系統的瓶頸。

  3. Free Schema的特效能夠很好的應對業務資料頻繁變化的情況,也能夠方便支援一些特殊業務場景的資料邏輯。

通過引入Hbase做為離線系統的內部資料儲存,我們成功解決了每天全量時對上游Mysql造成很大壓力的問題,大幅度的提升了整體系統的吞吐。資料儲存到Hbase也是全量任務向流式處理流程轉型(MR->Stream)的基礎,而這一點為後來Blink流引擎在搜尋離線的孕育和發展也埋下了伏筆。

當然Hbase也不是毫無缺點,JVM記憶體管理的痼疾、單機Handler打滿導致雪崩、缺乏容器化部署能力等也帶來了不少煩惱,很快我們就會替換Hbase為阿里內部發展的另外一套儲存引擎,期望能夠部分的解決這些問題。

★ 基於Flink的計算架構

2016年中,搜尋離線逐漸開始引入Flink作為計算引擎,重點解決搜尋實時計算場景碰到的大量問題。在社群Flink版本的基礎上,實時計算團隊開發了Blink,增加原生yarn模式、Incremetal checkpoint等若干解決Flink大規模分散式執行問題的特性,另一方面,在DataStream/DataSet介面的基礎上,進一步加強了TableAPI和SQL的功能,真正統一了Stream和Batch的呼叫介面,並實現計算業務邏輯的sql化開發模式。

離線平臺是Blink的早期使用者和開發者,從0.8版本開始經歷了多個Blink版本的升級和變遷,先後使用了DataStream、TableAPI和SQL作為任務介面,同時也開發了大量Connector以支援不同資料來源之間的互動。目前離線平臺已經在使用最新的Blink-2.1.1,Bahamut利用SqlTranslator直接生成SQL來描述任務邏輯,通過Bayes(Blink SQL開發平臺)服務化直接提交任務到不同的Yarn叢集,這樣做有以下幾個明顯的優勢:

  1. 採用SQL來描述Blink任務業務邏輯非常清晰,可以直接利用Blink提供的各種Operator完成資料處理,方便任務的除錯,例如:dim join、groupby,而不是在Datastream時期需要自行編寫完成類似Hbase Join的Operator。

  2. Blink 2.1原生支援Batch,採用Batch模式可以直接完成生成HFile的任務,下線MR任務,徹底統一計算引擎到Blink。Batch模式任務執行時採用分階段排程可以大幅的節省計算資源,提高叢集效率。Blink SQL可以通過修改提交模式,分別轉化為Stream或Batch任務,在保持業務邏輯穩定的同時方便任務除錯和驗證。

  3. 通過Bayes這樣的開發平臺服務化的方式提交任務到不同叢集,徹底解決以前任務通過GateWay提交運維複雜的問題,新增新的Yarn叢集只需要簡單配置即可完成。另外在Bayes上同樣會儲存Bahamut自動生成提交的Sql,可以在Bayes上直接進行任務的除錯和管理,方便了開發人員。

下圖是一個Bahamut自動生成的Blink Sql樣例,描述同步層的一個任務,任務中包含Source,Select Oper和Sink三個Operator,實現從Mysql實時變化到Hbase表的同步。

-- 定義資料來源表,這是一個DRC(Mysql binlog流)源

CREATE TABLE DRCSource_1 (
  `tag_id`                        VARCHAR,
  `act_info_id`                    VARCHAR,
) with (
  tableFactoryClass='com.alibaba.xxx.xxx.DRCTableFactory',
  -- other config);

-- 定義輸出表
CREATE TABLE HbaseSink_1 (
  `tag_id`                    VARCHAR,
  `act_info_id`               VARCHAR,
) with (
  class='com.alibaba.xxx.xxx.CombineSink',
  hbase_tableName='bahamut_search_tmall_act',
  -- other config
 );

-- 定義Blink任務的業務邏輯
INSERT INTO HbaseSink_1SELECT
  `tag_id`,
  `act_info_id`,
FROM DRCSource_1;

總結

搜尋離線資料處理是一個典型的海量資料批次/實時計算結合的場景,搜尋中臺團隊立足內部技術結合開源大資料儲存和計算系統,針對自身業務和技術特點構建了搜尋離線平臺,提供複雜業務場景下單日批次處理千億級資料,秒級實時百萬TPS吞吐的計算能力。離線平臺目前支援了集團內200多個不同業務線的搜尋業務需求,大幅提高了業務迭代的效率,成為搜尋中臺的重要組成部分。很快離線平臺還會在阿里雲上與Opensearch/ES結合,為集團外客戶提供高可用、高效能的搜尋離線資料處理能力。在不遠的將來離線平臺將會逐漸拓展到推薦和廣告的資料處理場景,有著廣闊的應用場景,一個涵蓋搜尋/推薦/廣告體系的SARO(Search Advertisment and Recommandation Offline)平臺會逐步成型。

到最後給大家推薦一個大資料學習:593188212,歡迎學習java,大資料的夥伴加入,裡面有零基礎,進階資料分享