天天看點

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語
阿裡妹導讀:阿裡主搜(淘寶天貓搜尋)是搜尋離線平台非常重要的一個業務,具有資料量大、一對多的表很多、源表的總數多和熱點資料等特性。對于将主搜這種邏輯複雜的大資料量應用遷移到搜尋離線平台總是不缺少性能的挑戰,搜尋離線平台經過哪些優化最終實作全量高吞吐、增量低延遲的呢?

作者簡介:王偉駿,花名鴻曆,阿裡巴巴搜尋推薦事業部進階開發工程師。2016年碩士畢業于南京郵電大學。Apache Hadoop && Flink && Eagle Contributor。目前負責阿裡巴巴搜尋離線平台Runtime層相關工作。

另外,陳華曦(昆侖)給了本文很多建議,文中部分圖由李國鼎(石及)貢獻。

前言

在阿裡搜尋工程體系中我們把搜尋引擎、線上算分等ms級響應使用者請求的服務稱之為“線上”服務;與之相對應的,将各種來源資料轉換處理後送入搜尋引擎等“線上”服務的系統統稱為“離線”系統。

搜尋離線平台

作為搜尋引擎的資料提供方,是集團各業務接入搜尋的必經之路,也是整個搜尋鍊路上極為重要的一環,離線産出資料的品質和速度直接影響到下遊業務的使用者體驗。

搜尋離線平台經過多年沉澱,不僅承載了集團内大量搜尋業務,在雲上也有不少彈外客戶,随着平台功能的豐富,Blink(阿裡内部版本的Flink) 版本的領先。我們在2019年年初開始計劃把主搜(淘寶天貓搜尋)遷移到搜尋離線平台上。

主搜在遷移搜尋離線平台之前的架構具有架構老化、Blink版本低、運維困難、計算架構不統一等不少缺點,随着老主搜人員流失以及運維難度與日俱增,重構工作早已迫上眉睫。對于将主搜這種邏輯複雜的X億資料量級應用遷移到搜尋離線平台總是不缺少性能的挑戰,業務特點與性能要求決定了主搜上平台的過程中每一步都會很艱辛。為了讓性能達到要求,我們幾乎對每個Blink Job都進行了單獨調優,最初的理想與最後的結局都是美好的,但過程卻是極其曲折的,本文将主要介紹主搜在遷移搜尋離線平台過程中在性能調優方面具體做了哪些嘗試。

主搜遷移搜尋離線平台的完成對于平台來說有裡程碑式的意義,代表搜尋離線平台有能力承接超大型業務。

搜尋離線平台基本概念

搜尋離線平台處理一次主搜全增量主要由同步層和資料處理層組成,它們又分别包括全量和增量流程。為了讀者更好了解下文,先簡單介紹幾個關于搜尋離線平台的基本概念。

集團内支撐業務

目前搜尋離線平台在集團内支援了包括主搜,AE在内的幾百個業務。其中資料量最大的為淘寶天貓評價業務,資料量達到了X百億條,每條資料近上X個字段。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

場景

處理使用者的資料源(mysql或odps)表,将資料經過一系列的離線處理流程,最終導入到Ha3線上搜尋引擎或ES中。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

平台相關技術棧

如下圖,搜尋離線平台目前資料存儲基于HDFS/盤古,資源排程依賴于YARN或Hippo,計算架構統一用Flink/Blink執行。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

全量

全量是指将搜尋業務資料全部重新處理生成,并傳送給線上引擎,一般是每天一次。

這麼做有兩個原因:有業務資料是Daily更新;引擎需要全量資料來高效的進行索引整理和預處理,提高線上服務效率。全量主要分為同步層與資料處理層。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

增量

增量是指将上遊資料源實時發生的資料變化更新到線上引擎中。

這也就意味着在我們的場景中對于增量資料不需要保證Exactly Once語義,隻需要保證At Least Once語義。基于該背景,我們才能用全鍊路異步化的思維來解一對多問題(下文會詳細講解)。

