您好,登錄后才能下訂單哦!
這篇文章主要講解了“從Druid遷移到ClickHouse的原因有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“從Druid遷移到ClickHouse的原因有哪些”吧!
eBay 廣告數據平臺為 eBay 第一方廣告主(使用 Promoted Listing 服務的賣家)提供了廣告流量、用戶行為和效果數據分析功能。
廣告賣家通過賣家中心(Seller Hub)的營銷標簽頁、效果標簽頁和公開API,有效掌控和對比店鋪的營銷活動和推廣商品的流量、銷量的實時和歷史數據,并通過網頁或者 API 下載數據分析報告。
這一系統上線之初使用了自研的分布式 SQL 引擎,構建在對象存儲系統之上。3 年前隨著廣告流量增加,我們把數據引擎切換到 Druid 上。
這一平臺的主要挑戰如下:
數據量大:每日的插入數據記錄有數百億條,每秒的插入峰值接近一百萬條。
離線數據攝入:在不影響實時數據攝入的情況下,每天需要對前 1-2 天的數據進行在線替換。
根據上游數據團隊發布清洗過的每日數據,廣告數據平臺需要在不影響查詢的情況下每日替換實時數據,數據切換要求實現跨節點的全局原子操作。
完整性和一致性:面向賣家的財務數據,離線更新后的數據要求不能有遺漏和重復;實時數據要求端對端的延遲在十秒內。
Druid vs ClickHouse
Druid 于 2011 年由 Metamarkets 開發,是一款高性能列式在線分析和存儲引擎。它于 2012 年開源,2015 年成為 Apache 基金會旗下項目。
Druid 在業界使用廣泛,為千億級數據提供亞秒級的查詢延遲,擅長高可用、水平擴展。
另外為數據攝入提供了很多非常方便的聚合、轉換模版,內建支持多種數據源,最快可以在幾十分鐘內配置好新的數據表,包括數據定義和數據攝入鏈路(Lambda 架構),大大提高了開發效率。
ClickHouse 由俄羅斯最大的搜索引擎公司 Yandex 研發,設計目標是支持 Yandex.Metrica(世界第二大 Web 分析平臺)生成用戶分析報表等核心功能。
ClickHouse 是一個數據庫管理系統(DBMS),有數據庫、表、視圖、DDL、DML 等概念,并提供了較為完整的 SQL 支持。
其核心特性有如下幾點:
高效的數據存儲:通過數據壓縮和列式存儲,可以達到最高 10 倍的數據壓縮率。
高效的數據查詢:通過主鍵索引、向量化引擎處理、多處理器并發和分布式查詢,最大壓榨 CPU 的所有能力,在中小規模的數據量上尤為突出。
靈活的數據定義和接入:通過支持 SQL 語言、JDBC 和關系模型,降低學習和遷移成本,可以和其他現有數據的產品無縫集成。
為什么遷移?
運維
Druid 雖然提供了很多非常方便的數據攝入功能,但它的組件構成也較為復雜,節點類型有 6 種(Overload,Coordinator,Middle Manager,Indexer,Broker 和 Historical)。
除了自身的節點,Druid 還依賴于 MySQL 存儲元數據信息、Zookeeper 選舉 Coordinator 和 Overlord、HDFS 備份歷史數據。
ClickHouse 的架構采用了對等節點的設計,節點只有一種類型,沒有主從節點。如果使用了副本功能,則依賴于 Zookeeper 保存數據段的同步進度。
與此同時,eBay 的基礎架構團隊提出在定制 ClickHouse 的基礎上,向產品團隊提供列式數據庫存儲的服務。
除了運維和生命周期管理,基礎架構團隊對 ClickHouse 進行改造和二次開發,進一步提高了數據攝入和存儲的效率,并在離線攝入方面彌補了和 Druid 的功能差距。
延時數據插入
Druid 通過引入實時數據的索引任務,把實時數據處理成一個個分段數據(segment),并歸檔成歷史數據。成為分段數據之后,該時段數據即不可寫入。
由于并發實時索引任務數的限制,我們設置了 3 個小時的窗口長度(每個小時一個任務),因此超過 3 個小時的數據就無法寫入。
在某些極端情況下,例如上游數據延遲或者實時數據消費過于滯后,就會導致離線數據替換前這部分數據的缺失。ClickHouse 則沒有這個限制,任意分區都可以隨時寫入。
主鍵優化
ClickHouse 支持的主鍵并不是傳統意義下關系型數據庫的主鍵。傳統的主鍵要求每條表記錄都有唯一的鍵值,通過查詢主鍵可以唯一地查詢到一條表記錄。
而在 ClickHouse 中,主鍵定義了記錄在存儲中排序的順序,允許重復,所以稱之為排序鍵似乎更加合理。
事實上在 ClickHouse 里的主鍵定義通過 ORDER BY 聲明,僅在個別場景中允許和排序鍵不一致(但必須是排序鍵的前綴)。
由于我們的產品是給賣家提供分析功能,幾乎所有的查詢限定在了單一賣家維度,因此通過主鍵按照賣家排序,可以極大地提高查詢效率以及數據壓縮率。
系統架構
圖 1
如圖 1 所示,系統由 4 個部分組成:
實時數據獲取模塊,接入 eBay 的行為和交易實時消息平臺。
離線數據替換模塊,接入 eBay 內部的數據倉庫平臺。
ClickHouse 部署和外圍數據服務。
報表服務,支撐廣告主、商家后臺和 eBay 公開 API。
實戰經歷
Schema 設計
ClickHouse 提供了豐富的 Schema 配置。這方面需要根據業務場景和數據模式反復斟酌和多次試驗,因為不同的選擇會對存儲和性能有數量級的影響,一個錯誤的選擇會導致后期巨大的調優和變更成本。
①表引擎
ClickHouse 的存儲引擎的核心是合并樹(MergeTree),以此為基礎衍生出:
匯總合并樹(SummingMergeTree)
聚合合并樹(AggregationMergeTree)
版本折疊樹(VersionCollapsingTree)等常用的表引擎
另外上述所有的合并樹引擎都有復制功能(ReplicatedXXXMergeTree)的對應版本。
我們的廣告數據平臺的展示和點擊數據選擇了復制匯總合并樹。這兩類用戶行為數據量極大,減小數據量節省存儲開銷并提升查詢效率是模式設計的主要目標。
ClickHouse 在后臺按照給定的維度匯總數據,降低了 60% 的數據量。
銷售數據選擇了普通的復制合并樹,一方面由于銷售數據對某些指標有除匯總以外的聚合需求,另一方面由于本身數據量不大,合并數據的需求并不迫切。
②主鍵
一般情況下,ClickHouse 表的主鍵(Primary Key)和排序鍵(Order By Key)相同,但是采用了匯總合并樹引擎(SummingMergeTree)的表可以單獨指定主鍵。
把一些不需要排序或者索引功能的維度字段從主鍵里排除出去,可以減小主鍵的大小(主鍵運行時需要全部加載到內存中),提高查詢效率。
③壓縮
ClickHouse支持列級別的數據壓縮,顯著地減少原始數據的存儲量,這也是列存儲引擎的巨大優勢。查詢階段,較小的存儲占用也可以減少 IO 量。
對不同列選擇一種合適的壓縮算法和等級,能把壓縮和查詢的平衡做到性價比最優。
ClickHouse 的所有列默認使用 LZ4 壓縮。除此以外,一般的數據列可以選擇更高壓縮率的算法如 LZ4HC,ZSTD。
而對于類似時間序列的單調增長數據可以選擇 DoubleDelta,Gorilla 等特殊壓縮算法。
LZ4HC 和 ZSTD 等高壓縮率的算法還可以自己選擇壓縮級別。在我們的生產數據集上,ZSTD 算法對 String 類型字段壓縮效果較為顯著。LZ4HC 是 LZ4 的高壓縮比改進版,更適用于非字符串類型。
更高的壓縮率意味著更少的存儲空間,同時由于降低了查詢的 IO 量,可以間接提升查詢性能。
不過 CPU 也不是大風刮來的,數據的插入性能就成了犧牲品。根據我們內部測試的數據,在我們的生產數據集上使用 LZ4HC(6) 相比 LZ4 可以節省 30% 的數據,但實時數據攝取性能下降了 60%。
④低基
值得一提的是,對于基數較低的列(即列值多樣性低),可以使用 LowCardinality 來降低原始存儲空間(從而降低最終存儲空間)。
如果在使用壓縮算法的情況下對一字符串類型的列使用 LowCardinality,還能再縮小 25% 的空間量。
在我們的測試數據集上,如果整表組合使用 LowCardinality、LZ4HC(6) 和 ZSTD(15),整體壓縮比大約在原來的 13% 左右。
離線數據替換
①挑戰
針對廣告主的數據報表要求數據準確、一致。實時的行為數據存在少量的 bot 數據(需要離線清除),另外廣告的歸因也需要在離線階段重新調整。
因此我們引入了離線數據鏈路,在實時數據寫入 24-72 小時之后,用離線數據替換實時數據。
其中的挑戰如下:
廣告系統每天需要處理的用戶離線數據量近 1TB,在此之前,需要耗費大量時間將數據從 Hadoop 導入 Druid。
另外,導入期間的 I/O、CPU 和內存的開銷對查詢的壓力不小。如何在保證數據一致性的同時,亦確保數據遷移的效率,是問題的關鍵。
如何在數據替換期間,確保用戶可見的數據波動最小。這就要求數據替換操作是原子性的,或者至少對每個廣告主都是原子的。
除了日常的離線數據更新,在數據倉庫數據出現偏差遺漏時,需要支持大范圍的數據修正和補償。
作業調度要求保證日常工作及時完成,并盡快完成數據修正工作。此外還需要監控數據更新中的各種指標,以應對各種突發狀況。
Druid 原生支持數據離線更新服務,我們與基礎架構團隊合作,在 ClickHouse 平臺實現了這一功能。
②數據架構
對于整合在線數據和離線數據的大數據架構,業界通常的做法是 Lambda 架構。即離線層和在線層分別導入數據,在展示層進行數據的合并。
我們也大致上采用了這一架構。但具體的做法和經典有所不同。
ClickHouse 里數據分區(partition)是一個獨立的數據存儲單元,每一個分區都可以單獨從現有表里脫離(detach)、引入(attach)和替換(replace)。
分區的條件可以自定義,一般按照時間劃分。通過對數據表內數據分區的單個替換,我們可以做到查詢層對底層數據更新的透明,也不需要額外的邏輯進行數據合并。
③Spark 聚合與分片
為了降低 ClickHouse 導入離線數據性能壓力,我們引入了 Spark 任務對原始離線數據進行聚合和分片。每個分片可以分別拉取并導入數據文件,節省了數據路由、聚合的開銷。
④數據更新任務管理
鎖定分區拓撲結構:在處理數據前,離線數據更新系統向基礎架構團隊提供的服務請求鎖定 ClickHouse 的分區拓撲結構,在此期間該分區的拓撲結構不會改變。
服務端根據預先定義好的數據表結構與分區信息返回數據的分片邏輯與分片 ID。
離線數據更新系統根據拓撲信息提交 Spark 任務。多張表的數據處理通過 Spark 并行完成,顯著提升了數據更新的速度。
數據聚合與分片:對于每一張需要更新的表,啟動一個 Spark 任務對數據進行聚合與分片。
根據 ClickHouse 服務端返回的表結構與分片拓撲將數據寫入 Hadoop,同時輸出數據替換階段用于校驗一致性的 checksum 與分片行數。
系統通過 Livy Server API 提交并輪詢任務狀態,在有任務失敗的情況下進行重試,以排除 Spark 集群資源不足導致的任務失敗。
離線數據更新不但要滿足每天的批量數據更新需求,還需要支持過往數據的再次更新,以便同步上游數據在日常定時任務更新之外的數據變動。
我們利用平臺團隊封裝的 Spring Batch 管理更新任務,按照日期將每天的數據劃分為一個子任務。
通過 Spring Batch 實現的 Continuously Job 保證在同一時刻子任務在運行的唯一性,避免產生任務競爭問題。
對于過往數據的更新,我們將 Batch 任務分類,除了日常任務之外,還可以手動觸發給定時間范圍內的數據修正任務(如圖 2)。
圖 2
數據替換:在子任務中的所有 Spark Job 完成后,離線數據更新系統會調用基礎架構團隊提供的數據替換接口,發起數據替換請求。
服務端按照定義好的分區,將數據從 Hadoop 直接寫入 ClickHouse,如圖 3 所示。
圖 3
離線數據更新系統的架構如圖 4 所示:
圖 4
MySQL 數據庫用于記錄數據替換過程中任務的狀態與優先級,當 Spark Job 失敗或者由于其他原因導致替換任務失敗重啟后,恢復任務的進度。
⑤原子性與一致性
為了保證數據替換的原子性,基礎架構團隊提供了分區替換的方式。在離線數據導入的過程中,首先創建目標分區的臨時分區。當數據替換完畢并且校驗完成之后,目標分區會被臨時分區替換。
針對不同機器上不同分片的原子性替換問題,基礎架構團隊為每一條數據引入了數據版本。
對于每一個數據分區,都有對應的活躍版本號。直到待替換數據分區的所有分片都成功導入之后,分區的版本號進行更新。
上游應用的同一條 SQL 只能讀取同一分區一個版本的數據,每個分區的數據替換只感覺到一次切換,并不會出現同時讀取新舊數據的問題。
廣告平臺報表生成應用因此在 SQL 層面引入了相應的修改,通過引入固定的 WITH 和 PREWHERE 語句,在字典中查詢出每個數據分區對應的版本號,并在查詢計劃中排除掉不需要的數據分區。
為了確保數據替換的一致性,在完成 Spark 數據處理之后,離線數據更新系統會計算各數據分片的校驗碼與數據總量。
當替換完畢之后,ClickHouse 服務端會對分片數據進行校驗,確保在數據搬遷過程中沒有數據丟失和重復。
數據查詢
ClickHouse 支持 SQL 查詢(不完全),有 HTTP 和 TCP 兩種連接方式,官方和第三方的查詢工具和庫豐富。
用戶可以使用命令行,JDBC 或者可視化工具快速進行數據查詢的開發和調試。
ClickHouse 通過 MPP(Massively Parallel Processing)+SMP(Symmetric Multiprocessing)充分地利用機器資源,單條查詢語句默認使用機器核數一半的 CPU。
因此 ClickHouse 不支持高并發的應用場景。在業務使用層面,最核心的問題是查詢校驗和并發控制,單條過大的查詢或者過高的并發都會導致集群資源使用率過高,影響集群穩定性。
應用架構
eBay Seller Hub 通過 Reports Service 接入 ClickHouse 查詢,Reports Service 提供了 Public 和 Internal 兩套 API。
Internal API 提供給 Seller Hub 以及其他內部的已知應用使用,Public API 在 eBay Developers Program 開放給第三方開發者,詳情見:
https://developer.ebay.com/
圖 5
Internal API 的查詢直接提交內部線程池執行,線程池的大小根據 ClickHouse 的集群機器數量設置。查詢請求執行前會進行校驗,過濾所有非法以及資源不可預估的請求。
Public API 通過任務提交的方式異步執行查詢,用戶提交的查詢任務存入 DB 中,Service 內部的 Schedule 定時掃表,根據任務的狀態串行執行查詢任務。
執行成功的任務上傳生成 Report 到文件服務器,用戶拿到 URL 后自行下載。執行失敗的任務,根據錯誤類型(非法的請求,資源不足等)來選擇是否在下一個周期再次執行。
測試發布
在生產環境部署完成后,我們開啟了數據雙寫,往 ClickHouse 里不斷地插入實時數據和離線數據,直到達到 Druid 的數據水平。
在數據一致性驗證過后,我們鏡像了一份生產服務的查詢,然后把這些查詢轉發給 ClickHouse。
通過收集和對比 Druid 和 ClickHouse 的響應,我們能夠驗證 ClickHouse 鏈路的數據質量和查詢性能。
之后的灰度階段,我們逐漸提升 ClickHouse 服務生產系統的比例,并保持 Druid 繼續運行,以保證出現問題可以及時回滾。
查詢 GUI
數據可視化方面,我們需要提供類似 Turnilo 的可視化工具給開發、測試和 BI 人員使用。
ClickHouse 支持多種商業和開源的產品接入,我們選用了 Cube.JS,并進行了簡單的二次開發。
圖 6
感謝各位的閱讀,以上就是“從Druid遷移到ClickHouse的原因有哪些”的內容了,經過本文的學習后,相信大家對從Druid遷移到ClickHouse的原因有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。