Categories
程式開發

攜程機票數據倉庫建設之路


一、前言

隨著大數據技術的飛速發展,海量數據存儲和計算的解決方案層出不窮,生產環境和大數據環境的交互日益密切。數據倉庫作為海量數據落地和扭轉的重要載體,承擔著數據從生產環境到大數據環境、經由大數據環境計算處理回饋生產應用或支持決策的重要角色。

數據倉庫的主題覆蓋度、性能、易用性、可擴展性及數據質量都是衡量數據倉庫解決方案好壞的重要指標。攜程機票部門數據倉庫也在不斷摸索向著這些目標砥礪前行。

二、攜程機票數據倉庫技術棧

攜程機票部門的數據倉庫建設主要基於公司公共部門的大數據基礎環境及數據調度平台,輔以部分自運維的開源存儲引擎和基於開源組件二次開發的數據同步工具和運維工具。

2.1 數倉技術演進歷史

機票部門的數據倉庫源於2008年,當時生產環境數據落地主要使用SQLServer,數據倉庫處理的目標數據體量不大,因此選擇的SQLServer、Informaticas、Kettle這樣的數據倉庫方案,數據模型設計及報表定制使用SAP的商用平台BO。

隨著機票業務系統的日益複雜,特別是生產環境引入消息中間件Kafka存儲日誌數據後,這套方案不可擴展性的缺點日趨明顯,SQLServer的存儲和計算能力很大程度上限制了數倉數據的主題覆蓋度及性能。

在2014年,公司公共部門hadoop集群部署上線,並且引入了zeus調度平台及DataX同步工具,各個BU的數據倉庫開始逐步轉為基於Hive建設。

隨著生產業務對實時監控、流量回放的需求增強,2016年機票部門部署了ElasticSearch,用以實時落地從Kafka同步的各個主流程服務日誌,並通過統一的交易標識(transactionID) 串聯用戶的一次完整的搜索、下單等行為,用於生產排障和流量回放。基於Hive的搜索性能一直被廣泛詬病,特別是針對adhoc查詢,機票部門在2016年調研並部署了Facebook開源的基於內存和Pipeline的查詢引擎Presto,在沒有享受到local數據獲取的前提下,查詢性能較原生的Hive引擎或者Spark引擎都有很大的提升。

在2018年,為了支持數倉數據的可視化運營平台,我們先後引入了ClickHouse和CrateDB作為後台的存儲和查詢引擎,特別是引入CrateDB以後,億級體量的表四個維度的聚合耗時P90下降到了4秒。

實時數據處理技術也經過了Esper,Storm,Spark Streaming和Flink的迭代,並慢慢收斂到Flink。總體的技術演進歷史如圖1所示。

攜程機票數據倉庫建設之路 1

圖1 數倉技術演進歷史

2.2 當前技術棧

生產環境的數據可以大致分成三類:

1)業務數據,主要存儲在MySQL和SQLServer,在這些關係型數據庫裡面有數以萬計的表承接著各種生產服務的業務數據寫入;

2)基礎數據,也是存儲在MySQL和SQLServer中,生產應用時一般會建立一層中心化緩存(如Redis)或者本地緩存;

3)日誌數據,這類數據的特點是”append only”,對已經生成的數據不會有更新的操作,考慮到這類數據的高吞吐量,生產環境一般會用消息隊列Kafka暫存;

數據倉庫在實施數據同步時,會根據需求在實時、近實時以及T+1天等不同的頻率執行數據同步,並且在大數據環境會用不同的載體承接不同頻率同步過來的數據。在攜程機票,實時同步的目標載體是ElasticSearch、CrateDB或者HBase,近實時(一般T+1小時)或者T+1天的目標載體是Hive。

從生產的數據載體來講,主要包括DB和消息隊列,他們的數據同步方案主要是:

1)生產DB到Hive的同步使用taobao開源的DataX,DataX由網站運營中心DP團隊做了很多擴展開發,目前支持了多種數據源之間的數據同步。實時同步的場景主要在MySQL,使用DBA部門使用Canal解析並寫入至消息隊列的bin log。

2)從Kafka到Hive同步使用Camus,但是由於Camus的性能問題及消費記錄和消費過期較難監控的問題,我們基於spark-sql-kafka開發了hamal,用於新建的Kafka到Hive的同步;Kafka實時同步的載體主要是ElasticSearch或者CrateDB,主要通過Flink實施。

