每日最新頭條.有趣資訊

快手兆級實時OLAP平台的建設與實踐

作者 | 李遠策

編輯 | 薛梁

12 月 7-8 日在北京舉辦的 ArchSummit 全球架構師峰會上,快手科技大數據平台架構師李遠策分享了快手在 OLAP 平台的建設與實踐。以下為演講的主要內容,有刪節。

快手 App 目前日活 1.5 億,每天會產生數兆規模的用戶行為數據,對這些數據的高效探索是一件很有挑戰同時也很有價值的工作。今天重點分享快手建設兆級數據規模 OLAP 平台的設計方案以及主要改進過程。

1

快手 OLAP 平台概覽

快手的 OLAP 平台誕生的時間不長,在 2018 年 4 月份之前,一些多維分析的需求還是採用預定義指標加上離線計算的方案,其缺點很明顯,首先指標預定義是非常固定的,另外因為採用離線計算,實用性也很差。

在今年 4 月份上線 Druid OLAP 分析引擎,加上 Superset 數據可視化平台,解決了不少業務的痛點。5 月,Druid 平台更新到了當時社區最新的 0.12 的版本,在更新過程中解決了時區、檔案加載性能等問題。7 月,Druid 平台每天的錄入消息數已經突破 1000 億,用戶配置的可視化圖表也超過 1000 個。7 月份之後平台進入了一個快速發展的階段,Druid 在查詢性能和穩定性方面都出現了很多的問題,我們做了非常多的改進。9 月,上線了 Druid 探針系統、時序和維度物化視圖功能、Indexing Service 細顆粒資源分配等,另外在資源調度層面也做了大量優化工作。截至今年 11 月,OLAP 平台每天攝入消息的數據量峰值已經超過 5000 億,用戶配置的可視化圖表數已經突破 1 萬。

半年來 OLAP 平台發展速度非常快,得益於基於 Druid 的高可用架構設計,以及團隊夥伴的努力,整個 OLAP 平台上線至今未出現中型或大型的故障,服務很穩定。

快手 OLAP 平台共有 150 台物理伺服器,接入的數據源超過 2000 個,每天錄入的消息數量在 5000 億左右,索引的數據存量約 400TB。每天查詢次數峰值 1000 萬,這個量是非常大的,但是有很多在程式裡觸發 API 的調用,人為觸發的比例較小。整體上平均查詢時延為 50 毫秒,P90 為 100 毫秒左右,P99 為 500 毫秒到 1 秒。可視化方面,積累的用戶看板數有八百多個,圖表數超過 1 萬。

2

快手使用 OLAP 的業務場景

首先是多媒體品質分析業務。快手使用了全國多家 CDN 廠商服務,涉及的域名有幾百個,每天上報的 CDN 品質監控數據上百億。CDN 服務品質會直接關係到主站 APP 用戶使用體驗,公司 CDN 品質團隊需要實時對 CDN 監控數據做分析和智能調度,以及對調度效果進行實時的監測。另外,對於 CDN 品質問題需要做出快速分析和定位,這本身也是一個多維分析的過程,OLAP 技術能夠很好地滿足這個需求。

另外一個業務場景是 A/B Test,快手已經上線了約 1000 個 A/B 的實驗,需要對比的 A/B 指標多達數千個,每天有數百億的數據要流入 A/B Test 平台。對 A/B Test 指標的分析,也是一個很典型的多維分析的過程,OLAP 平台要滿足每天幾十萬次的查詢調用需求,查詢的時延要保證在百毫秒級。

OLAP 平台選型時對公司多個業務團隊的需求做了調研,總結來講,大家對以下幾個點關注度會比較高。比如超大數據規模的支持,單個數據源可能每天有上百億的數據量需要錄入;查詢時延,要保證在毫秒到秒級;數據實時性,很多業務線明確提出實時數據分析的需求;另外還有高並發查詢、平台穩定性等,除此之外還有一些相對權重比較低的需求:如數據 Schema 的靈活變更、精確去重的功能,以及 SQU 接口的支持等。

根據對用戶調研的總結,我們對比了現在比較常用的 OLAP 技術。

