為什么PB級分析型數(shù)據(jù)庫ClickHouse這么快?
在百花齊放的交互式分析領(lǐng)域,ClickHouse 絕對是后起之秀,它雖然年輕,卻有非常大的發(fā)展空間。
圖片來自 Pexels
本文將分享 PB 級分析型數(shù)據(jù)庫 ClickHouse 的應(yīng)用場景、整體架構(gòu)、眾多核心特性等,幫助理解 ClickHouse 如何實現(xiàn)極致性能的存儲引擎,希望與大家一起交流。
交互式分析之 ClickHouse
交互式分析簡介
交互式分析,也稱 OLAP(Online Analytical Processing),它賦予用戶對海量數(shù)據(jù)進(jìn)行多維度、交互式的統(tǒng)計分析能力,以充分利用數(shù)據(jù)的價值進(jìn)行量化運營、輔助決策等,幫助用戶提高生產(chǎn)效率。
交互式分析主要應(yīng)用于統(tǒng)計報表、即席查詢(Ad Hoc)等領(lǐng)域,前者查詢模式較固定,后者即興進(jìn)行探索分析。
代表場景例如:移動互聯(lián)網(wǎng)中 PV、UV、活躍度等典型實時報表;互聯(lián)網(wǎng)內(nèi)容領(lǐng)域中人群洞察、關(guān)聯(lián)分析等即席查詢。
交互式分析是數(shù)據(jù)分析的一種重要方式,與離線分析、流式分析、檢索分析一起,共同組成完整的數(shù)據(jù)分析解決方案,在互聯(lián)網(wǎng)、物聯(lián)網(wǎng)快速發(fā)展的背景下,從不同維度滿足用戶對海量數(shù)據(jù)的全方位分析需求。
相比專注于事務(wù)處理的傳統(tǒng)關(guān)系型數(shù)據(jù)庫,交互式分析解決了 PB 級數(shù)據(jù)分析帶來的性能、擴(kuò)展性問題。
相比離線分析長達(dá) T+1 的時效性、流式分析較為固定的分析模式、檢索分析受限的分析性能,交互式分析的分鐘級時效性、靈活多維度的分析能力、超高性能的掃描分析性能,可以大幅度提高數(shù)據(jù)分析的效率,拓展數(shù)據(jù)分析的應(yīng)用范圍。
從數(shù)據(jù)訪問特性角度來看,交互式分析場景具有如下典型特點:
- 大多數(shù)訪問是讀請求。
- 寫入通常為追加寫,較少更新、刪除操作。
- 讀寫不關(guān)注事務(wù)、強(qiáng)一致等特性。
- 查詢通常會訪問大量的行,但僅部分列是必須的。
- 查詢結(jié)果通常明顯小于訪問的原始數(shù)據(jù),且具有可理解的統(tǒng)計意義。
百花齊放下的 ClickHouse
近十年,交互式分析領(lǐng)域經(jīng)歷了百花齊放式的發(fā)展,大量解決方案爆發(fā)式涌現(xiàn),尚未有產(chǎn)品達(dá)到類似 Oracle/MySQL 在關(guān)系型數(shù)據(jù)庫領(lǐng)域中絕對領(lǐng)先的狀態(tài)。
業(yè)界提出的開源或閉源的交互式解決方案,主要從大數(shù)據(jù)、NoSQL 兩個不同的方向進(jìn)行演進(jìn),以期望提供用戶最好的交互式分析體驗。
下圖所示是不同維度下的代表性解決方案,供大家參考了解:
其中,ClickHouse 作為一款 PB 級的交互式分析數(shù)據(jù)庫,最初是由號稱 “ 俄羅斯 Google ” 的 Yandex 公司開發(fā),主要作為世界第二大 Web 流量分析平臺 Yandex.Metrica(類 Google Analytic、友盟統(tǒng)計)的核心存儲,為 Web 站點、移動 App 實時在線的生成流量統(tǒng)計報表。
自 2016 年開源以來,ClickHouse 憑借其數(shù)倍于業(yè)界頂尖分析型數(shù)據(jù)庫的極致性能,成為交互式分析領(lǐng)域的后起之秀,發(fā)展速度非??欤珿ithub 上獲得 12.4K Star,DB-Engines 排名近一年上升 26 位,并獲得思科、Splunk、騰訊、阿里等頂級企業(yè)的采用。
下面是 ClickHouse 及其他開源 OLAP 產(chǎn)品的發(fā)展趨勢統(tǒng)計:
性能是衡量 OLAP 數(shù)據(jù)庫的關(guān)鍵指標(biāo),我們可以通過 ClickHouse 官方測試結(jié)果感受下 ClickHouse 的極致性能,其中綠色代表性能最佳,紅色代表性能較差,紅色越深代表性能越弱。
從測試結(jié)果看,ClickHouse 幾乎在所有場景下性能都最佳,并且從所有查詢整體看,ClickHouse 領(lǐng)先圖靈獎得主 Michael Stonebraker 所創(chuàng)建的 Vertica 達(dá) 6 倍,領(lǐng)先 Greenplum 達(dá)到 18 倍。
更多測試結(jié)果可參考 OLAP 系統(tǒng)第三方評測 ,盡管該測試使用了無索引的表引擎(或稱表類型),ClickHouse 仍然在單表模式下體現(xiàn)了強(qiáng)勁的領(lǐng)先優(yōu)勢。
ClickHouse 架構(gòu)
集群架構(gòu)
ClickHouse 采用典型的分組式的分布式架構(gòu),具體集群架構(gòu)如上圖所示:
- Shard:集群內(nèi)劃分為多個分片或分組(Shard 0 … Shard N),通過 Shard 的線性擴(kuò)展能力,支持海量數(shù)據(jù)的分布式存儲計算。
- Node:每個 Shard 內(nèi)包含一定數(shù)量的節(jié)點(Node,即進(jìn)程),同一 Shard 內(nèi)的節(jié)點互為副本,保障數(shù)據(jù)可靠。ClickHouse 中副本數(shù)可按需建設(shè),且邏輯上不同 Shard 內(nèi)的副本數(shù)可不同。
- ZooKeeper Service:集群所有節(jié)點對等,節(jié)點間通過 ZooKeeper 服務(wù)進(jìn)行分布式協(xié)調(diào)。
數(shù)據(jù)模型
ClickHouse 采用經(jīng)典的表格存儲模型,屬于結(jié)構(gòu)化數(shù)據(jù)存儲系統(tǒng)。我們分別從面向用戶的邏輯數(shù)據(jù)模型和面向底層存儲的物理數(shù)據(jù)模型進(jìn)行介紹。
①邏輯數(shù)據(jù)模型
從用戶使用角度看,ClickHouse 的邏輯數(shù)據(jù)模型與關(guān)系型數(shù)據(jù)庫有一定的相似:一個集群包含多個數(shù)據(jù)庫,一個數(shù)據(jù)庫包含多張表,表用于實際存儲數(shù)據(jù)。
與傳統(tǒng)關(guān)系型數(shù)據(jù)庫不同的是,ClickHouse 是分布式系統(tǒng),如何創(chuàng)建分布式表呢?
ClickHouse 的設(shè)計是:先在每個 Shard 每個節(jié)點上創(chuàng)建本地表(即 Shard 的副本),本地表只在對應(yīng)節(jié)點內(nèi)可見;然后再創(chuàng)建分布式表,映射到前面創(chuàng)建的本地表。
這樣用戶在訪問分布式表時,ClickHouse 會自動根據(jù)集群架構(gòu)信息,把請求轉(zhuǎn)發(fā)給對應(yīng)的本地表。
創(chuàng)建分布式表的具體樣例如下:
- # 首先,創(chuàng)建本地表
- CREATE TABLE table_local ON CLUSTER cluster_test
- (
- OrderKey UInt32, # 列定義
- OrderDate Date,
- Quantity UInt8,
- TotalPrice UInt32,
- ……
- )
- ENGINE = MergeTree() # 表引擎
- PARTITION BY toYYYYMM(OrderDate) # 分區(qū)方式
- ORDER BY (OrderDate, OrderKey); # 排序方式
- SETTINGS index_granularity = 8192; # 數(shù)據(jù)塊大小
- # 然后,創(chuàng)建分布式表
- CREATE TABLE table_distribute ON CLUSTER cluster_test AS table_local
- ENGINE = Distributed(cluster_test, default, table_local, rand()) # 關(guān)系映射引擎
其中部分關(guān)鍵概念介紹如下,分區(qū)、數(shù)據(jù)塊、排序等概念會在物理存儲模型部分展開介紹:
- MergeTree:ClickHouse 中使用非常多的表引擎,底層采用 LSM Tree 架構(gòu),寫入生成的小文件會持續(xù) Merge。
- Distributed:ClickHouse 中的關(guān)系映射引擎,它把分布式表映射到指定集群、數(shù)據(jù)庫下對應(yīng)的本地表上。
更直觀的,ClickHouse 中的邏輯數(shù)據(jù)模型如下:
②物理存儲模型
接下來,我們來介紹每個分片副本內(nèi)部的物理存儲模型,具體如下:
- 數(shù)據(jù)分區(qū):每個分片副本的內(nèi)部,數(shù)據(jù)按照 PARTITION BY 列進(jìn)行分區(qū),分區(qū)以目錄的方式管理,本文樣例中表按照時間進(jìn)行分區(qū)。
- 列式存儲:每個數(shù)據(jù)分區(qū)內(nèi)部,采用列式存儲,每個列涉及兩個文件,分別是存儲數(shù)據(jù)的 .bin 文件和存儲偏移等索引信息的 .mrk2 文件。
- 數(shù)據(jù)排序:每個數(shù)據(jù)分區(qū)內(nèi)部,所有列的數(shù)據(jù)是按照 ORDER BY 列進(jìn)行排序的??梢岳斫鉃椋簩τ谏蛇@個分區(qū)的原始記錄行,先按 ORDER BY 列進(jìn)行排序,然后再按列拆分存儲。
- 數(shù)據(jù)分塊:每個列的數(shù)據(jù)文件中,實際是分塊存儲的,方便數(shù)據(jù)壓縮及查詢裁剪,每個塊中的記錄數(shù)不超過 index_granularity,默認(rèn) 8192。
- 主鍵索引:主鍵默認(rèn)與 ORDER BY 列一致,或為 ORDER BY 列的前綴。由于整個分區(qū)內(nèi)部是有序的,且切割為數(shù)據(jù)塊存儲,ClickHouse 抽取每個數(shù)據(jù)塊第一行的主鍵,生成一份稀疏的排序索引,可在查詢時結(jié)合過濾條件快速裁剪數(shù)據(jù)塊。
ClickHouse 核心特性
ClickHouse 為什么會有如此高的性能,獲得如此快速的發(fā)展速度?下面我們來從 ClickHouse 的核心特性角度來進(jìn)一步介紹。
列存儲
ClickHouse 采用列存儲,這對于分析型請求非常高效。
一個典型且真實的情況是:如果我們需要分析的數(shù)據(jù)有 50 列,而每次分析僅讀取其中的 5 列,那么通過列存儲,我們僅需讀取必要的列數(shù)據(jù)。
相比于普通行存,可減少 10 倍左右的讀取、解壓、處理等開銷,對性能會有質(zhì)的影響。
這是分析場景下,列存儲數(shù)據(jù)庫相比行存儲數(shù)據(jù)庫的重要優(yōu)勢。這里引用 ClickHouse 官方一個生動形象的動畫,方便大家理解。
行存儲:從存儲系統(tǒng)讀取所有滿足條件的行數(shù)據(jù),然后在內(nèi)存中過濾出需要的字段,速度較慢。
列存儲:僅從存儲系統(tǒng)中讀取必要的列數(shù)據(jù),無用列不讀取,速度非???。
向量化執(zhí)行
在支持列存的基礎(chǔ)上,ClickHouse 實現(xiàn)了一套面向向量化處理的計算引擎,大量的處理操作都是向量化執(zhí)行的。
相比于傳統(tǒng)火山模型中的逐行處理模式,向量化執(zhí)行引擎采用批量處理模式,可以大幅減少函數(shù)調(diào)用開銷,降低指令、數(shù)據(jù)的 Cache Miss,提升 CPU 利用效率。
并且 ClickHouse 可利用 SIMD 指令進(jìn)一步加速執(zhí)行效率。這部分是 ClickHouse 優(yōu)于大量同類 OLAP 產(chǎn)品的重要因素。
以商品訂單數(shù)據(jù)為例,查詢某個訂單總價格的處理過程,由傳統(tǒng)的按行遍歷處理的過程,轉(zhuǎn)換為按 Block 處理的過程。
具體如下圖:
編碼壓縮
由于 ClickHouse 采用列存儲,相同列的數(shù)據(jù)連續(xù)存儲,且底層數(shù)據(jù)在存儲時是經(jīng)過排序的,這樣數(shù)據(jù)的局部規(guī)律性非常強(qiáng),有利于獲得更高的數(shù)據(jù)壓縮比。
此外,ClickHouse 除了支持 LZ4、ZSTD 等通用壓縮算法外,還支持 Delta、DoubleDelta、Gorilla 等專用編碼算法,用于進(jìn)一步提高數(shù)據(jù)壓縮比。
其中 DoubleDelta、Gorilla 是 Facebook 專為時間序數(shù)據(jù)而設(shè)計的編碼算法,理論上在列存儲環(huán)境下,可接近專用時序存儲的壓縮比,詳細(xì)可參考 Gorilla 論文。
在實際場景下,ClickHouse 通常可以達(dá)到 10:1 的壓縮比,大幅降低存儲成本。
同時,超高的壓縮比又可以降低存儲讀取開銷、提升系統(tǒng)緩存能力,從而提高查詢性能。
多索引
列存用于裁剪不必要的字段讀取,而索引則用于裁剪不必要的記錄讀取。ClickHouse 支持豐富的索引,從而在查詢時盡可能的裁剪不必要的記錄讀取,提高查詢性能。
ClickHouse 中最基礎(chǔ)的索引是主鍵索引。前面我們在物理存儲模型中介紹,ClickHouse 的底層數(shù)據(jù)按建表時指定的 ORDER BY 列進(jìn)行排序,并按 index_granularity 參數(shù)切分成數(shù)據(jù)塊,然后抽取每個數(shù)據(jù)塊的第一行形成一份稀疏的排序索引。
用戶在查詢時,如果查詢條件包含主鍵列,則可以基于稀疏索引進(jìn)行快速的裁剪。
這里通過下面的樣例數(shù)據(jù)及對應(yīng)的主鍵索引進(jìn)行說明:
樣例中的主鍵列為 CounterID、Date,這里按每 7 個值作為一個數(shù)據(jù)塊,抽取生成了主鍵索引 Marks 部分。
當(dāng)用戶查詢 CounterID equal ‘h’ 的數(shù)據(jù)時,根據(jù)索引信息,只需要讀取 Mark number 為 6 和 7 的兩個數(shù)據(jù)塊。
ClickHouse 支持更多其他的索引類型,不同索引用于不同場景下的查詢裁剪,具體匯總?cè)缦拢敿?xì)的介紹參考 ClickHouse 官方文檔:
物化視圖(Cube/Rollup)
OLAP 分析領(lǐng)域有兩個典型的方向:
- 一是 ROLAP,通過列存、索引等各類技術(shù)手段,提升查詢時性能。
- 另一是 MOLAP,通過預(yù)計算提前生成聚合后的結(jié)果數(shù)據(jù),降低查詢讀取的數(shù)據(jù)量,屬于計算換性能方式。
前者更為靈活,但需要的技術(shù)棧相對復(fù)雜;后者實現(xiàn)相對簡單,但要達(dá)到的極致性能,需要生成所有常見查詢對應(yīng)的物化視圖,消耗大量計算、存儲資源。
物化視圖的原理如下圖所示,可以在不同維度上對原始數(shù)據(jù)進(jìn)行預(yù)計算匯總:
ClickHouse 一定程度上做了兩者的結(jié)合,在盡可能采用 ROLAP 方式提高性能的同時,支持一定的 MOLAP 能力,具體實現(xiàn)方式為 MergeTree 系列表引擎和 MATERIALIZED VIEW。
事實上,Yandex.Metrica 的存儲系統(tǒng)也經(jīng)歷過使用純粹 MOLAP 方案的發(fā)展過程,具體參考 ClickHouse的發(fā)展歷史。
用戶在使用時,可優(yōu)先按照 ROLAP 思路進(jìn)行調(diào)優(yōu),例如主鍵選擇、索引優(yōu)化、編碼壓縮等。
當(dāng)希望性能更高時,可考慮結(jié)合 MOLAP 方式,針對高頻查詢模式,建立少量的物化視圖,消耗可接受的計算、存儲資源,進(jìn)一步換取查詢性能。
其他特性
除了前面所述,ClickHouse 還有非常多其他特性,抽取列舉如下,更多詳細(xì)內(nèi)容可參考 ClickHouse官方文檔:
- SQL 方言:在常用場景下,兼容 ANSI SQL,并支持 JDBC、ODBC 等豐富接口。
- 權(quán)限管控:支持 Role-Based 權(quán)限控制,與關(guān)系型數(shù)據(jù)庫使用體驗類似。
- 多機(jī)多核并行計算:ClickHouse 會充分利用集群中的多節(jié)點、多線程進(jìn)行并行計算,提高性能。
- 近似查詢:支持近似查詢算法、數(shù)據(jù)抽樣等近似查詢方案,加速查詢性能。
- Colocated Join:數(shù)據(jù)打散規(guī)則一致的多表進(jìn)行 Join 時,支持本地化的 Colocated Join,提升查詢性能。
- ……
ClickHouse 的不足
前面介紹了大量 ClickHouse 的核心特性,方便讀者了解 ClickHouse 高性能、快速發(fā)展的背后原因。
當(dāng)然,ClickHouse 作為后起之秀,遠(yuǎn)沒有達(dá)到盡善盡美,還有不少需要待完善的方面,典型代表如下:
分布式管控
分布式系統(tǒng)通常包含三個重要組成部分:
- 存儲引擎
- 計算引擎
- 分布式管控層
ClickHouse 有一個非常突出的高性能存儲引擎,但在分布式管控層顯得較為薄弱,使得運營、使用成本偏高。
主要體現(xiàn)在:
①分布式表
ClickHouse 對分布式表的抽象并不完整,在多數(shù)分布式系統(tǒng)中,用戶僅感知集群和表,對分片和副本的管理透明,而在 ClickHouse 中,用戶需要自己去管理分片、副本。
例如前面介紹的建表過程:用戶需要先創(chuàng)建本地表(分片的副本),然后再創(chuàng)建分布式表,并完成分布式表到本地表的映射。
②彈性伸縮
ClickHouse 集群自身雖然可以方便的水平增加節(jié)點,但并不支持自動的數(shù)據(jù)均衡。
例如,當(dāng)包含 6 個節(jié)點的線上生產(chǎn)集群因存儲或計算壓力大,需要進(jìn)行擴(kuò)容時,我們可以方便的擴(kuò)容到 10 個節(jié)點。
但是數(shù)據(jù)并不會自動均衡,需要用戶給已有表增加分片或者重新建表,再把寫入壓力重新在整個集群內(nèi)打散,而存儲壓力的均衡則依賴于歷史數(shù)據(jù)過期。
ClickHouse在彈性伸縮方面的不足,大幅增加了業(yè)務(wù)在進(jìn)行水平伸縮時運營壓力。
基于 ClickHouse 的當(dāng)前架構(gòu),實現(xiàn)自動均衡相對復(fù)雜,導(dǎo)致相關(guān)問題的根因在于 ClickHouse 分組式的分布式架構(gòu):同一分片的主從副本綁定在一組節(jié)點上。
更直接的說,分片間數(shù)據(jù)打散是按照節(jié)點進(jìn)行的,自動均衡過程不能簡單的搬遷分片到新節(jié)點,會導(dǎo)致路由信息錯誤。
而創(chuàng)建新表并在集群中進(jìn)行全量數(shù)據(jù)重新打散的方式,操作開銷過高。
③故障恢復(fù)
與彈性伸縮類似,在節(jié)點故障的情況下,ClickHouse 并不會利用其它機(jī)器補齊缺失的副本數(shù)據(jù)。需要用戶先補齊節(jié)點后,然后系統(tǒng)再自動在副本間進(jìn)行數(shù)據(jù)同步。
計算引擎
雖然 ClickHouse 在單表性能方面表現(xiàn)非常出色,但是在復(fù)雜場景仍有不足,缺乏成熟的 MPP 計算引擎和執(zhí)行優(yōu)化器。
例如:多表關(guān)聯(lián)查詢、復(fù)雜嵌套子查詢等場景下查詢性能一般,需要人工優(yōu)化;缺乏 UDF 等能力,在復(fù)雜需求下擴(kuò)展能力較弱等。
這也和 OLAP 系統(tǒng)第三方評測的結(jié)果相符。這對于性能如此出眾的存儲引擎來說,非常可惜。
實時寫入
ClickHouse 采用類 LSM Tree 架構(gòu),并且建議用戶通過批量方式進(jìn)行寫入,每個批次不少于 1000 行 或 每秒鐘不超過一個批次,從而提高集群寫入性能。
實際測試情況下,32 vCPU&128G 內(nèi)存的情況下,單節(jié)點寫性能可達(dá) 50 MB/s~200 MB/s,對應(yīng) 5w~20w TPS。
但 ClickHouse 并不適合實時寫入,原因在于 ClickHouse 并非典型的 LSM Tree 架構(gòu),它沒有實現(xiàn) Memory Table 結(jié)構(gòu),每批次寫入直接落盤作為一棵 Tree(如果單批次過大,會拆分為多棵 Tree),每條記錄實時寫入會導(dǎo)致底層大量的小文件,影響查詢性能。
這使得 ClickHouse 不適合有實時寫入需求的業(yè)務(wù),通常需要在業(yè)務(wù)和 ClickHouse 之間引入一層數(shù)據(jù)緩存層,實現(xiàn)批量寫入。
結(jié)語
本文重點分享了 ClickHouse 的整體架構(gòu)及眾多核心特性,分析了 ClickHouse 如何實現(xiàn)極致性能的存儲引擎,從而成為 OLAP 領(lǐng)域的后起之秀。
ClickHouse 仍然年輕,雖然在某些方面存在不足,但極致性能的存儲引擎,使得 ClickHouse 成為一個非常優(yōu)秀的存儲底座。
后續(xù)我們會在不斷拓展業(yè)務(wù)的同時,優(yōu)先從分布式管控層和計算引擎層著手,持續(xù)優(yōu)化 ClickHouse 的易用性、性能,打造業(yè)界領(lǐng)先的 OLAP 分析數(shù)據(jù)庫。
同時,我們會持續(xù)輸出內(nèi)核優(yōu)化、最佳實踐等經(jīng)驗,歡迎更多技術(shù)愛好者們一起探索、交流。
參考資料:
- 采用文檔:
https://clickhouse.tech/docs/zh/introduction/adopters/
- ClickHouse 官方測試結(jié)果:
https://clickhouse.tech/benchmark/dbms/
- OLAP 系統(tǒng)第三方評測:
http://www.clickhouse.com.cn/topic/5c453371389ad55f127768ea
- 專用編碼算法支持:
https://clickhouse.tech/docs/zh/sql-reference/statements/create/#codecs
- Gorilla 論文:
http://www.vldb.org/pvldb/vol8/p1816-teller.pdf
- 索引支持:
https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/mergetree/#table_engine-mergetree-data_skipping-indexes
- MergeTree系列表引擎:
https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/mergetree/
- MATERIALIZED VIEW:
https://clickhouse.tech/docs/en/sql-reference/statements/create/view/#materialized
- ClickHouse的發(fā)展歷史:
https://clickhouse.tech/docs/en/introduction/history/
- ClickHouse官方文檔:
https://clickhouse.tech/docs/en/
作者:姜國強(qiáng)
簡介:騰訊實時檢索研發(fā)工程師
編輯:陶家龍
出處:轉(zhuǎn)載自公眾號云加社區(qū)(ID:QcloudCommunity)