與全量一樣,增量也分為同步層與資料處理層。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

一對多

在搜尋這個領域某些業務資料需要用一對多的形式來描述,比如商品寶貝和SKU的關系即是個典型的一對多資料的例子。在搜尋離線基于Hologres(阿裡巴巴自研分布式資料庫)存儲的架構中,一對多的資料存儲在單獨的一張雙pk的HoloTable中,第一、二主鍵分别的寶貝ID與SKU_ID。

有了上面這些概念之後,在後續的段落中我們會看到搜尋離線平台針對主搜各Blink Job的性能調優,先簡要概括下主搜業務特點與性能要求。

資料存儲方式

搜尋離線平台以前用HBase做鏡像表時,是用一張多列族大寬表來存儲業務單次元所有資料。經過詳細調研之後,我們決定用Hologres替換HBase,是以需要對存儲架構做全面的重構。用多表來模拟HBase中的多列族,單HoloTable中包括很多業務資料源表的資料。重構後的資料存儲方式大緻如下:

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語
百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

同步層

所謂同步層,一般是将上遊資料源的資料同步到鏡像表,供資料處理層高效處理。由于業務方單次元的資料有很多Mysql表或odps表組成,少則X張,多則像主搜這樣X張。是以将同緯度資料聚合到一張Holo表中時,如果多張表兩兩join的話會産生大量shuffle,是以我們采取異步upsert方式,不同資料源表的資料寫Holo表中不同的列來解決海量資料導入問題。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語
百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

資料處理層

所謂資料處理層,是指将同步層得到的各鏡像表(HBase/Holo)的資料進行計算,一般包括多表Join、UDTF等,以友善搜尋業務的開發和接入。

主搜業務特點與性能要求

下面首先介紹下主搜業務特點與性能要求,再詳細介紹我們進行了怎樣的調優才達到了性能的要求。

主搜業務特點

★ 資料量大

主搜有X億(有效的X億)個商品,也就是主次元有X億條資料,相比于平台其他業務(除淘寶評價業務)多出X個數量級。這麼多資料我們能否在X個多小時完成全量?如何實作高吞吐?挑戰非常大。

★ 一對多的表很多

主搜業務有很多一對多的表需要Join,例如一個商品對應多個SKU,部分商品對應了接近X個SKU資訊。這些資訊如何能夠高性能的轉換為商品次元,并與商品資訊關聯?

★ 源表的總數多

主搜有X多張表(包括一對多的表),平台其他業務的源表個數一般都在個位數。源表數量多會導緻一系列的問題,比如讀取ODPS資料時如何避免觸發ODPS的限制?拉取大表資料時如何做到高吞吐?這些問題都需要我們一一解決。

★ 熱點資料

主搜有一些大賣家(餓了麼,盒馬等)對應了很多商品,導緻在資料處理層出現非常嚴重的資料傾斜等問題。如何解決大資料處理方向經常出現的SKEW?

主搜性能要求

★ 全量(同步層 + 資料處理層)高吞吐!

全量要求每天一次,在有限的資源情況下每次處理X億的商品,這麼大的資料量,如何實作高吞吐,挑戰非常大!

★ 增量(同步層 + 資料處理層)低延遲!

增量要在Tps為X W的情況下達到秒級低延遲,并且雙11期間有部分表(例如XX表)的Tps能達到X W,增量如何保證穩定的低延遲?值得思考!

下面一一描述我們是如何解決這些問題來達到性能要求的。

Blink Job性能調優詳解

根據上述主搜業務特點與性能要求羅列出下圖,左邊與中間兩清單示主搜哪些特點導緻某階段任務性能差。是以我們要對相應階段Blink Job進行調優,調優完成也就代表着平台能滿足圖中最右邊一列主搜所需要的全量高吞吐與增量低延遲的性能要求。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

下面按照全量,增量,解一對多問題的脈絡來給大家介紹我們是如何解決上述五個問題之後達到全量高吞吐以及增量低延遲的性能要求的。