首先,Hive/SparkSQL 在數據倉庫的領域應用是比較廣泛的,但是因為查詢時延很難能夠滿足毫秒到秒級的要求,同時因為是離線計算,數據時效性也比較差。

其次,ES 是一個功能很強大的系統,在中等數據規模場景下能較好地滿足需求,但是在兆和更大的數據規模場景下,數據的寫入性能和查詢性能都遇到了很大的瓶頸。

Kylin 和 Druid 功能比較類似,考慮到 Druid 採用 OLAP 架構,數據時效性相對於 Kylin 來講會更好,數據的變更也相對更加靈活,所以最終選用 Druid 作為 OLAP 平台的查詢引擎。

3

Druid 系統概述

上圖是 Druid 系統架構圖,其中 Coordinator 和 Overlord 是 Druid 的主節點;Middle Manager 主要是負責數據索引,生成索引檔案,Historical 節點主要負責加載索引檔案,同時提供歷史數據的查詢服務;Broker 是查詢的接入節點;除此,Druid 還需要對元數據進行存儲,比如選用 MySQL;Middle Manager 在產生索引檔案的時候,需要把索引檔案先發布到一個共享的存儲系統裡,我們選擇了大家普遍採用的 HDFS 系統。

上面提到 Druid 的查詢性能非常好,總結來說主要是因為採用了如下五個技術點:數據的預聚合、列式存儲、Bitmap 索引、mmap、以及查詢結果的中間緩存。下面針對兩個點具體展開講一下。

首先講下數據預聚合。Druid 會把一行數據消息分成三個部分,包括時間戳列、維度列以及指標列。所謂預聚合,就是當數據錄入到 Druid 系統時,會按照一定的時間周期把原始數據做一次預先聚合,會根據一個全維度聚合出要計算的指標,也就是要索引的內容。後續所有的查詢都是通過這些預聚合的中間結果做二次查詢。

接下來講下 Bitmap 索引。Bitmap 索引主要為了加速查詢時有條件過濾的場景。Druid 在生成索引檔案的時候,對每個列的每個取值生成對應的 Bitmap 集合。如圖上所示,Gender 為 Male 對應的 Bitmap 為“1001”,代表第 1 行和第 4 行的 Gender 為“Male”。舉一個查詢的例子,假設要篩選 Gender =‘Female’and City =‘Taiyuan’的數據,那麽只需要把 Gender =‘Female’對應的 Bitmap “0110”和 Taiyuan 對應的 Bitmap “0101”進行與操作,得到結果為“0100”,代表第二行滿足篩選條件。通過 Bitmap 可以快速定位要讀取的數據,加速查詢速度。

關於 Druid 模塊,Druid 支持從 kafka 實時導入數據,同時也支持批量從 HDFS 或者 HIVE 系統進行離線導入;Druid 提供了豐富的查詢 API 接口。除了默認提供的 Restful 接口之外,Python 、Java、Go 等編程語言都有第三方的實現 API 接口。此外,Druid 也提供了 SQL 接口的支持。值得一提的是,Hive 在 2.2 版本之後通過 StorageHandler 實現了對 Druid 的支持,這樣可以通過 Hive SQL 查詢 Druid 裡的數據,快手內部也在用,但是需要做一些修改工作,比如解決時區問題、Druid 數據源維度和指標的大小寫敏感問題,以及實現默認的 limit、默認時間範圍選擇等功能。

4

Druid 在快手使用的經驗以及一些主要改進點

這是快手 OLAP 的平台架構圖,中間部分是 Druid 自有的組件,數據通過 kafka 實時攝入和離線從 Hive 數倉中批量導入。除此之外,我們還配套了完善的 Metric 系統,探針系統、Druid 數據源管理系統等。

在兆甚至幾十兆數據規模場景下,OLAP 平台使用過程中也面臨了很多挑戰。比如如何讓查詢變得更快,資源的利用率如何更高效,在數據的管理到數據的接入如何更方便,集群平台如何更穩定,針對這些問題我們都針對性的做了改進和優化。

首先,穩定性方面我們做了多種的資源隔離部署的方案,在接入層通過代理實現 Broker 的高可用和負載均衡。