生產數據被同步數據倉庫後,會在數倉內完成數據清洗、信息整合、聚合計算等數據扭轉流程,最終數據出倉導入到其它載體,這一系列的流程調度由公司DP團隊運維的調度平台Zeus完成。

攜程機票數據倉庫建設之路 2

圖2 攜程機票數倉技術棧

2.3 實時 VS 離線

當前機票部門的數據倉庫建設主要基於離線數據,一方面跟OTA銷售產品不屬於快消品相關,實時當前並不是剛需;另一方面實時處理場景下需要對計算資源、存儲資源穩定性有更高的要求,保持數據一致性的代價很大。結合兩方面,如果業務對實時需求不高就鋪開做實時數倉,ROI很難達標。

當然,隨著攜程業務體量的增長,數據使用方對數據實時性要求日益增高,我們團隊在2020年也會探索實時數據倉庫的實施方案,並在一兩個重要的數據主題域上先行試點。

三、數據倉庫建設時涉及的共性問題

從團隊職能上來講,數據倉庫團隊需要負責從生產環境同步數據,在內部完成各層級的扭轉計算,參與所有數倉流程及報表的運維,並基於數倉公共數據層和應用數據層數據開發相關應用。

3.1 數據同步

為了保持數倉數據主題覆蓋足夠全面,我們部門幾乎將所有生產表和Kafka topics都同步到了Hive。以下會對同步最常見的兩種場景DB->Hive和Kafka->Hive相關的實踐做介紹。

3.1.1 DB同步到Hive

特別對生產表到Hive的同步,人工配置腳本的方式顯然不能處理數以萬計的表,因此需要一個自動化的同步方案。自動同步方案需要不僅僅要解決自動創建表腳本、創建對應的同步腳本問題,還需要在當表結構發生變更的時候,能夠自動地感知表結構的變化,並且修改表結構和對應的同步腳本。

DB到Hive同步需要依賴兩個數據源,1)Schema表的元數據信息,簡單地包括各個字段信息、字段類型及主鍵定義;2)統計數據,它主要描述的是這個表在數據產生後有沒有UPDATE和DELETE,這個決定著後續表的分區方式。

對業務型數據,一條數據生成後可能會有Update,因為在數倉裡絕大部分場景需要用到數據的最新狀態,所以我們會用一個分區存放所有歷史數據的最新狀態,這類表我們稱之為歷史切片表。對日誌型數據,生產上數據產生後就不會有任何修改,我們會選擇使用增量分區,每個分區會放當天的增量數據。對基礎數據,整個表的數據增加、更新的頻率都非常低,在ods層我們會每天全量同步一份到最新數據分區,並且會建立一個無分區的下游維表,將數據狀態為有效的數據放到這張下游無分區維表中方便流程使用。

有了上述這兩個數據源以後,我們會根據DBA Schema服務返回的元數據信息生成Hive表的腳本,並調度執行生成新的Hive表,再依據統計數據決定表的分區方式,進而生成對應新建表的同步腳本。當表創建或者表結構發生變更的時候,通過Schema服務兩天輸出的比對,我們會發現表結構的變更並映射到對應Hive表結構變更,同時可以改變對應的同步腳本。還有一種思路是可以通過DB發布系統的日誌,獲知每天DB創建、表創建以及表結構變化的增量。

攜程機票數據倉庫建設之路 3

圖3 生產DB到Hive的同步

有一個坑點就是生產物理刪除,如果出現了物理刪除並且需要在Hive表裡將刪除數據識別並標記出來,當前可能需要通過全量同步的方法(考慮到從生產環境取數的代價,全量同步業務主鍵字段即可)解決,特別對SQLServer。因此可以跟生產的開發協商盡量使用邏輯刪除,這樣數倉對刪除數據的感知代價會小很多。

3.1.2 Kafka同步到Hive

當前我們非實時同步主要在使用Linkedin很久以前的一個工具Camus,當然DP團隊經過優化和企業本地化二次開發。但從使用感受來看,Camus會有如下可能不足的地方:

1)基於mapreduce,mapreduce在yarn集群上搶占資源的能力較弱,在資源競爭高峰會有同步變慢的情況發生;

2)消費記錄存儲在HDFS各個文件裡,這樣對消費記錄的獲取和針對消費過期的監控都很不方便;

3)Kafka Topic和Hive表的血緣關係獲取不方便;