全量高吞吐性能調優

全量主要包括同步層與資料處理層,必須實作高吞吐才能讓全量在X個多小時之内完成。同步層在短時間内要同步約X張表中的上X億全量資料,且不影響同時在運作的增量時效性是一個巨大的挑戰。資料處理層要在短時間内處理X多億條資料,Join很多張鏡像表,以及UDTF處理,MultiGet等,最後産生全量HDFS檔案,優化過程一度讓人頻臨放棄。這裡重點介紹資料處理層的性能調優曆程。

該Job的調優曆時較長,嘗試方案較多,下面按照時間順序講解。

★ 初始形态

首先提一下IC次元為商品次元,UIC次元為賣家次元,并且最開始我們的方案是沒有FullDynamicNestedAggregation和IncDynamicNestedAggregation的(後文會詳細提到這兩個Job)。Scan IC次元單Pk表之後做一系列的DImJoin、UDTF、MultiJoin。在測試過程中發現DimJoin多pk表(一對多表)的資料時,性能非常低下,全鍊路Async的流程退化成了Sync,原因是我們一對多的資料存在單獨的一個SaroTable(對多個HoloTable的邏輯抽象)中,對指定第一pk來取對應所有資料用的是Partial Scan,這是完全Sync的,每Get一次都要建立一個Scanner,雖然我們不但對于DimJoin加了Cache,并且對于主搜特有的MultiGet也加了對于SubKey的精準Cache。但是測試下來發現,性能還是完全得不到滿足,是以嘗試繼續優化。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

★ 引入LocalJoin與SortMergeJoin

由于性能瓶頸是在DimJoin多pk的SaroTable這裡,是以我們想辦法把這部分去掉。由于一對多的SaroTable隻有兩個次元具有,是以我們嘗試先分别将IC次元與UIC次元的所有表(包括單pk與多pk)進行LocalJoin,結果再進行SortMergeJoin,然後繼續别的流程。

首先介紹下Local Join。由于HoloStore保證相同DB中所有表都是按照相同的Partition政策,并且都是按照主鍵字典序排好序的,是以我們可以将同緯度同Partition的資料拉取到一個程序中進行Join,避免了Shuffle,如下圖所示。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

是以拓撲大概變為:

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

經過測試,由于業務上面存在大賣家(一個賣家有很多商品),導緻SortMergeJoin之後會有很嚴重的長尾,如下圖所示,Uid為101與103的資料都是落到同一個并發中,我曾經嘗試再這個基礎之上再加一層PartitionBy nid打散,發現無濟于事,因為SortMergeJoin的Sort階段以及External Shuflle對于大資料量的Task需要多次進行Disk File Merge,是以該長尾Task還是需要很長時間才能Finish。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

★ 加鹽打散大賣家

是以我們需要繼續調優。經過組内讨論我們決定對大賣家進行加鹽打散,從ODPS源表中找出Top X的大賣家ID,然後分别在主輔次元Scan + Local Join之後分别加上UDF與UDTF,具體流程圖與原理示例見下面兩幅圖:

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語
百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

如上圖所示,Uid為101與103的資料被打散到多個并發中了,并且因為我們在SortMergeJoin之後加了UDTF把加的Salt去掉,是以最終資料不會有任何影響。

★ 最終形态

這樣全量FullJoin總算完成了,并且性能也勉強達标,是以我們開始調整增量流程(IncJoin),這時發現IncJoin跟FullJoin的初始形态存在一樣的問題,追增量非常慢,永遠追不上,是以組内讨論之後決定在同步層針對全量新增一個FullDynamicNestedAggregation Job(下文會詳細提到),這是一個Blink Batch Job它将各次元一對多的SaroTable資料寫到對應次元的主表中,然後在FullJoin最開始Scan時一起Scan出來,這樣就避免了DimJoin多pk的SaroTable。最終達到了全量高吞吐的要求,全量FullJoin最終形态如下:

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