在 Historical 數據存儲層,做了兩個層面的數據劃分。一是數據的冷熱分離,熱數據存儲在 SSD 的機器上,當熱數據變成冷數據之後會自動地遷移到 HDD 機器上。因為大部分查詢都是查詢最近的數據,所以才用 SSD 的加速效果是非常明顯的。考慮到 SSD 的成本比較高,可以在設定熱數據的副本的時候,把其中一個副本放在 SSD 上,另外一個副本放到 HDD 的機器上,然後設定 SSD 副本的權重,大部分的請求還是能夠落在 SSD 機器上。當 SSD 機器出現故障之後,請求才會發送 HDD 上,這樣能節約不少成本。

除了冷熱數據分離的考慮外,因為有些對查詢穩定性要求更高,快手通過 Tier 配置也對特殊業務也做了隔離,特殊的業務數據源索引數據存儲在專用的 Historical 機器上。這樣在一些大查詢可能會導致 historical 記憶體 GC 或者是系統 IO 支持 Load 較高的場景下,其查詢性能仍然不受影響。

在大規模數據場景下查詢性能的加速,我們也做了很多優化。首先是物化視圖,會做兩個層面的物化視圖,一個是維度層面的物化,一個是時序層面的物化。

什麽是物化視圖,假設一個數據源的原始維度有十個列,通過分析查詢請求發現,group1 中的三個維度和 group2 中的三個維度分別經常同時出現,剩餘的四個維度可能查詢頻率很低。更加嚴重的是,沒有被查詢的維度列裡面有一個是高基維,就是 count district 值很大的維度,比如說像 User id 這種。這種情況下會存在很大的查詢性能問題,因為高基維度會影響 Druid 的數據預聚合效果,聚合效果差就會導致索引檔案 Size 變大,進而導致查詢時的讀 IO 變大,整體查詢性能變差。針對這種 case 的優化,我們會將 group1 和 group2 這種維度分別建一個預聚合索引,然後當收到新的查詢請求,系統會先分析請求裡要查詢維度集合,如果要查詢的維度集合是剛才新建的專用的索引維度集合的一個子集,則直接訪問剛才新建的索引就可以,不需要去訪問原始的聚合索引,查詢的性能會有一個比較明顯的改善,這就是物化視圖的一個設計思路,也是一個典型的用空間換時間的方案。

時序物化視圖:除了剛才提到的查詢場景外,還有一種查詢 Case,Druid 也不能很好滿足。比如大跨度時間範圍的查詢,假設一個數據源的聚合力度是分鐘級別,但需要查詢最近三個月的數據就比較麻煩,因為需要把過去三個月的所有分鐘級別的索引檔案全部掃描一遍,然後再做一次聚合的計算。

為了解決這個問題,我們在數據源分鐘級別的索引上再新建一個小時級別甚至級別的物化索引,這種情況下聚合效果就會更好,索引整體的 size 也會比較小。當收到一個新的查詢請求時,如果查詢要統計的粒度是天級別或者是更高級別的查詢粒度,會把查詢請求自動路由到天級別物化索引上,這樣查詢性能也會有一個比較明顯的改善。

下面討論下 Druid 元數據存儲系統的性能優化,平台上線以來我們積累了大約幾百萬的 Segment 檔案,對這些數百萬 Segment 元資訊的查詢,或者說 MySQL Segments 表的查詢也遇到的性能瓶頸。

首先是 Overlord 與 MySQL 之間的互動優化。Overlord 在發布新的 Segment 檔案的時候會多次查詢 Segments 表,監控發現會有大量的慢查詢。解決方案很簡單,針對性地對 Segments 表增加索引即可。對比優化後的 MySQL 查詢性能,可以從 10 秒多降到 1 秒,有 10 倍以上的提升。

另外是 Coordinator 與 MySQL 之間的互動性能優化。Coordinator 會周期性的去全量掃描 Segments 表,每次掃描都會花費較長的時間。首先全量掃描完全是沒必要的,我們改造成增量掃描的方案,整個掃描的耗時從原來的 1.7 分鐘降到 40 秒左右。然後更進一步對增量掃描的 SQL 專門創建了 MySQL 索引,掃描耗時可以降到 30 毫秒,整體算下來有上千的性能提升。

