實時資料產品實踐——美團大交通戰場沙盤
背景
大資料時代,資料的重要性不言而喻,尤其對於網際網路公司,隨著業務的快速變化,商業模式的不斷創新、使用者體驗個性化、實時化需求日益突出,海量資料實時處理在商業方面的需求越來越大。如何通過資料快速分析出使用者的行為,以便做出準確的決策,越來越體現一個公司的價值。現階段對於實時資料的建設比較單一,主要存在以下問題:
- 實時倉庫建設不足,維度及指標不夠豐富,無法快速滿足不同業務需求。
- 實時資料和離線資料對比不靈活,無法自動化新增對比基期資料,且對比資料無法預先生產。
- 資料監控不及時,一旦資料出現問題而無法及時監控到,就會影響業務分析決策。
因此,本文將基於美團點評大交通實時資料產品,從面臨的挑戰、總體解決方案、資料設計架構、後臺設計架構等幾個方面,詳細介紹實時資料系統的整體建設思路。
挑戰
實時流資料來源系統較多,處理非常複雜,並且不同業務場景對實時資料的要求不同,因此在建設過程主要有以下挑戰:
- 如何在保證資料準確性的前提下實現多實時流關聯;實時流出現延遲、亂序、重複時如何解決。
流式計算中通常需要將多個實時流按某些主鍵進行關聯得到特定的實時資料,但不同於離線資料表關聯,實時流的到達是一個增量的過程,無法獲取實時流的全量資料,並且實時流的達到次序無法確定,因此在進行關聯時需要考慮儲存一些中間狀態及下發策略問題。 - 實時流可複用性,實時流的處理不能只為解決一個問題,而是一類甚至幾類問題,需要從業務角度對資料進行抽象,分層建設,以快速滿足不同場景下對資料的要求。
- 中臺服務如何保證查詢效能、資料預警及資料安全。
實時資料指標維度較為豐富,多維度聚合查詢場景對服務層的效能要求較高,需要服務層能夠支援較快的計算能力和響應能力;同時資料出現問題後,需要做好及時監控並快速修復。 - 如何保證產品應用需求個性化。
實時資料與離線資料對比不靈活,需要提供可配置方案,並能夠及時生產離線資料。
解決思路
我們在充分梳理業務需求的基礎上,重新對實時流進行了建設,將實時資料分層建模,並對外提供統一的介面,保證資料同源同口徑;同時,在資料服務層,增加可配置資訊模組解決了配置資訊不能自動化的問題,在資料處理策略上做了多執行緒處理、預計算、資料降級等優化,在資料安全方面增加資料審計功能,更好地提升了產品的使用者體驗。
總體方案
產品整體建設方案基於美團點評技術平臺,總共分為源資料層、儲存層、服務層及WEB層,整體架構如下所示:
源資料層:主要提供三部分資料,實時資料、離線資料、配置資訊、維度資訊。
儲存層:源資料清洗後放入相應的儲存引擎中,為服務層提供資料服務。
服務層:提供三部分功能,資料API服務、預計算服務、許可權服務、資料審計服務。
Web層:使用Echarts視覺化資料。
資料層
資料架構
依託於美團點評提供的公共資源平臺,資料架構按功能分為資料採集、資料處理、資料儲存、資料服務四層,如下所示:
資料採集
資料來源主要有兩種:業務上報的Log日誌及資料庫Binlog日誌。這些日誌通過美團點評日誌中心進行採集後儲存在訊息中介軟體Kafka中,並按照不同的分類儲存在不同的Topic中,供下游訂閱。
資料處理
資料處理顧名思義,就是對採集的實時流進行邏輯處理,按業務需求輸出對應的實時資料,因此這一步驟是流式計算的關鍵,分兩步進行:資料加工、資料推送。
資料加工:資料加工通常需要在流式計算系統中進行,目前流行的流式處理系統主要有Storm、Spark Streaming系統及Flink系統,這些系統都能在不同的應用場景下發揮很好處理能力,並各有優缺點,如下圖所示:
計算框架 | 吞吐量 | 延遲 | 傳輸保障 | 處理模式 | 成熟度 |
---|---|---|---|---|---|
Storm | 低 | 毫秒級 | At least once | 單條處理 | 成熟 |
Spark Streaming | 高 | 秒級 | Exactly once | 微批處理 | 成熟 |
Flink | 高 | 毫秒級 | Exactly once | 單條處理/微批處理 | 新興 |
最終我們選擇Storm作為實時資料處理框架,並藉助公司提供的通用元件來簡化拓撲開發流程和重複程式碼編碼。例如,元件MTSimpleLogBolt的主要功能是將Kafka中讀取的資料(Log or Binlog)解析成Java實體物件;元件StormConfHelper的功能是獲取Storm作業應用配置資訊。
資料推送:將處理好的資料推送到儲存引擎中。
資料儲存
資料加工完成後會被儲存到實時儲存引擎中,以提供給下游使用。目前常用的儲存引擎主要有MySQL、Druid、Elasticsearch、Redis、Tair比較如下:
儲存引擎 | 優點 | 缺點 |
---|---|---|
MySQL | 使用簡單,支援資料量小 | 資料量大,對MySQL的壓力大,查詢效能慢 |
Druid | 資料預計算 | 不支援精確查詢 |
Elasticsearch | 查詢效率快,支援常用聚合操作;可以做到精確去重 | 查詢條件受限 |
Redis | 記憶體儲存KV,查詢效率高 | 寫入資源有限,不支援大資料量寫入 |
Tair | 持久化和非持久化兩種快取,查詢效率高 | 單節點效能比Redis較弱 |
Kylin | 多維查詢預計算 | 不支援實時 |
綜上比較,由於實時資料量較大,且資料精度要求較高,因此我們最終選擇交易儲存使用ES,流量儲存使用Druid,維度儲存使用Tair,中間資料儲存使用Redis;而離線資料,我們採用Hive和Kylin儲存。
資料服務
將儲存引擎資料統一對外提供查詢服務,支援不同業務應用場景。
具體實現
實時流處理流程
整個資料層架構上主要分為實時資料和離線資料兩部分:實時資料分為交易的Binlog日誌和流量的Log日誌,經過Strom框架處理後寫入Kafka,再經過DataLinkStreaming分別寫入ES和Druid;離線資料通過Hive處理寫入Kylin。
下圖所示為一條訊息的處理流程:
兩個Topic分別是order_base(主要存放訂單基本資訊:訂單id、訂單狀態、支付時間、票量、金額等);order_biz(主要存放訂單的擴充套件資訊:訂單id、訂單型別、出發時間、到達時間、出發城市、到達城市)。我們最終要拿到一條包括上述全部內容的一條記錄。
具體例子:Bolt在處理一條記錄時,首先判斷這條記錄是base還是biz,如果是base則寫入快取中base的Category中,如果是biz則寫入biz的Category中。以order_id為Key,如果是base則去和biz關聯,如果biz存在則代表能夠關聯上,這時傳送關聯後的完整資料,同時刪除該主鍵(order_key)記錄;如果biz中不存在,則說明沒關聯上,這時可能biz的資料延遲或者是丟失,為了保證主資料的準確性,這時我們只發送base的資料,快取中的資料保留不被刪除。如果這條訊息是biz,則首先會更新快取中該主鍵的biz記錄,然後去和base關聯,關聯上則傳送同時刪除base中資料,否則不傳送。此時我們會根據ES的Update特性去更新之前的資料。從現實效果來看保證了99.2%的資料完整性,符合預期。
資料寫入
在Topic2es的資料推送中,通過DataLinkString工具(底層Spark Streaming)實現了Kafka2es的微批次同步,一方面通過多併發batch寫入ES獲得了良好的吞吐,另一方面提供了5秒的實時寫入效率,保證了ES查詢的實時可見。同時我們也維護了Kafka的Offset,可以提供At lease once的同步服務,並結合ES的主鍵,可以做到Exactly once,有效解決了資料重複問題。
ES索引設計及優化
在資料寫入ES過程中,由於資料量大,索引時間區間長,在建設索引時需要考慮合理設計保證查詢效率,因此主要有以下三點優化:
- 寫入優化 在通過DataLinkString寫入ES時,在叢集可接受的範圍內,資料Shuffle後再分組,增加Client併發數,提升寫入效率。
- 資料結構化 根據需要設計了索引的模版,使用了最小的足夠用的資料型別。
- 按天建索引 通過模版按天建索引,避免影響磁碟IO效率,同時通過別名相容搜尋一致性。
- 設定合理的分片和副本數 如果分片數過少或過多都會導致檢索比較慢。分片數過多會導致檢索時開啟比較多的檔案,另外也會影響多臺伺服器之間通訊。而分片數過少為導至單個分片索引過大,所以檢索速度慢。在確定分片數之前需要進行單服務單索引單分片的測試。 我們根據 索引分片數=資料總量/單分片數 設定了合理的分片數。
實時資料倉庫模型
整個實時資料開發遵循大交通實時數倉的分層設計,在此也做一下簡單介紹,實時數倉架構如下:
ODS層:包含美團頁面流量日誌、模組事件日誌以及使用者操作的Binlog資訊日誌,是直接從業務系統採集過來的原始資料。
事實明細層:根據主題和業務過程,生成訂單事實和流量事實。
彙總層:對明細層的資料擴充套件業務常用的維度資訊,形成主題寬表。
App層:針對不同應用在彙總層基礎上加工擴充套件的聚合資料,如火車票在搶票業務下的交易資料彙總資訊。
規範建模後,業務需求來臨時,只需要在App層建模即可,底層資料統一維護。
中臺服務層
後臺服務主要實現 登陸驗證和許可權驗證(UPM)、指標邏輯計算和API、預計算服務、資料質量監控、資料審計功能。由於資料量大且實時性要求較高,在實現過程遇到如下挑戰:
- 如何保證查詢響應效能。
- 服務發生故障後,資料降級方案。
- 資料監控預警方案及資料出現問題解決方案。
針對以上問題,下面進行一一詳述:
效能響應優化
服務層處理資料過程中,由於資料量大,在查詢時需要一定的響應時間,所以在保證響應效能方面,主要做了以下優化:
- 專案初始由於資料量不是很大,採用單執行緒直接查詢ES,能夠滿足需求。
- 隨著節假日來臨,資料量大增,並行查詢人次增多,查詢響應變慢,無法快速響應結果,因此引入快取技術,將中間結果進行快取,並在快取有效期內,直接讀取快取資料大大提高了時間效率;並且在此基礎上,引入Master-Worker多執行緒模式,將多指標查詢拆分,並行查詢ES,使得查詢響應大大提高。
- 雖然問題得到解決,但仍存在一個問題,就是每次都是現查ES及部分中間快取結果,尤其是第一次查詢,需要完全走ES,這樣就會讓第一個查詢資料的使用者體驗較差,因此引入預計算服務,通過定時排程任務,將部分重要維度下的指標進行預計算放入快取,使用者查詢時直接讀取快取資料。而一些不常用的維度下的資料,採用的策略是,第一個使用者查詢時現查ES,並將結果資料預載入到快取,後續所有使用者再次查詢直接讀快取資料,這樣既能保證使用者體驗,也不至於佔用太多快取空間。
資料降級方案
使用快取避免不了出現一些問題,比如快取失效、快取雪崩等問題,針對快取雪崩問題,通過設定不同Key的過期時間能夠很好的解決;而對於快取資料失效,我們有自己的資料降級方案,具體方案如下:
預計算資料會分別在Redis、Tair和本地快取中儲存一份以保證查詢效率,當查詢Redis資料不存在時,會去Tair中讀取資料,Tair也為空時,會讀取本地快取,只有當本地快取資料也為空時,才會現查ES做聚合計算,這樣也會降低ES的查詢壓力。
資料監控
實時監控預警非常重要,在資料出現問題時,一方面能夠及時通知我們快速定位修復資料,另一方面也能夠及時周知業務同學,避免做出錯誤分析。基於此,我們做了兩方面的實時監控,其一是對源實時流在Storm處理層面的監控,確保源實時流正確生產;其二是對展示的彙總資料進行監控,確保產品展示指標資料正常。
針對資料出現問題預警,我們在解決方案上規範了流程:
- 監控報警機制及時周知相關同學。
- 第一時間通過產品上方的黃條提示使用者哪些資料異常。
- 快速定位問題,給出修復方案。
目前對於實時異常資料的修補,主要有兩種方法:
a. 針對特殊情況的資料修補方案第一靈活指定Offset,重新消費Kafka資料。
b. 預留了Hive2es的準實時重導功能,確保生產資料的準確和完整。
資料安全
在以資料取勝的時代,資料的安全不言而喻,我們採用公司提供的UPM許可權介面進行二級許可權管理並加入審計功能及水印功能,能夠準確記錄使用者的所有訪問以及操作記錄,並且將日誌資料格式化到資料庫中,進行實時監控分析。
總結
實時資料可以為業務特定場景分析決策提供巨大支援,尤其對於大交通節假日及春運期間。在大交通實時戰場沙盤產品化過程中,我們投入了大量的思考和實踐,主要取得以下收益:
- 視覺化的產品,為業務方實時分析提供極大便利,取得較好的反饋。
- 優化實時資料倉庫建設,合理分層建模,規範命名設計,統一維度建設和指標口徑,對外提供統一介面,保證資料規範準確。
- 在Storm框架下實時開發和資料寫入方面積累了一定的經驗。
- 服務層支援可配置資訊,可以靈活配置個性化資訊。
- 服務層效能及獲取資料策略的優化,為使用者帶來更好的產品體驗。
加入我們
最後插播一個招聘廣告,我們是一群擅長大資料領域資料建設、數倉建設、資料治理及資料BI應用建設的工程師,期待更多能手加入,感興趣的可以投遞個人簡歷到郵箱:yangguang09#meituan.com,歡迎您的加入。
作者介紹
娣娣,美團點評資料開發工程師,2015年加入美團,從事資料倉庫建設、大資料產品開發工作。
曉磊,美團點評資料開發工程師,2017年加入美團,從事資料倉庫建設、大資料產品開發工作。