ClickHouse是一個用於聯機分析(OLAP)的列式資料庫管理系統(DBMS)。ClickHouse是近年來備受關注的開源列式資料庫,主要用於數據分析(OLAP)領域。目前國內社區火熱,各個大廠紛紛跟進大規模使用:今日頭條 內部用ClickHouse來做用戶行為分析,內部一共幾千個ClickHouse節點,單集群最大1200節點,總數據量幾十PB,日增原始數據300TB左右。
哪些公司使用這款開源列式資料庫
今日頭條內部用ClickHouse來做用戶行為分析,內部一共幾千個ClickHouse節點,單集群最大1200節點,總數據量幾十PB,日增原始數據300TB左右。
騰訊內部用ClickHouse做遊戲數據分析,並且為之建立了一整套監控運維體系。
攜程內部從18年7月份開始接入試用,目前80%的業務都跑在ClickHouse上。每天數據增量十多億,近百萬次查詢請求。
快手內部也在使用ClickHouse,存儲總量大約10PB, 每天新增200TB, 90%查詢小於3S。
在傳統的行式資料庫系統中,數據按如下順序存儲:
處於同一行中的數據總是被物理的存儲在一起。
常見的行式資料庫系統有: MySQL、Postgres和MS SQL Server。
在列式資料庫系統中,數據按如下的順序存儲:
該示例中只展示了數據在列式資料庫中數據的排列順序。
對於存儲而言,列式資料庫總是將同一列的數據存儲在一起,不同列的數據也總是分開存儲。
常見的列式資料庫有: 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 rows)進行寫入
不修改已添加的數據
每次查詢都從資料庫中讀取大量的行,但是同時又僅需要少量的列
寬表,即每個表包含著大量的列
較少的查詢(通常每臺伺服器每秒數百個查詢或更少)
對於簡單查詢,允許延遲大約50毫秒
列中的數據相對較小: 數字和短字符串(例如,每個URL 60個字節)
處理單個查詢時需要高吞吐量(每個伺服器每秒高達數十億行)
事務不是必須的
對數據一致性要求低
每一個查詢除了一個大表外都很小
查詢結果明顯小於源數據,換句話說,數據被過濾或聚合後能夠被盛放在單臺伺服器的內存中
列式資料庫更適合OLAP場景的原因
行式
列式
看到差別了麼?下面將詳細介紹為什麼會發生這種情況。
輸入/輸出
針對分析類查詢,通常只需要讀取表的一小部分列。在列式資料庫中你可以只讀取你需要的數據。例如,如果只需要讀取100列中的5列,這將幫助你最少減少20倍的I/O消耗。
由於數據總是打包成批量讀取的,所以壓縮是非常容易的。同時數據按列分別存儲這也更容易壓縮。這進一步降低了I/O的體積。
由於I/O的降低,這將幫助更多的數據被系統緩存。
例如,查詢 統計每個廣告平臺的記錄數量 需要讀取 廣告平臺ID 這一列,它在未壓縮的情況下需要1個字節進行存儲。如果大部分流量不是來自廣告平臺,那麼這一列至少可以以十倍的壓縮率被壓縮。當採用快速壓縮算法,它的解壓速度最少在十億字節(未壓縮數據)每秒。換句話說,這個查詢可以在單個伺服器上以每秒大約幾十億行的速度進行處理。這實際上是當前實現的速度。
CPU
由於執行一個查詢需要處理大量的行,因此在整個向量上執行所有操作將比在每一行上執行所有操作更加高效。同時這將有助於實現一個幾乎沒有調用成本的查詢引擎。如果你不這樣做,使用任何一個機械硬碟,查詢引擎都不可避免的停止CPU進行等待。所以,在數據按列存儲並且按列執行是很有意義的。
有兩種方法可以做到這一點:
向量引擎:所有的操作都是為向量而不是為單個值編寫的。這意味著多個操作之間的不再需要頻繁的調用,並且調用的成本基本可以忽略不計。操作代碼包含一個優化的內部循環。
代碼生成:生成一段代碼,包含查詢中的所有操作。
這是不應該在一個通用資料庫中實現的,因為這在運行簡單查詢時是沒有意義的。但是也有例外,例如,MemSQL使用代碼生成來減少處理SQL查詢的延遲(只是為了比較,分析型資料庫通常需要優化的是吞吐而不是延遲)。
請注意,為了提高CPU效率,查詢語言必須是聲明型的(SQL或MDX), 或者至少一個向量(J,K)。 查詢應該只包含隱式循環,允許進行優化。