接下來是 Segment 檔案加載過程的優化,Coordinator 掃描 segment 匹配 Rule 過程默認是串行實現的,我們對此做了並行化的加速,再加上一些細節點的改進。集群幾百萬量級的 Segment 檔案協調一遍的耗時從原來的 3 分鐘降低到現在的 30 秒。Druid 元數據系統通過如上幾個點的優化後,目前基本上不再有性能瓶頸。

5

快手對 Druid 集群資源利用率的改進

首先,每個 Kafka indexing task 會對應一個 Supervisor 的服務,Supervisor 的 task count 是一個固定的值,當用戶設定 task count 比較小時,可能會因為讀取 Kafka 的 lag 過大而出現數據延遲,而如果設定的過大會造成資源的浪費。另外,用戶在創建一個 indexing task 的時候,也很難估算 task count 應該是多少合適。我們的優化方案是讓 Supervisor 根據當前消費 Kafka 時延的情況,自動調節 task count,這樣業務高峰期不至於出現數據延時,數據低峰期時也能把資源還給集群,整個集群的利用率有明顯提升。

另外是 Middle Manager 的 indexing task 資源分配問題。Druid 為每個 Middler Manager 分配一個固定的 Slot 數,但是因為相對 Kafka indexing task 來講 Hadoop indexing task 其實只是一個 Hadoop 客戶端僅負責提交一個任務,本身並不怎麽佔資源,這樣的話會有一些資源的浪費的問題。針對這個問題的優化思路是,把 Middler Manager 的 task 調度配置從按照 Slot 數改成按照記憶體大小分配,我們會區別對待不同類型的 task,對於 Kafka 的 task 和 Hadoop 的 task 會默認不同的記憶體大小,當然用戶在提交 task 的時候,可以指定自己的 task 記憶體大小,我們會做一些最大值的限制,防止惡意的提交。

此外,對 Segment 檔案及時的做 Compaction 會有益於查詢性能加速,也能節省存儲空間。目前 Druid 在做 Compaction 的時候,會提交一個特殊的 Compaction task,串行掃描 Segment 檔案進行合並,性能較差。我們對此做了一個並行化的方案,思路是提交一個 Hadoop 的任務,在 Hadoop 集群上去並行掃描 Segment 的資訊,然後去做 Compaction,性能的提升還是非常明顯的。

在平台易用性方面我們也做了很多的工作。在平台運營的時候會面臨一個問題,每天都有很多數據源要接入,在平台上線初期,管理員是可以參與完成,但是當業務快速增長的時候,這個工作量非常大。數據源接入後,還會面臨很多需要修改數據源的維度和指標定義的需求,這些都需要系統化的去解決。

除此之外,很多時候用戶對 Druid 平台或者對自己的數據理解不夠深入,也可能對業務的分析需求場景不夠明確,在接入數據源時往往會導入大量的維度和指標資訊,這就帶來一個隱患:維度越多聚合效果就會變差,更甚至會有一些高基維嚴重影響數據聚合的效果和查詢性能。

針對這些問題,我們設計了兩套工具,分別是 Druid 數據源管理系統和 Druid 探針系統。

數據源的管理系統是一個 Web 管理系統,用戶可以在這個系統上完成數據源接入、查看和管理,可以查看的資訊包括維度和指標資訊、Kafka 消費的速率、kafka 消費的 lag 等。上圖展示的是數據源管理系統的 indexing task 列表資訊,系統配有權限管理功能,只有數據源的負責人可以修改數據源的維度和指標等配置資訊。

上圖是 indexing task 詳情頁面,除了一些基礎的資訊之外,還可以看到像 Kafka 消費的速率情況,用戶可以自主地去排查自己負責的數據源的線上問題。

這張是數據源的新建和編輯頁面。用戶新建 Kafka 數據源的過程非常方便, 其中 Kafka 的資訊是從 Kafka 的管理系統裡面直接抽取出來的,用戶不需要手動填寫,直接點選即可。對於時間戳列和時間戳列的格式,系統會自動抽取用戶 Kafka 的數據做填充,如果是用戶寫錯了時間戳列的格式,也能夠自動糾正過來。對於維度和指標系統也預先做了數據的解析提供 Suggestion,用戶只要用滑鼠點選即可。

