一、名詞
MMP:Massively Parallel Processing,是將任務並行的分散到多個服務器和節點上,在每個節點上計算完成后,將各自部分的結果匯總在一起得到最終的結果。采用MPP架構的數據庫稱為MPP數據庫。
向量化執行引擎:簡單理解為就是消除程序循環的優化,堆機器加快速度。實現向量化執行,需要利用CPU的SIMD指令。
SIMD:Single Instruction Multiple Data,用單條指令操作多條數據,不適合用於帶有較多分支判斷的場景。
DBMS:Database Management System,數據庫管理系統。
AST:Abstract syntax tree,抽象語法樹。
二、ClickHouse特點
1、完備的DBMS功能
- DDL:Data Definition Language,數據定義語言,可以動態地創建、修改或刪除數據庫、表和視圖,無須重啟服務。
- DML:Data Manipulation Language,數據操作語言,可以動態增刪改查數據。
- 權限控制:可以按照用戶粒度設置數據庫或者表的操作權限,保障數據的安全性。
- 數據備份與恢復:提供了數據備份導出與導入恢復機制,滿足生產環境的要求。
- 分布式管理:提供集群模式,自助管理多個數據庫節點。
2、列式存儲和數據壓縮
列式存儲,在掃描指定列時,不用按行組織其他非指定列的數據,避免多余的數據掃描。
數據壓縮,按照一定步長對數據進行匹配掃描,當發現重復部分的時候就進行編碼轉換,降低IO和存儲的壓力。例如【abcdefghi_bcdefghi】壓縮成【abcdefghi_(9,8)】,如果從下划線開始向前移動9個字節,會匹配到8個字節長度的重復 項,即這里的bcdefghi。數據默認使用LZ4算法壓縮。
3、向量化執行引擎
簡單理解就是消除程序循環的優化,堆機器加快速度,數據級並行。實現向量化執行,需要利用CPU的SIMD指令。
4、關系模型與SQL查詢
- 關系模型相比鍵值對等其他模型擁有更好的描述能力,在OLAP領域,已經有大量數據建模都是基於關系模型,其他數據庫遷移到CK的成本很低。
- 完全使用SQL作為查詢語言(支持 group by、order by、join、in等大部分標准SQL),SQL解析時大小寫敏感(select a 和 select A不同)。
5、多樣化的表引擎
CK的最初架構是基於MySQL實現的,表引擎設計就與MySQL類似,存儲引擎作為一層獨立的接口。種類繁多,根據業務場景自行選擇。
6、多線程與分布式
- 多線程處理就是通過線程級並行的方式實現了性能的提升。相比基於底層硬件實現的向量化執行SIMD,線程級並行通常由更高層次的軟件層面控制。多線程處理(線程級並行)與向量化執行(數據級並行)形成互補。
- 預先將數據分布到各台服務器,將數據的計算查詢直接下推到數據所在的服務器,因為計算移動比數據移動更加划算。
ClickHouse在數據存取方面,既支持分區(縱向擴展,利用多線程原理),也支持分片(橫向擴展,利用分布式原理),可以說是將多線程和分布式的技術應用到了極致。
7、多主架構
Multi-Master多主架構,集群中的每個節點角色對等,天然規避單點故障問題,適用於多數據中心、異地多活場景。
8、在線查詢
與其他分析型數據庫對比,存在許多相似之處,例如都支持海量查詢場景、支持列式存儲、數據分片、計算下推等特效,說明CK在設計上吸取了各路優點。
價格方面:其他開源系統慢,商用系統貴。CK又快又免費。
9、數據分片和分布式查詢
- CK有本地表(Local Table)和分布式表(Distributed Table),一張本地表等同於一份數據的分片,而分布式表不存儲數據,只是本地表的訪問代理。
- 分布式表類似分庫中間件,代理訪問多個數據分片,實現分布式查詢。
三、架構設計
1、Column與Field
這兩個是CK最基礎的映射單元,一列數據用一個Column對象表現,一列中的某一行(具體數值)用Field對象表示。
2、DataType
負責數據的序列化和反序列化相關工作,但是並不直接負責數據的讀取,而是轉由Column或Field對象獲取。在DataType的實現類中,聚合了相應數據類型的Column對象和Field對象。例如DataTypeString會引用字符串類型的ColumnString,而DataTypeArray則會引用數組類型ColumnArray,以此類推。
3、Block與Block流
CK的數據操作是面向Block對象進行的,並且是采用流的形式。雖然Column與Field組成了數據的基本映射單元,但對應到實際操作,它們還缺少一些必要信息,例如數據的類型以及列的名稱。於是乎,設計出了Block對象,Block=數據對象(Column/Feild) + DataType + 列名稱字符串。
流操作有兩個頂層接口:IBlockInputStream負責數據的讀取和關系運算,IBlockOutputStream負責將數據輸出到下一環節。
4、Table
在數據表的底層設計中並沒有所謂的Table對象,它直接使用 IStorage接口指代數據表。
表引擎是ClickHouse的一個顯著特性, 不同的表引擎由不同的子類實現,例如IStorageSystemOneBlock (系統表)、StorageMergeTree(合並樹表引擎)和 StorageTinyLog(日志表引擎)等。
5、Parser和Interpreter
Parser分析器負責創建AST對象,而Interpreter解釋器則負責解釋AST,並進一步創建查詢的執行管道。它們與IStorage一起,串聯起了整個數據查詢的過程。Parser分析器可以將一條SQL語句以遞歸下降的方法解析成 AST語法樹的形式。不同的SQL語句,會經由不同的Parser實現類解析。
6、Functions與Aggregate Functions
普通函數,例如四則運算、日前轉換、網址提取函數、IP地址脫敏函數。沒有狀態,函數效果作用於每行數據之上。在函數具體執行過程中,采用向量化的方式直接作用於一整列數據,而不是一行一行計算。
聚合函數,有狀態的,例如COUNT聚合函數,AggregateFunctionCount的狀態用整型UInt64記錄。聚合函數 的狀態支持序列化與反序列化,所以能夠在分布式節點之間進行傳 輸,以實現增量計算。
7、Cluster與Replication
集群由分片(Shard)組成,分片由副本(Replica)組成。
CK的1個節點只能擁有一個分片,如果要實現1分片、1副本,至少需要部署兩個服務節點。
分片是邏輯概念,物理承載由副本承擔。
四、CK為什么這么快?
- CK的設計采用自下而上的方式,因為最初的目的只是以最快速度進行group by 查詢和過濾。
- 針對特定場景,采用不同的底層算法。
- 在各個方面持續測試,持續改進。