ClickHouse是一個用於聯機分析(OLAP)的列式數據庫管理系統(DBMS)。
在傳統的行式數據庫中,數據存儲方式如下所示:
row | id | status | title | time |
---|---|---|---|---|
#1 | 12312 | 1 | alksdjalkdj | 2016-05-18 05:19:20 |
#2 | 12313 | 1 | alksdjalkdj | 2016-05-18 05:19:20 |
#3 | 12314 | 1 | alksdjalkdj | 2016-05-18 05:19:20 |
#4 | 12315 | 1 | alksdjalkdj | 2016-05-18 05:19:20 |
常見的行式數據庫有:mysql,postgresql、sqlserver等。
而列式數據庫的存儲方式如下所示:
row | #1 | #2 | #3 | #4 |
---|---|---|---|---|
id | 12312 | 12313 | 12314 | 12315 |
status | 1 | 1 | 1 | 1 |
title | alksdjalkdj | alksdjalkdj | alksdjalkdj | alksdjalkdj |
time | 2016-05-18 05:19:20 | 2016-05-18 05:19:20 | 2016-05-18 05:19:20 | 2016-05-18 05:19:20 |
常見的列數數據庫有:Vertica、 Paraccel (Actian Matrix,Amazon Redshift)、 Sybase IQ、 Exasol、 Infobright、 InfiniDB、 MonetDB (VectorWise, Actian Vector)、 LucidDB、 SAP HANA、 Google Dremel、 Google PowerDrill、 Druid、 kdb+。
OLAP場景的關鍵特徵
- 絕大多數是讀請求
- 數據以相當大的批次(> 1000行)更新,而不是單行更新;或者根本沒有更新。
- 已添加到數據庫的數據不能修改。
- 對於讀取,從數據庫中提取相當多的行,但只提取列的一小部分。
- 寬表,即每個表包含着大量的列(對join支持不好)
- 查詢相對較少(通常每臺服務器每秒查詢數百次或更少)
- 對於簡單查詢,允許延遲大約50毫秒
- 列中的數據相對較小:數字和短字符串(例如,每個URL 60個字節)
- 處理單個查詢時需要高吞吐量(每臺服務器每秒可達數十億行)
- 事務不是必須的(不支持事務)
- 對數據一致性要求低
- 每個查詢有一個大表。除了他以外,其他的都很小。
- 查詢結果明顯小於源數據。換句話說,數據經過過濾或聚合,因此結果適合於單個服務器的RAM中
行式數據庫與列式數據庫在查詢步驟上的差別
有一張學生表student,字段有id,name,age,address,phone,id_card等字段。
1)行式數據庫(以mysql爲例)
假設我們執行select id,name,age from student
首先會搜索innodb引擎的b+樹,在葉子節點找到所有的數據,然後再講需要的字段拆分出來,實際差分過程是在緩衝池中做的,這部分的時間消耗我們暫時忽略。假設表中有10000條數據,那麼此次IO就是10000條全量數據的IO。
2)列式數據庫
列式的存儲我們只需要根據需要查詢的id,name,age,取出本行的數據即可,即是所有我們需要的數據,當通過IO到內存時,沒有將多餘的address,phone等字段返回,這將大大提升此次查詢的效率。
我們假設每個字段一個字節,那麼行式數據庫相當於一次IO要傳輸6W個字節的數據;而列式的只需要3w。如此就相當於提升了2倍的性能。
假設如果表中有100個列,而你只需要5個,那麼就是20倍的提升。
ClickHouse的特性
1)數據壓縮
在一些列式數據庫管理系統中(例如:InfiniDB CE 和 MonetDB) 並沒有使用數據壓縮。但是, 若想達到比較優異的性能,數據壓縮確實起到了至關重要的作用。
除了在磁盤空間和CPU消耗之間進行高效通用壓縮編解碼器之外,ClickHouse還提供針對特定類型數據的專用編解碼器,這使得ClickHouse能夠與更小的數據庫(如時間序列數據庫)競爭並超越它們。
2)數據的磁盤存儲
ClickHouse被設計用於工作在傳統磁盤上的系統,它提供每GB更低的存儲成本,但如果可以使用SSD和內存,它也會合理的利用這些資源。
3)多核心並行處理
ClickHouse會使用服務器上一切可用的資源,從而以最自然的方式並行處理大型查詢。
4)多服務器分佈式處理
數據可以保存在不同的shard上,每一個shard都由一組用於容錯的replica組成,查詢可以並行地在所有shard上進行處理。
5)支持SQL
ClickHouse支持一種[基於SQL的聲明式查詢語言,它在許多情況下與ANSI SQL標準相同。
支持的查詢GROUP BY, ORDER BY, FROM, JOIN, IN以及非相關子查詢。
相關(依賴性)子查詢和窗口函數暫不受支持,但將來會被實現。
6)向量引擎
爲了高效的使用CPU,數據不僅僅按列存儲,同時還按向量(列的一部分)進行處理,這樣可以更加高效地使用CPU。
實際是按照向量的方向查詢數據,順序讀取磁盤,從而減少cpu等待磁盤IO的時間。
7)實時數據更新
ClickHouse支持在表中定義主鍵。爲了使查詢能夠快速在主鍵中進行範圍查找,數據總是以增量的方式有序的存儲在MergeTree中。因此,數據可以持續不斷地高效的寫入到表中,並且寫入的過程中不會存在任何加鎖的行爲。
8)索引
按照主鍵對數據進行排序,ClickHouse在幾十毫秒以內完成對數據特定值或範圍的查找。
9)適合在線查詢
在線查詢意味着在沒有對數據做任何預處理的情況下以極低的延遲處理查詢,並將結果加載到用戶的頁面中。
10)支持近似計算
ClickHouse提供各種各樣在允許犧牲數據精度的情況下對查詢進行加速的方法:
1、用於近似計算的各類聚合函數,如:distinct values, medians, quantiles
2、基於數據的部分樣本進行近似查詢。這時,僅會從磁盤檢索少部分比例的數據。
3、不使用全部的聚合條件,通過隨機選擇有限個數據聚合條件進行聚合。這在數據聚合條件滿足某些分佈條件下,在提供相當準確的聚合結果的同時降低了計算資源的使用。
11)自適應連接算法(Adaptive Join Algorithm)
ClickHouse支持自定義JOIN多個表,它更傾向於散列連接算法,如果有多個大表,則使用合併-連接算法
12)支持數據複製和數據完整性
ClickHouse使用異步的多主複製技術。當數據被寫入任何一個可用副本後,系統會在後臺將數據分發給其他副本,以保證系統在不同副本上保持相同的數據。在大多數情況下ClickHouse能在故障後自動恢復,在一些少數的複雜情況下需要手動恢復。
13)自身的限制
1、沒有完整的事務支持。
2、缺少高頻率,低延遲的修改或刪除已存在數據的能力。僅能用於批量刪除或修改數據,但這符合 GDPR。
3、稀疏索引使得ClickHouse不適合通過其鍵檢索單行的點查詢。
性能
ClickHouse表現出了比同類可比較產品更優的性能。你可以在 這裏 查看具體的測試結果。
如下我截取一張和mysql的對比圖:1)單個大查詢吞吐量
吞吐量可以使用每秒處理的行數或每秒處理的字節數來衡量。
如果數據被放置在page cache中,則一個不太複雜的查詢在單個服務器上大約能夠以2-10GB/s(未壓縮)的速度進行處理(對於簡單的查詢,速度可以達到30GB/s)。
如果數據沒有在page cache中的話,那麼速度將取決於你的磁盤系統和數據的壓縮率。
例如,如果一個磁盤允許以400MB/s的速度讀取數據,並且數據壓縮率是3,則數據的處理速度爲1.2GB/s。這意味着,如果你是在提取一個10字節的列,那麼它的處理速度大約是1-2億行每秒。
對於分佈式處理,處理速度幾乎是線性擴展的,但這受限於聚合或排序的結果不是那麼大的情況下。
2)處理短查詢的延遲時間
如果一個查詢使用主鍵並且沒有太多行(幾十萬)進行處理,並且沒有查詢太多的列,那麼在數據被page cache緩存的情況下,它的延遲應該小於50毫秒(在最佳的情況下應該小於10毫秒)。
否則,延遲取決於數據的查找次數。如果你當前使用的是HDD(機械硬盤),在數據沒有加載的情況下,查詢所需要的延遲可以通過以下公式計算得知: 查找時間(10 ms) * 查詢的列的數量 * 查詢的數據塊的數量。
3)處理大量短查詢的吞吐量
在相同的情況下,ClickHouse可以在單個服務器上每秒處理數百個查詢(在最佳的情況下最多可以處理數千個)。但是由於這不適用於分析型場景。因此我們建議每秒最多查詢100次。
4)數據的寫入性能
我們建議每次寫入不少於1000行的批量寫入,或每秒不超過一個寫入請求。
當使用tab-separated格式將一份數據寫入到MergeTree表中時,寫入速度大約爲50到200MB/s。如果您寫入的數據每行爲1Kb,那麼寫入的速度爲50000到200000行每秒。如果您的行更小,那麼寫入速度將更高。
爲了提高寫入性能,您可以使用多個INSERT進行並行寫入,這將帶來線性的性能提升。