萬億資料秒級響應,Doris在360數科實時數倉中的優秀實踐

陶然陶然發表於2022-12-01

   導讀:隨著業務的不斷髮展,360數科對資料的安全性、準確性、實時性提出了更嚴格的要求,亟需對實時數倉架構做出最佳化和重構。基於此,2022年3月正式對 Apache Doris 調研並投入使用,當前已穩定支援多條業務線,支援萬億級別資料量實現秒級實時分析。360數科將透過本文與大家分享在數倉最佳化重構過程中應用、最佳化經驗,希望對大家有所幫助。

  作為以人工智慧驅動的金融科技平臺,360數科攜手金融合作夥伴,為尚未享受到普惠金融服務的優質使用者提供個性化的網際網路消費金融產品,致力於成為連線使用者與金融合作夥伴的科技平臺。360數科旗下產品主要有 360借條、360小微貸、360分期等,截止目前,已累計幫助 141 家金融機構為 4300 萬使用者提供授信服務、為 2630 萬使用者提供借款服務、單季促成交易金額 1106.75 億元。同時作為國內領先的信貸科技服務品牌,360數科在三季度累計註冊使用者數突破 2 億。

   業務需求

  隨著金融科技業務的不斷髮展,對資料的安全性、準確性、實時性提出了更嚴格的要求,早期 Clickhouse 叢集用於分析、標籤業務場景,但是存在穩定性較低、運維複雜和表關聯查詢較慢等問題,除此之外,我們業務中有部分報表資料分散儲存在各類 DB 中,這也導致維護管理複雜度較高,亟需做出最佳化和重構。

   系統選型

  基於以上需求及痛點,我們對實時數倉的選型目標提出了明確的需求,我們希望新的 MPP 資料庫具有以下幾個特點:

  資料寫入效能高,查詢秒級

  相容標準的 SQL 協議

  表關聯查詢效能優秀

  豐富的資料模型

  運維複雜度低

  社群活躍

  對商業友好,無法律風險

  2022 年 3 月開始,我們對符合以上特點的資料庫 Apache Doris 展開了為期兩個月的調研測試,以下是 Apache Doris 1.1.2 在各個方面的滿足情況:  

  基於上述情況,我們決定採用 Apache Doris,除了可以滿足上文提到的幾個特點,我們還考慮以下幾個方面:

  Clickhouse 由於 Join 查詢限制、函式侷限性、資料模型侷限性(只插入,不更新)、以及可維護性較差等原因,更適合日誌儲存以及保留當前存量業務,不滿足我們當前的業務需求。

  目前Apache Doris 社群活躍、技術交流更多,SelectDB 針對社群有專職的技術支援團隊,在使用過程中遇到問題均能快速得到響應解決。

  Apache Doris 風險更小,對商業友好,無法律風險。大資料領域 Apache 基金會專案構成了事實標準,在 360數科內部已有廣泛應用,且 Apache 開源協議對商業友好、無法律風險,不會有協議上的顧慮。

   平臺架構

  360數科大資料平臺(毓數)提供一站式大資料管理、開發、分析服務,覆蓋大資料資產管理、資料開發及任務排程、自助分析及視覺化、統一指標管理等多個資料生命週期流程。在整個 OLAP 中,目前 Apache Doris 主要運用離線數倉分析加速、自助 BI 報表等業務場景。  

  在引入 Doris 後,考慮已有資料分析業務以及資料規模,Doris 叢集將先同步部分業務上優先順序更高的資料。透過上述架構圖可以看到,依託 Doris 強大的查詢效能,我們將把 Doris 架設在 Hive 數倉的上層,為特定場景進行查詢加速,這樣的架構建設起來成本很低,只需要完成資料從 Hive 數倉到 Doris 叢集的匯入適配,因為 Doris 叢集並沒有產生任何新表,可以直接複用已經建設好的資料血緣關係。

  資料匯入方案,我們在調研了 Stream Load 和 Broker Load ,從匯入效能、開發成本上進行了評估,在匯入效能上,Broker Load 要比 Stream Load 略勝一籌,而在開發成本上兩種方式並沒有明顯的差異。而且對於大表的同步,Broker Load 的匯入方式可以做到單表一次匯入一個事務,而 Stream Load 在單表資料量超 10G 時則需要拆分後進行資料匯入。因此資料匯入選擇使用 Broker Load 來進行。

  數倉即席查詢方案,我們自行開發的查詢引擎支援多查詢引擎動態切換的機制,透過識別查詢資料的元資訊對本次查詢做自動的查詢引擎(Doris/Presto/Spark/Hive)路由和故障切換。

  Doris 支援原生 MySQL 協議,對標準 SQL 支援良好,使得 Doris 可以和一些 BI 工具(帆軟、觀遠等)無縫結合,因此單獨搭建了一個 Doris 報表分析叢集作為 BI 工具資料來源。

   應用實踐

  Doris 對 Hive 數倉的加速方案

  在即席查詢場景中,傳統的查詢引擎(Hive/Spark/Presto)越來越滿足不了資料開發者、資料分析師對查詢響應效能提出的高要求,動輒幾十秒甚者分鐘級的查詢耗時極大的限制了相關場景的開發效率。

  為提高查詢效能,我們透過架設的 Doris 數倉加速層來縮短查詢耗時,目前我們在不開啟 Doris 快取、不開啟用物化檢視等最佳化策略的情況下,命中 Doris 即席查詢平均耗時即可從幾分鐘縮短至 5 秒內。

  未來我們將透過分析相關查詢的特徵,透過開啟快取、建立相關物化檢視等策略來進一步最佳化 Doris 的查詢效能。  

  實現 Doris 加速的核心是支援查詢引擎動態切換,查詢引擎動態切換的工作機制如下:  

  查詢引擎會及時收集 Hive 和 Doris 的元資訊,包括庫、表、表欄位、錶行數等資訊,在使用者提交即席查詢請求時,首先會解析出使用者查詢的表,並按照如下順序判斷:

  查詢的表是否已在 Doris 同步

  Doris 表和 Hive 表結構是否相同

  Doris 表和 Hive 表表行數是否一致

  如果以上要求均被滿足,則會將該查詢路由到 Doris,否則會依次按照 Presto、Spark、Hive 的順序進行路由查詢,當查詢出現異常時,也會按照該順序依次進行故障轉移。

  慢查詢慢匯入分析

  對於慢查詢和慢匯入,Doris 提供了完善的 Profile 機制,在瞭解相關技術細節後,我們線上上叢集開啟了 Profile 收集,透過排程任務定時收集慢查詢、慢匯入的 Profile 資訊並落庫。  

  Doris 提供的 Profile 資訊非常詳細,例如 OLAP_SCAN_NODE 提供了原始的掃描行數,各個索引的過濾行數,每個 Instance 的 EXCHANGE_NODE 提供了接收的資料總行數和接收的資料量大小。這些資訊為查詢調優提供了詳細的依據,我們在使用過程中針對快速定位查詢效能的瓶頸進行了最佳化,取得了良好的效果。

  建表規範

  在我們的使用場景中,有下列型別的表:

  pda表:每日全量更新,即每日分割槽儲存全量快照資料

  pdi表:每日增量更新,即每日分割槽儲存增量資料

  a表:全量不分割槽表

  s表:靜態非每日更新資料

  由於當前 Doris 叢集中所有的表都是基於 Hive 數倉中各層級的表同步而來,因此目前僅使用了 Duplcate 模型和 Unique 模型,對於 pda、pdi 和 a 表,為了降低 Doris 表的分割槽數,減輕 FE 後設資料管理壓力,我們在建 Doris 表時均啟用了根據日期劃分的動態分割槽特性,較久遠的歷史資料我們按年、月的維度分割槽歸檔,近期的資料按日、小時分割槽,未來我們計劃透過程式自動識別完成歷史分割槽的歸檔合併。

  對於 pda 表使用場景,pda 表需要每日同步全量資料,我們採用了 Duplicate 模型,不考慮使用 Unique 模型資料去重的原因是 Doris 的匯入模型本身就提供了基於任務 Label 的資料一致性保證,同步時一次排程週期的 pda 表的一個分割槽的匯入任務能產生唯一且不變的 Label,因此我們可以保證即使錯誤執行了多次,該分割槽的資料仍然不會重複。另外,因為 Duplicate 模型相比於 Unique 模型,在匯入和查詢階段均不會做預聚合去重,所以可以一定程度上加速匯入和查詢的效能。

  對於 pdi 表使用場景,因在實際使用中 pdi 表存在少數對歷史資料的部分更新場景(絕大部分是資料更新場景,基本沒有資料刪除場景),考慮到 Doris 資料表的分割槽可用性,我們採用了 Unique 模型,這樣在更新歷史分割槽的資料時不必做重建分割槽操作。

  對於 a 表使用場景,因業務上可以接受短時間資料不可用情況,我們啟用了動態分割槽,在做資料匯入時,每次匯入都會先刪除歷史分割槽,然後將全量資料匯入今天的分割槽內,這樣做的考慮是杜絕重建表操作,且實施成本相對比較低,因此我們沒有采取動態更新檢視繫結當日分割槽的方案。

  在 Doris 之前的版本中,尚未實現 Hive 後設資料變更同步和管理功能,為了提高效率開發了 Doris 建表工具,我們透過選擇和配置數倉叢集、Hive 表名、資料模型、Bucket 數量等引數,自動關聯 Hive 表,解析表欄位並生成對應的建表語句。經過與社群溝通得知,最近即將釋出的 1.2 新版本中已經實現 Multi Catalog,支援 Hive 後設資料的對接和 Schema 的自動同步,可以極大程度上減少這一部分的工作。

  監控體系

  當前 Doris 叢集監控體系分為主機指標監控告警、日誌告警和叢集指標監控告警,總體監控體系如下。  

  主機指標監控是基於 Open-Falcon 開發的監控告警平臺,主要採集 Doris 叢集節點的 CPU、IO、記憶體、磁碟等相關指標並進行監控告警。  

  叢集指標監控參考了 Doris 官方文件提供的基於 Prometheus 和 Grafana 和叢集指標監控方案。  

  日誌告警仍然是基於我們的監控告警平臺,主要用於監控 Doris 服務日誌中容易識別但其他監控方式成本較高的監控、告警場景,是其他兩種監控的補充。透過日誌監控告警,我們能夠準確識別資料匯入任務的失敗原因並能進行及時的推送通知。

  問題排查和審計日誌

  為了及時排查一些極端的叢集問題,上述針對 Doris 的監控體系建設仍然是不夠的。為了在叢集 BE 出現異常當機時快速定位堆疊,需要在所有的 BE 節點開啟 Core Dump。除此之外,審計日誌在叢集的日常運維中也發揮了重要作用。

  對於 Doris 叢集的審計日誌收集一般可以透過 2 種方式:

  第一種方式是透過日誌收集元件、收集各個 FE 節點上的 fe.audit.log

  第二種方式是透過安裝 Doris 提供的 Auditloader 外掛(下載 Doris 原始碼,該外掛在doris/fe_plugins/auditloader,具體使用文件可參考官方文件)。

  考慮到第二種方式操作更簡單,因此採用此方式進行日誌採集。不過在使用 Auditloader 外掛的過程中,陸續發現和修復了一些外掛問題,並向社群提交了 PR,與此同時,我們定製開發了內部控制檯,便於檢視叢集的同步任務情況,資料分佈情況以及進行審計日誌的檢索。  

  審計日誌為叢集 BE 崩潰時具體 SQL 定位、客戶端訪問統計、查詢 SQL 耗時統計、訪問 SQL 特徵分析等提供了詳細的資訊。例如,資料開發曾經反饋查詢 Doris SQL 失敗,檢索日誌出現了大量連線數超限的異常,我們透過審計日誌,迅速定位到了問題原因是由於上游匯入工作流 Bug 在短時間內建立較多的資料庫連線。另外,對於曾經使用的低版本 Doris 出現數次 BE 異常當機問題,我們透過 gdb 除錯工具定位到崩潰時 SQL 的query_id後,配合審計日誌也能快速的定位到導致崩潰的具體 SQL。

   最佳化實踐

  資料匯入實踐和調優

  初期資料來源主要來自 Hive 數倉,因此大部分資料匯入以 Broker Load 方式為主。大資料平臺自助匯入任務工作流適配了 Doris Broker Load 匯入方式,資料開發零程式碼——透過簡單的勾選配置即可完成自助的 Doris 資料匯入工作流建立。

  而在 Broker Load 的使用過程中,我們也陸續遇到了一些問題,這裡拿出幾個典型的問題和一些調優經驗來分享。

  在 Broker Load 匯入時遇到的問題:

  1)因表分桶數設定過少造成 Broker Load 匯入失敗,具體表現為匯入任務失敗且異常資訊為:

  tablet writer write failed, tablet_id=xxx, txn_id=xxx, err=-238

  我們推測造成 -238 錯誤的原因可能是分桶設定太少,接著我們透過 BE 節點的掛載資料來檢視單個 Tablet 下的檔案大小,我們發現單個 Tablet 的檔案佔用空間遠大於官方推薦的10GB 上限範圍,這也證明了我們的推測正確,因此我們透過適當提高 Doris 表的分桶數,使得這個問題有了較大的緩解。

  順便說一下,如果出現 -235(舊版本是 -215)異常,一般是由於 Compaction 過慢導致 Tablet 版本堆積超過限制,這個時候透過 Grafana 看到 BE Compaction Score 在匯入前後有明顯的波動,而且絕對值很高。如果遇到此問題可以參閱 ApacheDoris 公眾號文章:Doris 優秀實踐-Compaction調優(3)

  2)因 Hive 表欄位變更導致 Broker Load 匯入失敗:

  Hive 表在使用過程中會有一些 DDL 的執行,從而導致表欄位新增,我們數倉的 Hive 表均使用 ORC 格式儲存,那麼就會導致 Hive 表中部分歷史分割槽的 ORC 檔案中欄位資訊缺失(缺失新增欄位),而新分割槽的 ORC 檔案中欄位是正常的,這個時候如果對歷史資料重新匯入,就會有下面的異常資訊:

  detailMessage: ParseError : Invalid column selected xxx

  在閱讀了 Broker Load 相關程式碼後確認了問題原因:在一次 Broker Load 匯入過程中,匯入任務的欄位解析器會讀取一個 ORC 檔案頭解析欄位資訊,但解析器只會解析一次,如果一次匯入過程中同時有新、歷史分割槽的 ORC 檔案,那麼就可能導致任務失敗。

  修復的方法也很簡單,只需針對每個 ORC 檔案重新解析一次檔案頭的欄位資訊即可。在瞭解問題原因及分析解決思路後,我們也和社群的同學一起修復了這個問題並提交了相關 PR。

  3)遇到空 ORC 檔案時 Broker Load 匯入失敗:

  這個問題的錯誤表現和問題 2 比較類似,具體原因是 Broker Load 匯入過程沒有對 ORC 檔案做判空,遇到空 ORC 檔案仍會嘗試解析 ORC 檔案欄位資訊導致報錯,我們把這個問題反饋給社群後,社群的同學很快修復了該問題。

  4)Broker Load 匯入任務出現 Broker list path exception. path=hdfs:xxx

  建立 Broker Load 任務,使用 Kerberos 認證訪問 HDFS 的 Hive 檔案匯入資料,Hive 檔案路徑中分割槽和下一級目錄使用萬用字元 *,訪問所有分割槽所有檔案,任務提交後隔 40 多秒出現如下的錯誤:

  type:ETL_RUN_FAIL; msg:errCode = 2, detailMessage = Broker list path exception. path=hdfs:xx

  在閱讀了 Broker Load 的訪問 HDFS 相關程式碼後確認了問題原因,Broker Load 呼叫 HDFS 的 LS、DU 方法時會獲取檔案目錄資訊,由於路徑下的檔案過多導致耗時會超過 45 秒,而 Thrift 設定的 Socket 請求超時預設小於 40 秒,所以出現了上述的 RPC 異常,問題反饋社群後,對 FE 增加了配置引數broker_timeout_ms,設定為 90 秒後解決問題。

  關於 Broker Load 的匯入效能調優策略

  我們針對 Broker Load 匯入調優的主要方向在確保 Doris 叢集不承壓的情況下儘可能提高匯入併發度,下面根據 2 個典型的案例來說明:

  1)部分 pdi/pda 表因為資料規模太大導致全量匯入耗時過長(匯入資料來源是 Hive 分割槽表)

  部分 pdi/pda 表資料規模在 T 級別,在進行全量匯入時,如果只提交一個 Broker Load Job ,將因為匯入任務的併發不夠,導致匯入耗時達到 5-6 小時。針對此問題,我們可以對匯入任務進行 Job 拆分,在大資料平臺也適配這種場景,支援任務的自動拆分和重試機制,具體的拆分方式如下圖:  

  不過要注意的是,拆分後可能會對叢集有較高的寫入壓力,要及時監控匯入任務和叢集的狀態,特別針對 -235 的情況可能需要進行 Compaction 調優。

  2)部分 ads 表因為資料規模太大導致全量匯入耗時過長(匯入資料來源是Hive非分割槽表)

  資料開發對部分報表的同步時效提出了很高的要求,我們在針對性的最佳化表同步時效時,發現一些表匯入耗時較長,但透過叢集監控體系發現相關表同步期間,BE、FE 節點的 CPU、記憶體、磁碟 IO 、網路卡 IO 並沒有達到瓶頸,叢集的 Compaction Score 在此期間也一直穩定在低位,且整個同步過程同步任務均未出現-235、-238等相關的錯誤,我們推測瓶頸可能還是在匯入任務的併發程度上。

  因為有些表在 Hive 數倉是非分割槽的表,所以第 1 種透過劃分分割槽範圍拆分多個匯入 Job 的方式就行不通了,理論上仍然可以透過劃分不同的 HDFS 檔案來拆分 Job,但是這種方式在毓數大資料平臺還需要進一步去適配,所以我們還是優先考慮透過調整叢集配置的方式徹底解決此問題:

  首先可以透過適當調高 FE 的max_broker_concurrency去提高 Scan HDFS 檔案階段的併發度(最高調高至 BE 節點數),而對於 Table Sink 階段,可透過調高 FE 的default_load_parallelism(設定fe.conf,可調整到 BE 節點數)和 send_batch_parallelism引數( SQL Session 執行set global send_batch_parallelism=5或在提交 Broker Load 中的 PROPERTIES 中指定,最高調整到 5,如果超過此值,需要同步調整be.conf的 max_send_batch_parallelism_per_job 引數),提高該階段併發度。透過提高 Broker Load Job 各階段匯入的併發度,相關報表的同步時效顯著提升,這裡我們選取 5 張典型表為例,最佳化前後的同步時效表現如下:  

  雙機容災建設

  為了保障 Doris 叢集的可用性,我們需要為 Doris 叢集提供雙機房容災能力。Doris 目前雖然可以透過不同的 Tag 將 BE 分組部署在多個機房,但是無法解決機房出現問題時的 FE 可用性問題。經過方案調研分析,我們決定透過自行開發 Replicator 主從同步外掛去實施雙機房容災建設,具體的架構如下:  

  透過在主叢集安裝 Replicator 外掛,Replicator 外掛會攔截並解析主叢集執行的全量 SQL,然後經過過濾操作,篩選涉及庫、表結構變更和資料增、刪、改相關的 SQL,並將相關 SQL(部分 SQL 需要改寫)傳送到備叢集進行重放。除此之外,我們在 Doris 控制檯開發了 Validator 資料校驗程式,定期校驗主備叢集間的資料結構差異和資料差異並上報,在主叢集因各種問題導致不可用時,直接透過切換 DNS 解析地址到備叢集 LVS 地址完成主備叢集的切換。

   總結規劃

  獲得收益

  從 2022 年3月份開始進行對實時數倉溝通進行調研,7月份正式上線生產,叢集資料規模快速增長。目前,生產環境共有 2 個叢集,數百張表,幾十 TB 資料,每日有數百個同步工作流在執行,幾十億規模的資料新增/更新。在此規模下,Doris 對業務支援良好,穩定執行。  

  Doris 叢集架構清晰簡單,不依賴其他元件,資料模型簡單,資料匯入方式多樣化且適配成本很低,使得我們可以快速完成前期的調研測試並在短時間內上線實施。

  Doris 叢集作為目前公司 BI 工具的重要資料來源,承載了相當一部分的報表分析業務,極大加速了報表分析的時效性。Doris 上線 3+月的時間,已經承載了小部分即席查詢場景,大大縮短了相關查詢的耗時。

  Doris 具有完善的監控機制和審計機制,極大的降低了我們的運維工作

  Doris 社群十分活躍,在我們使用 Doris 過程中遇到的一些疑難問題,官方也可以及時進行響應、處理。

  未來規劃

  在近期的規劃中,我們希望 Doris 能支撐更多的業務場景、發揮更大價值。例如基於 Doris 建立實時數倉、基於 Doris 重構使用者行為畫像、Doris HIVE 外表特性等。同時我們計劃透過分析使用者的查詢 SQL 特徵,結合 Doris 的查詢快取和物化檢視特性,進一步提升查詢效率。透過開發叢集探查工具,實時探測叢集資料表的資料分佈情況,比如 Tablet 有沒有過大,Tablet 資料分佈是否均勻等,綜合探查叢集的執行情況並自動給出最佳化建議。

  目前我們使用了 Doris 有大半年時間,在這半年期間一直保持和社群同學進行交流(提交 Issues 和 PRs)。非常感謝 SelectDB 團隊一直以來對我們的技術支援,祝 Apache Doris 未來越來越好,為基礎軟體建設添磚加瓦。

來自 “ SelectDB ”, 原文作者:360數科中介軟體團隊;原文連結:http://server.it168.com/a2022/1201/6778/000006778319.shtml,如有侵權,請聯絡管理員刪除。

相關文章