增量低延遲性能調優

增量性能主要受困于資料處理層IncJoin,該Job最開始是一個Blink Stream Job,主要是從SwiftQueue中讀出增量消息再關聯各個鏡像表中的資料來補全字段,以及對資料進行UDTF處理等,最後将增量消息發往線上引擎SwiftQueue中。

基于“流批一體”的思想,經過一系列嘗試,我們增量資料處理層Job的最終形态如下。與全量不同的是由于增量是實時更新的,是以更新記錄不僅要寫到Swift Queue中,還要寫入SaroTable中。另外,我們根據業務特點給各個Job分别加了按pk對記錄去重的window。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

解一對多問題

主搜有很多一對多的表,在資料處理層如何高效的将資料Get出來轉換為主次元之後進行字段補全,困擾我們很久。

為了提升效率我們必須想辦法提升Cpu使用率。是以Get記錄改為全鍊路異步來實作,由于我們一對多資料存在多pk的HoloTable中,指定第一pk去擷取相關資料在Holo服務端是以Scan來實作的。這樣由于異步程式設計的傳染性,全鍊路異步會退化為同步,性能完全不達标。

★ 解決方法

為了将“僞異步”變成真正的全鍊路異步,經過多次讨論與實踐之後,我們決定将一對多表中相同第一pk的多條資料Scan出來GroupBy為一條資料,将每個字段轉化為Json之後再Put進主表中,主要步驟如下圖所示。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

我們針對全量與增量在同步層加Job來解決,分别為FullDynamicNestedAggregation(Blink Batch Job)與IncDynamicNestedAggregation(Blink Stream Job),這兩個Job大緻流程為如下圖所示。

百萬TPS高吞吐、秒級低延遲,阿裡​搜尋離線平台如何實作?前言搜尋離線平台基本概念主搜業務特點與性能要求Blink Job性能調優詳解結語

值得一提的是,正如前文介紹增量時提到的背景,我們的場景中對于增量資料不需要保證Exactly Once語義,隻需要保證At Least Once語義。是以基于該背景,我們能夠将資料處理層增量Job拆分為兩個Job執行,一對多的問題得以解決。

這樣我們在資料處理層就不需要去Scan HoloTable了,進而可以用全鍊路異步化的方式來提升增量整體性能。

★ 截斷優化

為了避免将多條資料轉為一條資料之後由于資料量過大導緻FullGC的“大行”問題。基于業務的特性,我們對于每個一對多表在Scan時支援截斷功能,對于相同的第一pk記錄,隻Scan一定條數的記錄出來組裝為Json,并且可以針對不同的表實作白名單配置。

★ 加過濾Window優化

針對業務的特點,一對多的很多表雖然可以接受一定時間的延遲,但是為了避免對離線系統以及線上BuildService造成太大的沖擊,是以更新不能太多,是以我們加了30min的去重視窗,這個視窗作用非常大,平均去重率高達X%以上。

結語

經過一系列優化,主搜不僅在資源上相對于老架構有不少的節省,而且同時實作全量高吞吐與增量低延遲,并且在2019年度雙11 0點應對突增流量時表現的遊刃有餘。

對系統進行性能調優是極其複雜且較精細的工作,非常具有技術挑戰性。不僅需要對所選用技術工具(Flink/Blink)熟悉,而且對于業務也必須了解。加window,截斷優化,加鹽打散大賣家等正是因為業務場景能容忍這些方法所帶來的相應缺點才能做的。

除了本文提到的調優經驗,我們對同步層全增量Job與MultiGet也進行了不少調優,篇幅原因與二八原則這裡就不詳細介紹了。

主搜成功遷移也使得搜尋離線平台完成了最後一塊拼圖,成為阿裡巴巴集團搜尋中台以及核心鍊路的基礎子產品。

原文釋出時間:2020-01-20

作者:鴻曆

本文來自阿裡雲合作夥伴“

阿裡技術

”,了解相關資訊可以關注“

”。