联机分析的列式数据库 clickHouse
? ? ? ? ? ? ??
ClickHouse是一個用于聯機分析(OLAP)的列式數據庫管理系統(DBMS)。
在傳統的行式數據庫系統中,數據按如下順序存儲:
| #0 | 89354350662 | 1 | Investor Relations | 1 | 2016-05-18 05:19:20 |
| #1 | 90329509958 | 0 | Contact us | 1 | 2016-05-18 08:10:20 |
| #2 | 89953706054 | 1 | Mission | 1 | 2016-05-18 07:38:00 |
| #N | … | … | … | … | … |
處于同一行中的數據總是被物理的存儲在一起。
常見的行式數據庫系統有:MySQL、Postgres和MS SQL Server。
在列式數據庫系統中,數據按如下的順序存儲:
| WatchID: | 89354350662 | 90329509958 | 89953706054 | … |
| JavaEnable: | 1 | 0 | 1 | … |
| Title: | Investor Relations | Contact us | Mission | … |
| GoodEvent: | 1 | 1 | 1 | … |
| EventTime: | 2016-05-18 05:19:20 | 2016-05-18 08:10:20 | 2016-05-18 07:38:00 | … |
這些示例只顯示了數據的排列順序。來自不同列的值被單獨存儲,來自同一列的數據被存儲在一起。
常見的列式數據庫有: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行)更新,而不是單行更新;或者根本沒有更新。
已添加到數據庫的數據不能修改。
對于讀取,從數據庫中提取相當多的行,但只提取列的一小部分。
寬表,即每個表包含著大量的列
查詢相對較少(通常每臺服務器每秒查詢數百次或更少)
對于簡單查詢,允許延遲大約50毫秒
列中的數據相對較小:數字和短字符串(例如,每個URL 60個字節)
處理單個查詢時需要高吞吐量(每臺服務器每秒可達數十億行)
事務不是必須的
對數據一致性要求低
每個查詢有一個大表。除了他以外,其他的都很小。
查詢結果明顯小于源數據。換句話說,數據經過過濾或聚合,因此結果適合于單個服務器的RAM中
很容易可以看出,OLAP場景與其他通常業務場景(例如,OLTP或K/V)有很大的不同, 因此想要使用OLTP或Key-Value數據庫去高效的處理分析查詢場景,并不是非常完美的適用方案。例如,使用OLAP數據庫去處理分析請求通常要優于使用MongoDB或Redis去處理分析請求。
列式數據庫更適合OLAP場景的原因?
列式數據庫更適合于OLAP場景(對于大多數查詢而言,處理速度至少提高了100倍),下面詳細解釋了原因(通過圖片更有利于直觀理解):
行式
列式
看到差別了么?下面將詳細介紹為什么會發生這種情況。
輸入/輸出?
針對分析類查詢,通常只需要讀取表的一小部分列。在列式數據庫中你可以只讀取你需要的數據。例如,如果只需要讀取100列中的5列,這將幫助你最少減少20倍的I/O消耗。
由于數據總是打包成批量讀取的,所以壓縮是非常容易的。同時數據按列分別存儲這也更容易壓縮。這進一步降低了I/O的體積。
由于I/O的降低,這將幫助更多的數據被系統緩存。
例如,查詢?統計每個廣告平臺的記錄數量?需要讀取?廣告平臺ID?這一列,它在未壓縮的情況下需要1個字節進行存儲。如果大部分流量不是來自廣告平臺,那么這一列至少可以以十倍的壓縮率被壓縮。當采用快速壓縮算法,它的解壓速度最少在十億字節(未壓縮數據)每秒。換句話說,這個查詢可以在單個服務器上以每秒大約幾十億行的速度進行處理。這實際上是當前實現的速度。
CPU?
由于執行一個查詢需要處理大量的行,因此在整個向量上執行所有操作將比在每一行上執行所有操作更加高效。同時這將有助于實現一個幾乎沒有調用成本的查詢引擎。如果你不這樣做,使用任何一個機械硬盤,查詢引擎都不可避免的停止CPU進行等待。所以,在數據按列存儲并且按列執行是很有意義的。
有兩種方法可以做到這一點:
向量引擎:所有的操作都是為向量而不是為單個值編寫的。這意味著多個操作之間的不再需要頻繁的調用,并且調用的成本基本可以忽略不計。操作代碼包含一個優化的內部循環。
代碼生成:生成一段代碼,包含查詢中的所有操作。
這是不應該在一個通用數據庫中實現的,因為這在運行簡單查詢時是沒有意義的。但是也有例外,例如,MemSQL使用代碼生成來減少處理SQL查詢的延遲(只是為了比較,分析型數據庫通常需要優化的是吞吐而不是延遲)。
請注意,為了提高CPU效率,查詢語言必須是聲明型的(SQL或MDX), 或者至少一個向量(J,K)。查詢應該只包含隱式循環,允許進行優化。
總結
以上是生活随笔為你收集整理的联机分析的列式数据库 clickHouse的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于单TCP连接的高吞吐模型设计
- 下一篇: sql server和mysql的区别是