基於Blink構建親聽項目以及全鏈路debug項目實時響應能力

案例與解決方案彙總頁:

本文全面總結了大數據項目組在親聽項目以及全鏈路debug項目上進行的實時流處理需求梳理,架構選型,以及達成效果

一、背景介紹

1.1親聽項目

親聽項目專注於幫助用戶收集、展示、監控和處理用戶體驗問題,是保證產品的主觀評價質量的利器,關於其具體功能可參考在ata搜索"親聽"查看系列文章。目前親聽項目的實時流處理需求來自算法效果監控,算法效果監控需要對上游TimeTunnel日誌進行解析後經過處理得到一些關鍵指標,親聽通過對這些指標的前端展示和閾值監控報警達到算法效果監控目的。

基於Blink構建親聽項目以及全鏈路debug項目實時響應能力

需求要點可以總結如下:

  1. 上游需要處理的TimeTunnel日誌的實時數據量大約在日常峰值每秒數萬條記錄,大促峰值每秒幾十萬條記錄
  2. 從用戶搜索行為到親聽系統得到搜索行為指標數據秒級的低延時
  3. 數據的處理邏輯較為複雜且會隨著算法迭代需要發生變化

1.2全鏈路debug

全鏈路debug專注於幫助用戶在線上搜索結果出現異常和問題時幫助開發者復現搜索後端各子系統的中間結果,定位並解決子系統存在的問題,是系統層級質量保證和測試的有力工具。關於其具體功能可參考在ata搜索"全鏈路debug"查看系列文章。全鏈路debug的實時流處理需求是實時從TimeTunnel日誌中提取出幫助排除搜索線上問題的關鍵內容,全鏈路debug利用這些內容幫助進行問題排查。全鏈路debug的實時流處理需求模型可以用下圖描述:

基於Blink構建親聽項目以及全鏈路debug項目實時響應能力

需求要點可以總結如下:

  1. 上游需要處理的TimeTunnel日誌的實時數據量大約在日常峰值每秒數萬條記錄,大促峰值每秒幾十萬條記錄
  2. 需要保存的單條記錄較大,平均達到幾K左右
  3. 對上游TimeTunnel日誌解析邏輯大部分為字段提取和透傳且不會頻繁變化

二、解決方案

2.1整體架構

應對以上需求,親聽以及全拉鍊路debug的實時流處理系統的最終架構如下:

親聽:

基於Blink構建親聽項目以及全鏈路debug項目實時響應能力

全鏈路debug:

基於Blink構建親聽項目以及全鏈路debug項目實時響應能力

對於親聽和全鏈路debug的實時流處理需求最終選擇上述架構主要出於實時性和擴展性兩方面考慮

2.2實時性

親聽和全鏈路debug的實時流處理需求在實時性要求上是類似的,即要對接tt日誌,在tt日誌記錄寫入到對於親聽和全鏈路debug的使用方可見延時要控制在秒級,這種實時性的需求可以分解為兩個部分,第一是對實時流數據的處理,而是對實時流數據處理結果的存儲和查詢服務。對於實時流數據的處理,目前公司內的中間件產品blink能很好滿足我們的需求,blink提供對接TimeTunnel的api接口,同時具備很好的實時流處理性能和運維體驗;對於實時流處理結果的存儲和查詢,需要支持幾萬到幾十萬qps的寫壓力以及在每天累計幾十T數據量情況下毫秒級延時的讀性能,hbase能夠基本滿足對讀寫的需求,但是druid和drill能夠在滿足讀寫性能的同時提供更好的數據查詢體驗和實時流處理邏輯的可擴展性,所以對於實時流數據處理結果的存儲和查詢服務我們是優先考慮druid和drill的,但是全鏈路debug的實時流處理結果有一個特點就是單條記錄數據大小平均為幾K左右,這麼大的單條記錄的大小將導致druid需要的內存量過大且查詢性能低下而不可用,所以對於全鏈路debug的實時流處理結果的存儲和查詢服務選擇了hbase。

2.3擴展性

