Clickhouse架構及應用

內容大綱:node

  1. 背景;
  2. Clickhouse介紹;
  3. Clickhouse架構及性能;
  4. Clickhouse在好將來的實踐;
  5. 建設與規劃;
  6. 參考文獻。

背景

在日誌中心發展早期,日誌檢索分析主要基於elasticsearch進行,隨着日誌中心接入的業務愈來愈多,數據量也逐漸增加,基於日誌進行分析和監控告警的需求變得愈來愈複雜,很難用elasticsearch來知足,因此須要根據需求場景來選擇合適數據庫。咱們須要的:mysql

  • 數據量會很大,所以須要分佈式;
  • 支持實時寫入,支持快速計算,在較短期內能完成計算;
  • 強大的sql能力,實時指標sql化;
  • 人力有限,運維須要簡單;
  • 高效的壓縮比存儲,服務器有限,能夠用更少的服務器存儲更多的數據;

基於以上特色,咱們選擇了Clickhouse,接下來會介紹Clickhouse的特色、系統架構以及使用狀況。sql

Clickhouse介紹

一、Clickhouse特色

圖2-1 Clickhouse特色圖數據庫

能夠看到,Clickhouse的特色恰是咱們所須要的。接下來詳細的介紹一下核心特性:設計模式

1)完備的DBMS功能:數組

ClickHouse擁有完備的管理功能,因此它稱得上是一個DBMS ( Database Management System,數據庫管理系統 ),而不只是一個數據庫。緩存

做爲一個DBMS,它具有了一些基本功能,如:安全

  • DDL ( 數據定義語言 ):能夠動態地建立、修改或刪除數據庫、表和視圖,而無須重啓服務;
  • DML ( 數據操做語言 ):能夠動態查詢、插入、修改或刪除數據;
  • 權限控制:能夠按照用戶粒度設置數據庫或者表的操做權限,保障數據的安全性;
  • 數據備份與恢復:提供了數據備份導出與導入恢復機制,知足生產環境的要求;
  • 分佈式管理:提供集羣模式,可以自動管理多個數據庫節點。

2) 列式存儲與數據壓縮服務器

列式存儲和數據壓縮,對於一款高性能數據庫來講是必不可少的特性。想讓查詢變得更快,最簡單且有效的方法是減小數據掃描範圍和數據傳輸時的大小,而列式存儲和數據壓縮就能夠幫助咱們實現上述兩點。因爲Clickhouse是真正意義上的列式存儲,每一列都在不一樣的文件下,因此該文件數據類型一致,能夠更有效的壓縮。網絡

3) 向量化執行引擎

向量化執行以列存爲前提,主要思想是每次從磁盤上讀取一批列,這些列以數組形式組織。每次next都經過for循環處理列數組。這麼作能夠大幅減小next的調用次數。相應的CPU的利用率獲得了提升,另外數據被組織在一塊兒。

能夠進一步利用CPU硬件的特性,如SIMD,將全部數據加載到CPU的緩存當中去,提升緩存命中率,提高效率。在列存儲與向量化執行引擎的雙重優化下,查詢執行的速度會有一個很是巨大的飛躍。

4) 關係模型與SQL查詢

ClickHouse是一個關係型數據庫。它幾乎能夠支持近百分之九十的sql做爲查詢語句,好比group by,order by等。

5) 多樣化的表引擎

ClickHouse和mysql同樣,也將存儲部分進行了抽象,把存儲引擎做爲一層獨立的接口。因此說Clickhouse實現了不少種表引擎,好比mergetree,log,memory等類型的引擎,每一種表引擎都有着各自的特色,用戶能夠根據實際業務場景的要求,選擇合適的表引擎使用。

6) 多線程與分佈式
ClickHouse幾乎具有現代化高性能數據庫的全部典型特徵,對於能夠提高性能的手段可謂是一一用盡,對於多線程和分佈式這類被普遍使用的技術,天然更是不在話下。