這張圖展示的數據源的列表資訊,可以在列表上清楚地看到這個數據源的數據量、Segment 檔案的平均大小、維度和指標資訊。此外,如果這個數據源是通過離線任務導入的話,能夠會自動關聯離線任務的名字,方便快速定位到自己的定時導入任務。

Druid 探針系統主要解決如下幾個問題:

第一,數據源查詢熱度的分析。探針系統會對 Druid 所有的數據源做總體的查詢熱度排名,這樣管理員可以知道哪些數據源是查詢的大客戶,會做針對性的“關照”。此外,還可以發現一些沒有查詢請求的冷數據源或者僵屍數據源,並通知用戶去做下線處理,避免佔用集群的資源。

對於單個數據源,探針系統還可以對這個數據源內部的維度和指標做查詢熱度的分析,了解哪些維度是經常被查詢的,哪些維度和指標是不常查詢的冷維度或指標,特別是還能發現一些既是冷維度又是高基維的維度,這種 Case 會嚴重影響查詢性能,要及時通知用戶進行優化。

下面講一下 OLAP 平台數據可視化方面的工作。一個強大的可視化工具,是 OLAP 平台必備的組件,我們採用了開源的 Superset 方案。Superset 是 Airbnb 開源的、能與 Druid 深度集成的、互動式的、高效的、數據分析和可視化平台,它的功能非常強大,支持種類豐富的數據可視化的圖表。

截至目前,我們的 Superset 已經積累了上萬個圖表,用戶在使用 Superset 過程中也遇到很多問題,針對這些問題我們對 Superset 同樣做了大量的改造。包括數據的同步、權限管理、報警功能、產品設計的一些互動改進等。

針對幾個重點的改進點做下介紹,比如對多 time shift 的支持,所謂 time shift 就是可以在一張圖裡面同時繪製出來當前值與前一天同比和環比的指標對比。這裡展示的是當前這一天與前一天,以及上周同天指標對比情況,用戶可以加任意多的其他日期的指標對比到同一張圖裡面。除了這種時序線圖之外,我們對其他圖表也做了大量的 time shift 支持。

這裡展示的是 Superset 同一個看板裡面多個圖表,在滑鼠滑動視窗進行滑行的時候能夠聯動刷新的功能,對其中一個圖表進行時間範圍選擇,其他圖表能夠關聯進行刷新,這在進行多表關聯分析的時候還是比較實用的。

這裡展示的是 Superset 報警功能的設計。公司很多監控數據都是依賴 Druid 和 Superset 做數據分析,對報警需求也是非常強烈。我們參考了 Grafana 的報警功能的設計,在 Superset 上也實現了類似的功能,用戶可以在平台上自定義一些報警維度、指標、檢查周期、報警級別等。

6

總結:快手對 Druid 的改進

在性能提升方面,我們做了時序和維度兩個層面的物化視圖以及元數據方面的互動優化。在資源管理層面,實現了 Supervisor indexing task 的自動伸縮、Middler Manager 細粒度資源分配以及並行 Compaction。在穩定性層面,設計了 Broker 和 Historical 的隔離部署。在平台易用性層面,自研了數據源的管理系統、數據探針系統,以及引入 Superset 數據可視化平台。

最後分享未來快手 OLAP 平台的一些工作計劃。首先,我們會引入一些新型的 OLAP 的技術,比如 Clickhouse。第二,我們在考慮 OLAP 與 Adhoc,以及例行報表的整合,希望 OLAP 技術能夠在離線數據分析方面也有更大的發揮空間。第三,從數據的流入到數據的可視化提供一站式的服務,降低技術人員和非技術人員的使用門檻。第四,希望平台能夠從技術輸出向產品化、服務化的方向去演進。

作者介紹

李遠策,快手科技大數據平台架構師,數據查詢引擎團隊負責人。負責公司 SQL 引擎、OLAP 引擎、多維可視化平台的研發以及在公司的應用。曾供職於奇虎 360,是開源項目 XLearning 的作者。主要研究領域包括分布式計算、OLAP 引擎、SQL on Hadoop、AI on Hadoop 等。

獲得更多的PTT最新消息
按讚加入粉絲團