在親聽實時流處理系統的下游引入tt->druid,然後使用drill查詢druid提供查詢服務,是出於對擴展性的考慮。druid是一種支持實時流處理和查詢的olap系統(ATA),對接druid使得可以把一部分實時流數據的處理邏輯交給druid,這樣當實時流處理邏輯需要修改時,很多情況下就可以通過修改查詢邏輯(只要修改一個請求druid時的json配置文件)而不需要修改blink任務(需要修改代碼、打包、編譯、調參、上線)實現,大幅提升實時流處理系統的擴展性,而親聽實時流處理需求頻繁變化的業務特點非常需要這種擴展性;drill是高性能的SQL查詢引擎,通過drill對接druid提供查詢服務不但使查詢語法從druid的json文件變為sql可讀性大幅增強,同時drill對druid查詢結果具有的二次處理能力也進一步增強了通過修改查詢邏輯可以滿足的實時流處理邏輯變化,進一步增強系統可擴展性。

在blink和druid之間增加了TimeTunnel進行數據中轉以保證blink產出流數據被轉化為下游druid支持的流數據源形式。

2.4經驗總結

使用table api編寫

stream api作為blink的底層api,具有較高的靈活性,但是可讀性很不好,進而非常影響代碼的可維護性和擴展性,當要在實時任務中加入新需求時經常要改動很多地方並且很容易出錯,所有實時任務我們選擇使用table api編寫,table api使用類sql語法描述實時流處理邏輯,使得數據流處理邏輯變得非常清晰,可讀性大幅增強,進而節約代碼的維護和擴展成本。

進行字段歸類合併

我們通過梳理業務方最終需要使用的字段內容,將blink任務輸出到TimeTunnel中記錄的字段進行了分類合併,除了出於druid查詢性能考慮將若干需要進行group by以及count distinct查詢的原有字段保留,其餘全部按照諸如搜索請求相關信息、用戶相關信息、搜索返回寶貝相關信息這樣的概念將原有字段分組後合併為多值字段,而每個合併後的多值字段又會在blink代碼中用一個udtf函數統一處理。這樣做的好處在於代碼邏輯上變得更清晰,當實時流處理需求發生變化,需要產出新的內容或修改現有內容產出邏輯時,只需找到新增內容或待修改內容對應的多值字段,修改對應udtf邏輯並重新上線blink任務即可,下游的druid build無需進行任何修改;同時用有限的幾個udtf對整個實時流輸出記錄的處理邏輯進行歸類,避免了記錄處理邏輯頻繁變化可能導致的代碼中過時字段和udf氾濫,可讀性下降,修改易出錯的問題。

drill處理邏輯前移

請看下面這個sql:

select * from druid.sqa_wireless_search_pv where INSTR(auction_tag, '15')

這個sql drill的處理邏輯是從druid表中召回druid.sqa_wireless_search_pv表中全部記錄後逐條進行auction_tag字段的比對,過濾出包含‘15’字符串的記錄,這種召回全部記錄進行處理的操作對於drill來說會造成很大的性能問題,佔用集群資源急劇上升,查詢延時大幅提高,甚至導致集群oom使查詢服務中斷服務。在使用drill進行查詢時應儘量避免執行類似召回大量記錄進行處理的sql,我們對親聽算法效果監控現有sql進行了梳理,找到召回記錄數目可能會過高的sql,通過將處理邏輯前移到blink任務階段大幅優化drill查詢性能(例如上面的sql只要將比對auction_tag字段是否含有‘15’的邏輯交給blink處理,並讓blink任務新增產出一個tag字段,這樣druid就可以針對tag字段建索引,通過where tag==‘true’這樣的語句就可以直接召回需要的記錄)

三、成果總結

目前tt->blink->hbase和tt->blink->tt->druid是在公司內使用非常廣泛的兩種實時流處理架構,能以秒級延時完成線上實時日誌處理,這兩種實時流處理架構比較好地滿足了親聽和全鏈路debug項目的實時數據處理需求,極大提升了項目價值

鷙鳥,來自搜索事業部-工程效率&技術質量-算法工程平臺-實時大數據平臺

15年加入阿里,主要從事電商體系實時數據研發以及實時大數據平臺研發

基於Blink構建親聽項目以及全鏈路debug項目實時響應能力


分享到:


相關文章: