比Hive快279倍的資料庫-ClickHouse到底是怎樣的
問題導讀
1.什麼是ClickHouse?
2.ClickHouse適合哪些場景?
3.為什麼面向列的資料庫查詢如此快?
1.什麼是ClickHouse
ClickHouse是一個面向列的資料庫管理系統(DBMS),用於線上分析處理查詢(OLAP)。
在“傳統”面向行的DBMS中,資料按以下順序儲存:
換句話說,與行相關的所有值都物理地儲存在彼此旁邊。
面向行的DBMS的示例是MySQL,Postgres和MS SQL Server。
在面向列的DBMS中,資料儲存如下:
這些示例僅顯示資料的排列順序。不同列的值分別儲存,同一列的資料儲存在一起。
面向列的DBMS的示例:Vertica,Paraccel(Actian Matrix和Amazon Redshift),Sybase IQ,Exasol,Infobright,InfiniDB,MonetDB(VectorWise和Actian Vector),LucidDB,SAP HANA,Google Dremel,Google PowerDrill,Druid和KDB +。
儲存資料的不同順序更適合於不同的場景。資料訪問場景是指進行了哪些查詢,多長時間以及以何種比例進行查詢;為每種型別的查詢讀取多少資料 - 行,列和位元組;讀取和更新資料之間的關係;資料大小以及如何使用本地資料;transactions是否被使用,以及它們是否隔離;資料replication和邏輯完整性的要求;每種型別的查詢的延遲和吞吐量要求,等等。
系統負載越高,定製系統設定以匹配使用方案的要求就越重要,並且此定製變得越精細。沒有一個系統同樣適用於明顯不同的場景。如果系統適應各種場景,在高負載下,系統將同樣處理所有場景,或者僅適用於一種或幾種可能的場景。
2.OLAP場景的關鍵屬性
絕大多數請求都是讀訪問許可權。
資料以相當大的批次(> 1000行)更新,而不是單行更新;或者它根本沒有更新。
資料已新增到資料庫,但未進行修改。
對於讀取,從DB中提取了相當多的行,但只提取了一小部分列。
表格“寬”,意味著它們包含大量列。
查詢相對較少(通常每臺伺服器數百個查詢或每秒更少)。
對於簡單查詢,允許延遲大約50毫秒。
列值相當小:數字和短字串(例如,每個URL 60個位元組)。
處理單個查詢時需要高吞吐量(每個伺服器每秒最多數十億行)。
Transactions不是必需的。
對資料一致性要求低。
每個查詢有一個大表。所有表都很小,除了一個。
查詢結果明顯小於源資料。換句話說,資料被過濾或聚合,因此結果適合單個伺服器的RAM。
很容易看出OLAP場景與其他流行場景(例如OLTP或鍵值訪問)非常不同。 因此,如果希望獲得不錯的效能,嘗試使用OLTP或鍵值DB來處理分析查詢是沒有意義的。 例如,如果嘗試使用MongoDB或Redis進行分析,則與OLAP資料庫相比,效能會非常差。
3.為什麼面向列的資料庫在OLAP場景中更好地工作
面向列的資料庫更適合OLAP場景:它們在處理大多數查詢時至少快100倍。 原因在下面詳細解釋,但事實更容易在視覺上展示:
面向行的DBMS
面向列的DBMS
看到不同?
輸入/輸出
對於分析查詢,只需要讀取少量表列。 在面向列的資料庫中,只能讀取所需的資料。 例如,如果需要100列中的5列,則可以預期I / O減少20倍。
由於資料以資料包形式讀取,因此更容易壓縮。 列中的資料也更容易壓縮。 這進一步減少了I / O量。
由於I / O減少,更多資料適合系統快取。
例如,查詢“計算每個廣告平臺的記錄數”需要讀取一個“廣告平臺ID”列,其佔用未壓縮的1個位元組。 如果大多數流量不是來自廣告平臺,則可以預期此列的壓縮率至少為10倍。 當使用快速壓縮演算法時,資料解壓縮可以每秒至少幾千兆位元組的未壓縮資料的速度進行。 換句話說,可以在單個伺服器上以每秒大約幾十億行的速度處理該查詢。 這種速度實際上是在實踐中實現的。
例子:
[Bash shell] 純文字檢視 複製程式碼
?
0102030405060708091011121314151617181920212223242526272829303132333435363738394041 | $ clickhouse-client ClickHouse client version 0.0.52053. Connecting to localhost:9000. Connected to ClickHouse server version 0.0.52053. :) SELECT CounterID, count() FROM hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20 SELECT CounterID, count() FROM hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20 ┌─CounterID─┬──count()─┐ │ 114208 │ 56057344 │ │ 115080 │ 51619590 │ │ 3228 │ 44658301 │ │ 38230 │ 42045932 │ │ 145263 │ 42042158 │ │ 91244 │ 38297270 │ │ 154139 │ 26647572 │ │ 150748 │ 24112755 │ │ 242232 │ 21302571 │ │ 338158 │ 13507087 │ │ 62180 │ 12229491 │ │ 82264 │ 12187441 │ │ 232261 │ 12148031 │ │ 146272 │ 11438516 │ │ 168777 │ 11403636 │ │ 4120072 │ 11227824 │ │ 10938808 │ 10519739 │ │ 74088 │ 9047015 │ │ 115079 │ 8837972 │ │ 337234 │ 8205961 │ └───────────┴──────────┘ 20 rows in set . Elapsed: 0.153 sec. Processed 1.00 billion rows, 4.00 GB (6.53 billion rows /s ., 26.10 GB /s .) :) |
CPU
由於執行查詢需要處理大量行,因此有助於為整個向量而不是單獨的行排程所有操作,或者實現查詢引擎以便幾乎不需要排程成本。如果不這樣做,使用任何half-decent的磁碟子系統,查詢直譯器將不可避免地停止CPU。將資料儲存在列中並在可能的情況下按列處理它是有意義的。
有兩種方法可以做到這一點:
向量引擎:所有操作都是為向量而不是為單獨的值編寫的。這意味著不需要經常呼叫操作,並且排程成本可以忽略不計。操作程式碼包含優化的內部迴圈。
程式碼生成:為查詢生成的程式碼中包含所有間接呼叫。
這不是在“傳統”資料庫中完成的,因為在執行簡單查詢時沒有意義。但是,也有例外。例如,MemSQL使用程式碼生成來減少處理SQL查詢時的延遲。 (為了進行比較,分析DBMS需要優化吞吐量,而不是延遲。)
請注意,對於CPU效率,查詢語言必須是宣告性的(SQL或MDX),或者至少是向量(J,K)。查詢應該只包含隱式迴圈,允許優化。
每天進步一點點,歡迎關注公眾號
↑ 翹首以盼等你關注
轉載註明本文連結:
http://www.aboutyun.com/forum.php?mod=viewthread&tid=26264
----------------------------END----------------------------
1.about雲知識星球,掃碼可瞭解
2.加好友領取專案資料,附上“2”;
專案介紹:
http://www.aboutyun.com/forum.php?mod=viewthread&tid=25235
本公眾號精彩文章推薦: