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

1、背景介紹

1.1親聽項目前端

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

需求要點能夠總結以下:sql

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

1.2全鏈路debugjson

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

需求要點能夠總結以下:api

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

2、解決方案

2.1總體架構架構

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

親聽:運維

全鏈路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’這樣的語句就能夠直接召回須要的記錄)

3、成果總結

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

感興趣的能夠本身來個人Java架構羣,能夠獲取免費的學習資料,羣號:855801563對Java技術,架構技術感興趣的同窗,歡迎加羣,一塊兒學習,相互討論。

相關文章
相關標籤/搜索