7) 多主架構

HDFS、Spark、HBase和Elasticsearch這類分佈式系統,都採用了Master-Slave主從架構,由一個管控節點做爲Leader統籌全局。而ClickHouse則因爲它的集羣架構和其餘數據庫不一樣,這種架構使得它是一個多主架構。

8) 在線查詢

ClickHouse採用了LSM樹結構,因此使得Clickhouse的插入量能夠很大。同時,Clickhouse的內部優化,使得在複雜查詢的場景下,它也可以作到極快響應,且無須對數據進行任何預處理加工。達到了實時數倉的效果

9) 數據分片與分佈式查詢

Clickhouse擁有分佈式能力,天然支持數據分片,數據分片是將數據進行橫向切分,這是一種在面對海量數據的場景下,解決存儲和查詢瓶頸的有效手段。ClickHouse並不像其餘分佈式系統那樣,擁有高度自動化的分片功能。ClickHouse提供了本地表 ( Local Table ) 與分佈式表 ( Distributed Table ) 的概念。一張本地表等同於一份數據的分片。而分佈式表自己不存儲任何數據,它是本地表的訪問代理,其做用相似分庫中間件。藉助分佈式表,可以代理訪問多個數據分片,從而實現分佈式查詢。

二、C****lickhouse常見應用場景

  • 電信行業用於存儲數據和統計數據使用;
  • 新浪微博用於用戶行爲數據記錄和分析工做;
  • 用於廣告網絡和RTB,電子商務的用戶行爲分析;
  • 日誌分析;
  • 檢測和遙感信息的挖掘;
  • 商業智能;
  • 網絡遊戲以及物聯網的數據處理和價值數據分析;
  • 最大的應用來自於Yandex的統計分析服務Yandex.Metri ca。

Clickhouse架構及性能

Clickhouse的集羣架構是和其餘的數據集羣有必定的區別,他的集羣能力是表級別的,而咱們熟知的大數據體系,好比hadoop系列的集羣都是服務級別的。例如,一個hdfs集羣,全部文件都會切片、備份;而Clickhouse集羣中,建表時也能夠本身決定用不用,也就是說其實Clickhouse單節點就能存活。可能有其餘的大數據經驗的人對這種設計會有點奇怪,後面會從單機架構到集羣架構,詳細的去介紹。

=======================================================================================================================================================================================================

一、Clickhouse單機架構設計

官方介紹Clickhouse架構的資料比較匱乏,依據已有的經驗結合外部資料,根據本身的理解還原Clickhouse的架構以下:


圖3-1 clickhouse單機架構圖

1)Parser與Interpreter

Parser和Interpreter是很是重要的兩組接口:Parser分析器是將sql語句已遞歸的方式造成AST語法樹的形式,而且不一樣類型的sql都會調用不一樣的parse實現類。而Interpreter解釋器則負責解釋AST,並進一步建立查詢的執行管道。Interpreter解釋器的做用就像Service服務層同樣,起到串聯整個查詢過程的做用,它會根據解釋器的類型,聚合它所須要的資源。首先它會解析AST對象;而後執行"業務邏輯" ( 例如分支判斷、設置參數、調用接口等 );最終返回IBlock對象,以線程的形式創建起一個查詢執行管道。

2)表引擎

表引擎是ClickHouse的一個顯著特性,上文也有提到,clickhouse有不少種表引擎。不一樣的表引擎由不一樣的子類實現。表引擎是使用IStorage接口的,該接口定義了DDL ( 如ALTER、RENAME、OPTIMIZE和DROP等 ) 、read和write方法,它們分別負責數據的定義、查詢與寫入。

3)DataType

數據的序列化和反序列化工做由DataType負責。根據不一樣的數據類型,IDataType接口會有不一樣的實現類。DataType雖然會對數據進行正反序列化,可是它不會直接和內存或者磁盤作交互,而是轉交給Column和Filed處理。

