美團大交通實時數據倉庫實踐

背景

大數據時代,數據的重要性不言而喻,尤爲對於互聯網公司,隨着業務的快速變化,商業模式的不斷創新、用戶體驗個性化、實時化需求日益突出,海量數據實時處理在商業方面的需求愈來愈大。如何經過數據快速分析出用戶的行爲,以便作出準確的決策,愈來愈體現一個公司的價值。現階段對於實時數據的建設比較單一,主要存在如下問題:數據庫

  1. 實時倉庫建設不足,維度及指標不夠豐富,沒法快速知足不一樣業務需求。
  2. 實時數據和離線數據對比不靈活,沒法自動化新增對比基期數據,且對比數據沒法預先生產。
  3. 數據監控不及時,一旦數據出現問題而沒法及時監控到,就會影響業務分析決策。
    所以,本文將基於美團大交通實時數據產品,從面臨的挑戰、整體解決方案、數據設計架構、後臺設計架構等幾個方面,詳細介紹實時數據系統的總體建設思路。

挑戰

實時流數據來源系統較多,處理很是複雜,而且不一樣業務場景對實時數據的要求不一樣,所以在建設過程主要有如下挑戰:緩存

  1. 如何在保證數據準確性的前提下實現多實時流關聯;實時流出現延遲、亂序、重複時如何解決。
    流式計算中一般須要將多個實時流按某些主鍵進行關聯獲得特定的實時數據,但不一樣於離線數據表關聯,實時流的到達是一個增量的過程,沒法獲取實時流的全量數據,而且實時流的達到次序沒法肯定,所以在進行關聯時須要考慮存儲一些中間狀態及下發策略問題。
  2. 實時流可複用性,實時流的處理不能只爲解決一個問題,而是一類甚至幾類問題,須要從業務角度對數據進行抽象,分層建設,以快速知足不一樣場景下對數據的要求。
  3. 中臺服務如何保證查詢性能、數據預警及數據安全。
    實時數據指標維度較爲豐富,多維度聚合查詢場景對服務層的性能要求較高,須要服務層可以支持較快的計算能力和響應能力;同時數據出現問題後,須要作好及時監控並快速修復。
  4. 如何保證產品應用需求個性化。
    實時數據與離線數據對比不靈活,須要提供可配置方案,並可以及時生產離線數據。

解決思路

咱們在充分梳理業務需求的基礎上,從新對實時流進行了建設,將實時數據分層建模,並對外提供統一的接口,保證數據同源同口徑;同時,在數據服務層,增長可配置信息模塊解決了配置信息不能自動化的問題,在數據處理策略上作了多線程處理、預計算、數據降級等優化,在數據安全方面增長數據審計功能,更好地提高了產品的用戶體驗。安全

整體方案

產品總體建設方案基於美團技術平臺,總共分爲源數據層、存儲層、服務層及WEB層,總體架構以下所示:服務器

 

圖1 總體架構圖數據結構

源數據層:主要提供三部分數據,實時數據、離線數據、配置信息、維度信息。
存儲層:源數據清洗後放入相應的存儲引擎中,爲服務層提供數據服務。
服務層:提供三部分功能,數據API服務、預計算服務、權限服務、數據審計服務。
Web層:使用Echarts可視化數據。多線程

數據層

數據架構

依託於美團提供的公共資源平臺,數據架構按功能分爲數據採集、數據處理、數據存儲、數據服務四層,以下所示:架構

 

圖2 數據架構圖併發

數據採集

數據來源主要有兩種:業務上報的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。

 

圖3 產品數據架構

下圖所示爲一條消息的處理流程:

 

圖4 數據關係

兩個Topic分別是order_base(主要存放訂單基本信息:訂單id、訂單狀態、支付時間、票量、金額等);order_biz(主要存放訂單的擴展信息:訂單id、訂單類型、出發時間、到達時間、出發城市、到達城市)。咱們最終要拿到一條包括上述所有內容的一條記錄。

 

圖5 數據處理流程

具體例子: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效率,同時經過別名兼容搜索一致性。
  • 設置合理的分片和副本數 若是分片數過少或過多都會致使檢索比較慢。分片數過多會致使檢索時打開比較多的文件,另外也會影響多臺服務器之間通信。而分片數過少爲導至單個分片索引過大,因此檢索速度慢。在肯定分片數以前須要進行單服務單索引單分片的測試。 咱們根據 索引分片數=數據總量/單分片數 設置了合理的分片數。

實時數據倉庫模型

整個實時數據開發遵循大交通實時數倉的分層設計,在此也作一下簡單介紹,實時數倉架構以下:

圖6 實時數倉架構