因此,我們基於spark-sql-kafka開發hamal,旨在解決如上痛點並且讓配置更加的簡潔。實現的過程大概包括,spark-sql-kafka會根據輸入的任務從Kafka各個Partition消費出payload數據,對每條payload執行解編碼、解壓、magic code等操作,此時會將payload數據轉化成json字符串,這個json字符串可以直接作為一個字段寫入到Hive表裡,也可以根據事先配置提取出對應的節點和值作為列和列值寫入到Hive中,甚至可以通過Json的Schema推斷出Hive表結構,並將Json各節點對應寫到Hive表的各列中。

攜程機票數據倉庫建設之路 4

圖4 轉化為json字符串RDD代碼示例

如果選擇推斷的模式,實現的時候可以使用sampling的方式,類似spark jsonRDD第二個參數,比如說0.001,Hamal可以直接指定採樣數據條數,從Kafka topic中拉取出來,通過jsonRDD推斷出StructType,並映射成Hive建表語句。對於建好的表,通過表的字段匹配獲取數據,最終寫入Hive表,最後會提交消費記錄到一張Hive的ConsumerRecord表裡面。這樣其實基於這個表,我們既可以獲取Kafka topic和Hive表的血緣,也可以方便地監控每次同步的數據量。

攜程機票數據倉庫建設之路 5

圖5 Kafka同步至Hive Hamal設計

3.2 數倉分層

分層設計主要參考公司推行的數據規範,將數據倉庫的流程分成了生產鏡像層(ods)、中間層(edw)、公共數據層(cdm)及應用數據層(adm)。在中間層對ods表做異常數據剔除、NULL值處理、枚舉值統一等數據清理和綁定維表信息工作,在公共數據層對中間層表進行進一步的整合,豐富表主題的維度和度量,一般以寬表的形式呈現,用以後續的adhoc取數、報表。

根據機票本身的業務特點,我們將數據劃分成流量、產量、收益、生產KPI、業務考核等幾大主題域,對數據表的業務分類和有效管理有重要意義。

攜程機票數據倉庫建設之路 6

圖6 數倉分層設計

3.3 數據解析

數據在同步至數據ods層後,產品經常會提的一個需求是將ods層某個含報文字段的表按照字段設計展開,如果要支持此類需求,數據開發就需要了解生產上這個表各個字段含義及報文字段的契約定義,而這些對應表的寫入開發非常熟悉。因此,為了提高整體的工作效率,我們開發了一套數據解析框架,對業務開發封裝了大數據組件的API調用及相關參數調整,讓業務開發更高效地完成熟悉的單條數據解析開發。

攜程機票數據倉庫建設之路 7

圖7 數據解析框架

3.4 數倉運維工具

數據倉庫擁有所有生產表的鏡像表、數以萬計的生產數據同步流程、數據扭轉流程以及後續報表,對如此規模的數倉實體的管理和運維需要一個不斷迭代的系統支持,從而可以大幅度提高數據工程師的效率。

我們根據數倉建設中遇到的一些費力度較高且需要重複做的操作,開發了一套運維工具集合,目前還在持續迭代中。運維工具集功能主要包括數據實體通用搜索,報表收件人批量變更,維表導入,Oncall錄入,腳本模板生成,序列化與反序列化等等。工具開發難度不大,但對提高效率的幫助很大。

四、數據質量體系

對龐大的數據倉庫實體建設完善的數據質量監控體系,光靠人工one by one設置檢驗規則是不夠的,需要對幾乎所有的實體建立相應的監控,並且不能給大數據集群帶來很多額外的計算代價。當這樣的覆蓋面很廣的監控完善後,配合著元數據信息,就有可能在故障的Root Cause點第一時間發現故障,並可以清晰地知曉故障的影響範圍以及故障恢復的流程優先級調度。

因此,建立完善的數據質量體系需要完善元數據管理,建立輕量的覆蓋面廣的質量監控,並且對特別重要的流程,需要增加額外的業務相關校驗。

4.1 元數據管理

在生產環境和大數據環境存在多種實體,這些實體包括應用、各類表(如SQLServer、MySQL、MongoDB的表等)、消息隊列topic、ElasticSearch的index、Hive的表等等,這些實體相互關聯,共同支撐著線上的系統,線下的分析。對這些信息的治理,實體的元數據管理至關重要。

在數倉體系中,元數據主要包含基礎信息、血緣關係以及標籤。基礎信息跟數據表相關,具體包括表的字段、存儲、分區類型等;血緣會涉及到各類的實體,表、流程、報表、郵件推送等,這些實體之間存在著上下游調用與被調用關係,成體系地管理好這些實體之間的關係,可以清晰地了解到數倉邊界,使得對故障的Root Cause追溯以及該Root Cause帶來的影響面評估非常便捷。標籤是對實體的分類描述,如層級是屬於哪一層,安全是否有涉密,重要等級,是否有非常重要的流程在上面,業務標籤是屬於訂單、前端還是訂後。

4.2 數據質量相關因素

數據質量的問題其實一般可以在流程執行的日誌中看出端倪,因為人工排查故障的時候,除了常規通過SQL查詢驗證表的增量、業務主鍵、某些字段值是否正常,另外一個有效手段就是分析運行日誌。

從運行日誌中可以獲取以下信息,流程的開始時間、截止時間流程執行時間、完成狀態、每天增量的字節數、增量條數,引擎執行的參數,在用Spark或者MapReduce執行時消耗資源的情況等等一系列特徵。通過對各類計算引擎產生日誌的分析,可以獲得各類引擎下記錄日誌數據的pattern,從而提取出相關的特徵信息。遇到特殊的流程或者引擎,可以藉用其他手段補齊特徵數據,如用SQL,用Hadoop的命令。

攜程機票數據倉庫建設之路 8

圖8 數據質量相關特徵

這是我們簡單的一個日誌輸出,第一張是Spark的執行日誌,下面一張是MapReduce的執行日誌。

攜程機票數據倉庫建設之路 9

攜程機票數據倉庫建設之路 10

圖9 MR和Spark引擎執行日誌示例

有了數據質量特徵提取的邏輯,實時流程異常發現可以如下實施:我們可以將質量特徵數據計算分成兩塊,一塊是實時的針對單個流程日誌的解析出相關特徵,一塊是離線的基於歷史特徵數據的統計。我們從消息隊列中消費實時獲取執行完成的流程id和actionid,通過運維團隊提供的詳情日誌查詢接口獲取完整日誌,通過特徵解析邏輯,解析出實時的流程質量相關特徵,匹配歷史數據,應用規則。當滿足異常規則,可以通過元數據信息中的血緣判斷影響的範圍,推送告警信息。

攜程機票數據倉庫建設之路 11

圖10 實時流程異常監控實施方案

五、應用案例

攜程作為平台方,對機票價格沒有定價權,價格由產品提供方來提供。在每年航班計劃換季的時候,產品提供方會有一小部分概率將價格錄入錯。錯誤的運價,特別是很低的錯誤運價會讓航司或供應商蒙受超大的損失。本著公平交易的原則,攜程作為銷售平台,做了機票價格監控系統。上線至今,發現了數十起價格異常事件。

在生產的消息隊列中,我們落地了用戶查詢返回的所有航班組合和價格信息,數據倉庫完成近實時同步,將數據解析處理成異常價格相關特徵集,每天的增量在百億級別。我們從Kafka實時消費兩類日誌數據,一類是查詢日誌,一類是下單日誌,建立匹配,建立規則集發現可疑的低價交易標識,並且進一步監控跟交易標識是否進入下單流程。當某個疑似異常特徵帶來的訂單超過一定閾值時,系統會對這疑似異常特徵對應的查詢進行自動禁售。

攜程機票數據倉庫建設之路 12

圖11 價格監控系統

六、小結

一套完整的數據倉庫實施方案應該包括但不局限於上面介紹的數據同步方案、數據存儲方案、數據規範、元數據建設、數據質量體系、運維工具等,每個實施團隊應該根據面臨的實際情況選擇針對每個點的具體技術方案。

攜程機票數據倉庫團隊也正朝著建設全面、規範、易用、高效、精準的數倉路上探索前行,當前在數據同步、數倉數據扭轉以及出倉應用方面的實踐方案還在隨著需求的變化而迭代。接下來,我們團隊會著重在數據倉庫規範徹底落地以及實時數倉實施這些方向上努力。

致謝

數據倉庫建設離不開各兄弟團隊的大力支持和配合,感謝機票大數據基礎架構團隊和公司DP團隊在機票數倉實踐過程中提供的平台、工具、運維、接口方面的支持。

作者介紹

華智,攜程高級研發經理,現負責數據倉庫技術架構、性能優化、數倉規範制定、數據模型設計以及數據應用開發。

本文轉載自公眾號攜程技術(ID:ctriptech)。

原文鏈接

https://mp.weixin.qq.com/s?__biz=MjM5MDI3MjA5MQ==&mid=2697269396&idx=1&sn=7f16f0df1a8550a49c9a1687a83a5470&chksm=8376efa0b40166b6908b08a6e92286d25819adfa969f8252be1bbfbbc0e13c43459741397906&scene=27#wechat_redirect