4)Column與Field

Column和Field是ClickHouse數據最基礎的映射單元。做爲一款百分之百的列式存儲數據庫,ClickHouse按列存儲數據,內存中的一列數據由一個Column對象表示。Column對象分爲接口和實現兩個部分,在IColumn接口對象中,定義了對數據進行各類關係運算的方法,例如插入數據的insertRangeFrom和insertFrom方法、用於分頁的cut,以及用於過濾的filter方法等。而這些方法的具體實現對象則根據數據類型的不一樣,由相應的對象實現,例如ColumnString、ColumnArray和ColumnTuple等。在大多數場合,ClickHouse都會以整列的方式操做數據,但凡事也有例外。若是須要操做單個具體的數值 ( 也就是單列中的一行數據 ),則須要使用Field對象,Field對象表明一個單值。與Column對象的泛化設計思路不一樣,Field對象使用了聚合的設計模式。在Field對象內部聚合了Null、UInt6四、String和Array等13種數據類型及相應的處理邏輯。

5)Block

ClickHouse內部的數據操做是面向Block對象進行的,而且採用了流的形式。雖然Column和Filed組成了數據的基本映射單元,但對應到實際操做,它們還缺乏了一些必要的信息,好比數據的類型及列的名稱。因而ClickHouse設計了Block對象,Block對象能夠看做數據表的子集。Block對象的本質是由數據對象、數據類型和列名稱組成的三元組,即Column、DataType及列名稱字符串。Column提供了數據的讀取能力,而DataType知道如何正反序列化,因此Block在這些對象的基礎之上實現了進一步的抽象和封裝,從而簡化了整個使用的過程,僅經過Block對象就能完成一系列的數據操做。在具體的實現過程當中,Block並無直接聚合Column和DataType對象,而是經過ColumnWith TypeAndName對象進行間接引用。

二、Clickhouse集羣架構設計

Clickhouse是集羣是經過配置clickhouse_remote_servers來管理集羣的。在配置中,能夠配置集羣名字,集羣所須要節點的信息,經過這些節點能夠配置分片和副本機制。

簡單的配置爲例:

<yandex>
 <clickhouse_remote_servers>
 <cluster1>
 <shard>
 <internal_replication>true</internal_replication>
 <replica>
 <host>clickhouse-node1</host>
 <port>9000</port>
 </replica>
 <replica>
 <host>clickhouse-node2</host>
 <port>9001</port>
 </replica>
 </shard>
 <shard>
 <internal_replication>true</internal_replication>
 <replica>
 <host>clickhouse-node3</host>
 <port>9000</port>
 </replica>
 <replica>
 <host>clickhouse-node4</host>
 <port>9001</port>
 </replica>
 </shard>
 ...
 </cluster1>
 ...
 </clickhouse_remote_servers>
 ...
</yandex>

以上集羣配置完以後,想要用到Clickhouse的集羣能力,還須要使用Replicated_MergeTree+Distributed引擎,該引擎是"本地表 + 分佈式表"的方式,所以能夠實現多分片多副本;下面具體介紹下Replicated_MergeTree引擎和Distributed引擎。

1)Replicated*MergeTree引擎

首先須要介紹下MergeTree引擎,這也是Clickhouse存儲數據的最核心引擎,以前所說的特色主要就是針對該引擎所描述的。MergeTree引擎則是在MergeTree基礎上中擴展了一些功能引擎,包括支持ReplacingMergeTree,SummingMergeTree等等MergeTree家族引擎,詳細瞭解可看官網mergetree引擎介紹,不帶replication的MergeTree引擎均可以當作單機引擎,也就是說它們是在單節點上存在的。

而使用Replicated_MergeTree就是將MergeTree引擎的數據經過Zookeeper調節,達到副本的效果。好比上述配置中,咱們首先能夠在cluster1中的每一個節點上建立Replicated_MergeTr ee表,經過配置文件,能夠看到Clickhouse-node1和Clickho use-node2是在同一個shard裏的,每一個shard標籤裏的replica就表明複製節點。這時咱們建立表時將兩個副本指定在同一個zo okeeper目錄下,那麼寫入到node1的數據會複製到node2,寫入node2的數據會同步到node1,達到預計的複製效果。

到這裏,每一個節點上的本地表已經完成,可是多個分片的數據如何進行彙總,則須要下面的Distributed引擎。

**2)**Distributed引擎

使用Distributed引擎的表自己不存儲任何數據,但容許在多個服務器上進行分佈式查詢處理,讀取是自動並行的。在讀取期間,會使用遠程服務器上的表索引(也就是咱們上述使用的Replicate d*MergeTree引擎)。

在讀寫數據時,若是使用Distributed表,能夠按照配置文件配置的分片方案,從不一樣分片(shard)中讀寫數據,作到數據分片的效果。好比咱們讀取數據時,是經過Distributed引擎表讀取,這個時候它會讀取集羣中的每一個分片的數據作彙總計算。注意,這一塊會有深度分頁的狀況,有些sql能夠先分散在每一個節點上執行完再在查詢節點作結果聚合,而有些則沒法作結果聚合,必須將全部數據同步到查詢節點,由查詢節點統一彙總,這種狀況就須要根據具體的數據狀況進行優化。


圖3-2 本地表加分佈式表的查詢流程圖

圖3-2是一個2分片2副本的架構,使用的是Replicated*Merge Tree + Distributed引擎模式。紅色的數字表明節點的話,也就是節點1和2互爲副本,3和4互爲副本。

圖中events爲Distributed引擎表,也叫分佈式表;events_loc al爲Replicated*MergeTree引擎表,也叫本地表。該圖中,分佈式表只在節點3中建立,線上環境通常會在每一個節點上都建立一個分佈式表(不會消耗資源,由於分佈式表不會存儲數據)。

執行查詢時,會訪問一個節點的分佈式表,該圖中訪問的是節點3中分佈式表。而後分佈式表會分別的讀取2個分片的數據,在這裏,它讀取了節點3和節點2的本地表數據,這兩個節點加在一塊就是完整的數據。彙總查詢後將結果(Result Set)返回。

三、Clickhouse性能

**1)插入:**單機100-150M/s的插入速度;

**2)查詢:**單字段groupby沒有索引,1億數據查詢須要2.324s。有索引下,查詢時間爲0.101秒。能夠看到Clickhouse的查詢速度是及其快的,市面上常見的數據庫基本都達不到這種性能;

**3)其餘:**併發,官網默認配置爲100。因爲是大數據分析數據庫主要適用於olap場景,對併發支持略差多個大數據查詢可能會直接將cpu等資源佔滿,故併發實際達不到100。

Clickhouse在好將來的實踐


圖4-1 clickhouse線上架構圖

一、業務場景

目前在好將來除了咱們部門,在其餘部門也已經有了多個業務方。

1) 本部門

使用平臺:日誌中心,貓頭鷹,土撥鼠,grafana等。

使用方式:咱們將須要的數據經過flink,spark,gohangout等工具消費kakfa,寫入clickhouse,而後經過clickhouse作聚合查詢,將數據展現出來。

好比,土撥鼠主要是經過網關數據作的聚合,能夠看到各個域名,url或者服務器的調用次數,請求耗時等狀況。再好比直播數據則是消費直播上報日誌,用grafana將數據展現出來。

2) 其餘部門

除了在本部門,還有其餘業務方,數據研發部,數據中臺等也都在使用,數據研發部主要會將hive中的熱點數據經過spark/dataX同步至Clickhouse。而後將數據經過天樞天璇等平臺展現給分析師使用,提升了查詢速度。


圖4-2:clickhouse使用圖

二、存儲現狀