ODS層:包含美團頁面流量日誌、模塊事件日誌以及用戶操做的Binlog信息日誌,是直接從業務系統採集過來的原始數據。
事實明細層:根據主題和業務過程,生成訂單事實和流量事實。
彙總層:對明細層的數據擴展業務經常使用的維度信息,造成主題寬表。
App層:針對不一樣應用在彙總層基礎上加工擴展的聚合數據,如火車票在搶票業務下的交易數據彙總信息。

規範建模後,業務需求來臨時,只須要在App層建模便可,底層數據統一維護。

中臺服務層

後臺服務主要實現 登錄驗證和權限驗證(UPM)、指標邏輯計算和API、預計算服務、數據質量監控、數據審計功能。因爲數據量大且實時性要求較高,在實現過程遇到以下挑戰:

  • 如何保證查詢響應性能。
  • 服務發生故障後,數據降級方案。
  • 數據監控預警方案及數據出現問題解決方案。

針對以上問題,下面進行一一詳述:

性能響應優化

服務層處理數據過程當中,因爲數據量大,在查詢時須要必定的響應時間,因此在保證響應性能方面,主要作了如下優化:

 

圖7 性能響應優化

  1. 項目初始因爲數據量不是很大,採用單線程直接查詢ES,可以知足需求。
  2. 隨着節假日來臨,數據量大增,並行查詢人次增多,查詢響應變慢,沒法快速響應結果,所以引入緩存技術,將中間結果進行緩存,並在緩存有效期內,直接讀取緩存數據大大提升了時間效率;而且在此基礎上,引入Master-Worker多線程模式,將多指標查詢拆分,並行查詢ES,使得查詢響應大大提升。
  3. 雖然問題獲得解決,但仍存在一個問題,就是每次都是現查ES及部分中間緩存結果,尤爲是第一次查詢,須要徹底走ES,這樣就會讓第一個查詢數據的用戶體驗較差,所以引入預計算服務,經過定時調度任務,將部分重要維度下的指標進行預計算放入緩存,用戶查詢時直接讀取緩存數據。而一些不經常使用的維度下的數據,採用的策略是,第一個用戶查詢時現查ES,並將結果數據預加載到緩存,後續全部用戶再次查詢直接讀緩存數據,這樣既能保證用戶體驗,也不至於佔用太多緩存空間。

數據降級方案

使用緩存避免不了出現一些問題,好比緩存失效、緩存雪崩等問題,針對緩存雪崩問題,經過設置不一樣Key的過時時間可以很好的解決;而對於緩存數據失效,咱們有本身的數據降級方案,具體方案以下:

 

圖8 數據降級方案

預計算數據會分別在Redis、Tair和本地緩存中存儲一份以保證查詢效率,當查詢Redis數據不存在時,會去Tair中讀取數據,Tair也爲空時,會讀取本地緩存,只有當本地緩存數據也爲空時,纔會現查ES作聚合計算,這樣也會下降ES的查詢壓力。

數據監控

實時監控預警很是重要,在數據出現問題時,一方面可以及時通知咱們快速定位修復數據,另外一方面也可以及時周知業務同窗,避免作出錯誤分析。基於此,咱們作了兩方面的實時監控,其一是對源實時流在Storm處理層面的監控,確保源實時流正確生產;其二是對展現的彙總數據進行監控,確保產品展現指標數據正常。
針對數據出現問題預警,咱們在解決方案上規範了流程:

  1. 監控報警機制及時周知相關同窗。
  2. 第一時間經過產品上方的黃條提示用戶哪些數據異常。
  3. 快速定位問題,給出修復方案。
    目前對於實時異常數據的修補,主要有兩種方法:
    a. 針對特殊狀況的數據修補方案第一靈活指定Offset,從新消費Kafka數據。
    b. 預留了Hive2es的準實時重導功能,確保生產數據的準確和完整。

數據安全

在以數據取勝的時代,數據的安全不言而喻,咱們採用公司提供的UPM權限接口進行二級權限管理並加入審計功能及水印功能,可以準確記錄用戶的全部訪問以及操做記錄,而且將日誌數據格式化到數據庫中,進行實時監控分析。

總結

實時數據能夠爲業務特定場景分析決策提供巨大支持,尤爲對於大交通節假日及春運期間。在大交通實時戰場沙盤產品化過程當中,咱們投入了大量的思考和實踐,主要取得如下收益:

    1. 可視化的產品,爲業務方實時分析提供極大便利,取得較好的反饋。
    2. 優化實時數據倉庫建設,合理分層建模,規範命名設計,統一維度建設和指標口徑,對外提供統一接口,保證數據規範準確。
    3. 在Storm框架下實時開發和數據寫入方面積累了必定的經驗。
    4. 服務層支持可配置信息,能夠靈活配置個性化信息。
    5. 服務層性能及獲取數據策略的優化,爲用戶帶來更好的產品體驗。
相關文章
相關標籤/搜索