圖4-3 單節點數據存儲狀況

以上數據第一列爲庫名,第二列爲行數,第三列爲壓縮前大小,第四列爲壓縮後大小。

能夠看到單個節點已有多個達到TB級別和百億級別行數的數據庫。目前數據節點是6個,也就是說在集羣中,數據量須要再乘以6,表明有個別庫庫行數已達到千億行,容量達到百T級別。

建設與規劃

一、監控

Clickhouse官方目前沒有提供直接的監控界面,可是所須要的監控數據在system庫中都會記錄下來,網上已有人經過grafana展現出來,目前的監控圖如圖5-1所示。

圖5-1 clickhouse監控圖

除此以外,還寫了腳本,按期的對每一個節點的探活及故障重啓。同時也使用神樹平臺查看各個節點的硬件信息及告警。

二、遇到的問題

Clickhouse做爲olap數據庫,在使用過程當中或多或少會出現一些問題,例如版本bug,使用不規範,混部出現的問題等,如今主要介紹幾個須要持續優化或者業務配合的問題。其餘遇到的一些問題也會在wiki上持續更新:

1) 大量查詢致使服務器負載高狀況,影響業務查詢

**分析:**多個複雜查詢,而且命中數據量極大的狀況下。每一個查詢都會佔用大量的cpu和內存。會致使服務器負載被打滿的狀況。尤爲是內存被打滿,會形成節點掛掉的現象。
解決:

  • 用戶限制,避免內存被打滿,能夠配置max_memory_us age_ for_all_queries,使其低於服務器實際內存。而且還能夠限制用戶的併發,每次查詢的數據量等;
  • 某些業務下沒法限制查詢數據量,能夠添加緩存機制,避免大量大數據查詢。

2) ddl語句卡死

分析:Clickhouse主要支持的是追加及查詢,可是使用mergetr ee引擎的表,是能夠作update和delete的。更新和刪除操做是用alter table語句的,也就是說其實這是須要ddl的權限的。每一次這種操做,數據庫都會發生加鎖,更新表等操做,而且數據量大的狀況下,作更新操做,整個數據都會根據索引狀況從新排序,這是一個漫長的過程。Clickhouse的ddl語句底層應該是個隊列,一個沒執行完,也會致使其餘ddl卡住。

**解決:**儘可能減小ddl語句的執行頻率以及增長執行間隔,或者儘可能不要執行。

3) zookeeper失聯

**分析:**Clickhouse集羣方案很依賴zk,副本同步機制都是依賴zk的,致使每次插入數據都會和zk作交互,而且在zk中作寫操做,插入併發高的狀況下,可能會致使zk暫時失聯。

**解決:**以前zookeeper是和Clickhouse混部,後期作了拆分,狀況有一部分好轉。可是目前依然會偶爾出現問題,後續會繼續對這塊優化,zookeeper的服務器性能也會去儘可能完善,申請高配服務器,提升zookeeper的性能,使得不會由於zookeeper性能而影響到Clickhouse。

三、將來規劃

想要打造一個高性能高穩定的大數據場景數據庫,須要的是持續不斷地學習以及和業務方的配合。

  • 深刻了解業務,根據業務場景建表;
  • 持續學習clickhouse,根據clickhouse特性優化sql;
  • 同時也須要業務方配合,若是大查詢頻率較高,能夠考慮使用緩存等機制,或者特定場景可使用近似計算。同時特殊場景特殊對待,實現合適的sql;
  • 數據持續增加,查詢壓力也是愈來愈大,進行集羣之間的隔離,使其重要業務之間不會互相影響;
  • 持續完善監控和告警機制;
  • clickhouse還有不少強大的功能,將來也會去嘗試使用。

參考文獻

[1]https://clickhouse.tech/docs
[2]https://blog.csdn.net/tzs_104...
[3]https://www.jianshu.com/p/ab8..

相關文章
相關標籤/搜索