ClickHouse目錄下多為測試版更新,更新速度快;clickhouse-altinity-stable目錄為穩(wěn)定版發(fā)布目錄。
(2)部署包說明
ClickHouse安裝部署需要四個安裝包:
clickhouse-client.rpm
clickhouse-common-static.rpm
clickhouse-server.rpm
clickhouse-server-common4.rpm
(3)部署方式
下載安裝包時要對應版本下載四個安裝包,將四個安裝包拷貝到統(tǒng)一目錄下,執(zhí)行rpm -ivh * 即可完成安裝。
安裝完成后的主要目錄以及文件說明:
/etc/clickhouse-server:配置文件目錄,包括:config.xml和users.xml
/etc/clickhouse-client:客戶端配置文件目錄
/var/lib/clickhouse:默認數(shù)據(jù)目錄
/var/log/clickhouse-server:默認日志目錄
/etc/init.d/clickhouse-server:啟動shell腳本
/etc/security/limits.d/clickhouse.conf:最大文件打開數(shù)的配置
/etc/cron.d/clickhouse-server:定時任務配置,默認沒有任務
/usr/bin/clickhouse-client:clickhouse客戶端
如上圖,是我們的線上服務器情況,ClickHouse查詢使用并行處理機制,對CPU和內(nèi)存的要求還是比較高的。不建議單臺機器上部署多個節(jié)點,同時也要求ClickHouse節(jié)點與集群中ZooKeeper節(jié)點分開。防止高負載下相互影響。
由于當時使用的ClickHouse版本不支持多數(shù)據(jù)盤,所以選擇一個合適的Raid方式也是很多人關(guān)心的問題,這里我們直接建議Raid5,注意配置熱備盤,這樣無論從磁盤IO,數(shù)據(jù)可靠性,數(shù)據(jù)恢復,及運維復雜度來說都提供了很好的保障。這里也給出了Raid5情況下的磁盤恢復的影響,供大家參考。
此外, 19.15 版本開始,ClickHouse 開始實現(xiàn)多卷存儲的功能。它具有多種用途,其中最重要的用途是將熱數(shù)據(jù)和冷數(shù)據(jù)存儲在不同類型的存儲中。這種配置被稱為分層存儲,如何很好的利用多卷存儲能力,實現(xiàn)結(jié)合業(yè)務實現(xiàn)分層存儲,也期待大家能分享自己的經(jīng)驗。
圖1 分布式集群示例
圖2 分片和副本關(guān)系示例
如【圖1、圖2】,ClickHouse分布式集群有4個節(jié)點,2個Shard,副本數(shù)為2。其中節(jié)點example1,example2屬于同一Shard,互為副本,他們的數(shù)據(jù)一致。example3,example4屬于同一Shard。查詢時,分布從2個Shard中隨機取一個節(jié)點進行訪問。其中任何單節(jié)點異常時,寫入和查詢都能保障數(shù)據(jù)完整性,高可用,業(yè)務無感知。
ClickHouse的分布式也是一個有意思的設計方式,多個節(jié)點部署完成后,節(jié)點與節(jié)點之間并沒有聯(lián)系。通過ClickHouse集群的配置文件來實現(xiàn),即節(jié)點與節(jié)點之間通過配置文件來形成成集群,配置中包含集群的節(jié)點信息,復制節(jié)點,分片節(jié)點,同構(gòu)成一個Cluster。
這樣就形成了一個有意思的現(xiàn)象。我們可以抽象為:“集群定義節(jié)點,和節(jié)點關(guān)系,節(jié)點不知道集群”。這樣一個引用關(guān)系,表現(xiàn)為ClickHouse的分布式在使用上就很靈活。
舉個例子,一個集群里有30節(jié)點,我可以挑選其中2個配置整個集群的分布式關(guān)系,這樣你會發(fā)現(xiàn)每個節(jié)點都是獨立的,并不知道整個集群的全貌,集群的調(diào)整我只要關(guān)注2個節(jié)點的配置就行。包括基于之上的,數(shù)據(jù)安全,外部訪問控制等等。
如上,從高可用的角度,我們默認都是采用分布式集群方式,數(shù)據(jù)做分片,保證數(shù)據(jù)寫入不中斷。數(shù)據(jù)副本提供可靠性,同時提升并發(fā)查詢能力。
有四個節(jié)點,example1、example2、example3、example4,可以在config.xml中配置,配置文件中搜索remote_servers,在remote_servers內(nèi)即可配置字集群,也可以提出來配置到擴展文件中。incl屬性表示可從外部文件中獲取節(jié)點名為clickhouse_remote_servers的配置內(nèi)容。
通常,我們采用擴展文件的方式來配置集群,首先,在config.xml文件中添加外部擴展配置文件metrika.xml的配置信息,在config.xml文件中加入以下內(nèi)容允許使用擴展文件metrika.xml來配置信息。
<!-- 依賴外部metrika.xm依賴外部metrika.xml --><include_from>/etc/clickhouse-server/metrika.xml</include_from>
然后,在/etc/clickhouse-server下新建metrika.xml文件,并且插入以下內(nèi)容。
說明:
我們這里以有副本模式的數(shù)據(jù)寫入為例,首先在每一個節(jié)點創(chuàng)建本地表,可以到每個實例上運行一次建表語句。
(1) 創(chuàng)建本地表
此時,將internal_replication設置為true,這種配置下,寫入不需要通過分布式表,而是將數(shù)據(jù)直接寫入到每個Shard內(nèi)任意的一個本地表中,如圖所示。
(2)創(chuàng)建分布式表
我們只借助于分布式表提供分布式查詢能力,與數(shù)據(jù)寫入無關(guān),類似創(chuàng)建DB的View命令,所以這里只需要在提供查詢?nèi)肟诘臋C器上創(chuàng)建,并不一定在所有機器上創(chuàng)建。
(3)借助集群的指令
oncluster {cluster_name} 這個指令使得操作能在集群范圍內(nèi)的節(jié)點上都生效。這里使用類似create table xxx oncluster [cluster_name](xxx) ENGINE = ReplicatedMergeTree()。
在任意一個節(jié)點上運行,ClickHouse會根據(jù)集群里面配置的分片信息在每一個節(jié)點上將表格創(chuàng)建好。有些日常批量維護的命令可以通過類似方式執(zhí)行。
如果需要通過此方式進行維護,需要注意維護一個專門用戶發(fā)送集群指令的節(jié)點列表。
實際生產(chǎn)運維中,我們并不推薦集群指令的方式,建議通過運維的方式,從管理規(guī)范上,準備日常維護的批量腳本,配置文件的分發(fā)和命令的執(zhí)行,從操作機上,使用腳本批量遠程登陸執(zhí)行。
禁止分布式寫入,采用本地表寫入。
社區(qū)很多伙伴在分享時,也都提到了禁止使用分布式表寫入,我們也一樣。
禁止使用的原因是需要設計及減少Part的生成頻率,這對整個集群的穩(wěn)定性和整體性能有著決定的作用,這個在之前我司的分享中曾經(jīng)介紹過,我們控制批次的上線和批次的時間窗口,保障寫入操作對每個節(jié)點的穩(wěn)定壓力。
這里也分享下我們在做評估寫入穩(wěn)定性測試的結(jié)果,作為大家可借鑒的評估思路,其本質(zhì)是平衡好合并速度和Part數(shù)量的關(guān)系,一定是需要相對均衡的。
(1)寫本地表
數(shù)據(jù)寫入時,可以由客戶端控制數(shù)據(jù)分布,直接寫入集群中ClickHouse實例的本地表,也可以通過LB組件(如LVS,Nginx)進行控制。
(2)寫分布式表
數(shù)據(jù)寫入時,先寫入集群中的分布式表下的節(jié)點臨時目錄,再由分布式表將Insert語句分發(fā)到集群各個節(jié)點上執(zhí)行,分布式表不存儲實際數(shù)據(jù)。
ClickHouse在分布式寫入時,會根據(jù)節(jié)點數(shù)量在接收請求的節(jié)點的下創(chuàng)建集群節(jié)點的臨時目錄,數(shù)據(jù)(Insert語句)會優(yōu)先提交的本地目錄下,之后同步數(shù)據(jù)到對應的節(jié)點。此過程好處是提交后,數(shù)據(jù)不會丟失。我們模擬同步過程中節(jié)點異常,重啟后數(shù)據(jù)也會自動恢復,如果你的數(shù)據(jù)量及集群壓力并不大,分布式也可以認為是一種簡單的實現(xiàn)方式。
(3)寫入副本同步
在集群配置中,Shard標簽里面配置的replica互為副本,將internal_replication設置成true,此時寫入同一個Shard內(nèi)的任意一個節(jié)點的本地表,ZooKeeper會自動異步的將數(shù)據(jù)同步到互為副本的另一個節(jié)點。
業(yè)務查詢?nèi)肟谝U喜樵兏呖捎?,需要提供負載均衡和路由的能力。一些大廠都會有自己的LB基礎設施。其實大家可以能夠觀察ClickHouse提供兩個網(wǎng)絡端口分別是:
HTTP默認8123;
TCP默認9000;
ClickHouse的JDBC客戶端是通過HTTP的方式與ClickHouse進行交互的,我們可以判斷場景的可以基于HTTP協(xié)議做負載均衡,路由的中間件是可以滿足需求的,這樣我們的選擇其實就有很多了?;趥鹘y(tǒng)運維常見中間件的如:LVS,Nginx,HAProxy都有相關(guān)的能力,這里我們選用了Nginx。
我們基于它實現(xiàn)2個目的:(1)負載均衡能力(2)采集請求響應日志。
大家可能奇怪第2個目的,ClickHouse本身有自己的查詢響應日志,為啥還要單獨采集。原因很簡單,我們把ClickHouse本身的日志定位為做具體問題,排查與分析的日志,日志分散在了集群內(nèi)部,并且分布式的查詢轉(zhuǎn)換為本地SQL后作為集群的系統(tǒng)行監(jiān)測,我們認為并不合適。我們通過Nginx日志分析線上業(yè)務的請求情況,并進行可視化展現(xiàn)包括業(yè)務使用情況,慢查詢,并發(fā)能力等等,如果確實有需要追溯的場景時候,才會使用到ClickHouse的自身日志。
同時我們發(fā)現(xiàn)社區(qū)目前也提供了CHProxy作為負載均衡和HTTP代理,從我們角度更愿意選擇一個簡單,熟悉的。
需要注意的是,我們只針對提供查詢?nèi)肟诘膶嵗渲梅植际奖?,然后通過Nginx進行代理。由Nginx將請求路由到代理的ClickHouse實例,這樣既將請求分攤開,又避免了單點故障,同時實現(xiàn)了負載均衡和高可用。并且我們在生產(chǎn)環(huán)境中也根據(jù)不同的業(yè)務配置路由入口,實現(xiàn)訪問的業(yè)務和負載隔離。
Nginx轉(zhuǎn)發(fā)后的節(jié)點(根據(jù)負載配置多個),使用Distribute表引擎作為集群的統(tǒng)一訪問入口,當客戶端查詢分布式表時,ClickHouse會將查詢分發(fā)到集群中各個節(jié)點上執(zhí)行,并將各個節(jié)點的返回結(jié)果在分布式表所在節(jié)點上進行匯聚,將匯聚結(jié)果作為最終結(jié)果返回給客戶端。
在我們的業(yè)務中,需要實現(xiàn)跨數(shù)據(jù)中心的分析,可以利用ClickHouse的靈活配置化分布式特性,將多數(shù)據(jù)中心的所有集群的分片都添加到一個ClickHouse實例中,并在該ClickHouse實例上創(chuàng)建分布式表,作為客戶端查詢的統(tǒng)一入口。如下圖所示。
當客戶端查詢該分布式表時,ClickHouse會將查詢分發(fā)到各個數(shù)據(jù)中心的所有分片上,并將各個分片的返回結(jié)果在分布式表所在配置的節(jié)點上進行匯聚,匯聚結(jié)果作為最終結(jié)果返回給客戶端,需要注意的是如果數(shù)據(jù)量巨大會給匯聚節(jié)點造成巨大的壓力,所以要平衡好數(shù)據(jù)量與服務器硬件資源之間的關(guān)系,才可以保證系統(tǒng)的穩(wěn)定性,從業(yè)務的安全來說,也只有對外的入口節(jié)點知道整個集群的信息。
在實際項目中,無論是寫入、查詢以及保證集群穩(wěn)定運行,需要配置一些參數(shù)來維護集群的狀態(tài),下屬表格中的參數(shù)是我們根據(jù)依據(jù)線上業(yè)務總結(jié)出來的最佳實踐參數(shù)。如果大家基于ClickHouse的生產(chǎn)使用,我們希望使用者理解其中每一個參數(shù)的含義,和配置的目的,社區(qū)的交流過程發(fā)現(xiàn)很多同行中經(jīng)常遇到一些問題,實際都可以從表格中得到答案。
請注意,其中很多參數(shù)配置是對集群的穩(wěn)定性有著決定性的作用。在理解的基礎上,大家才能結(jié)合自己的硬件和業(yè)務設置自己的最佳參數(shù)實踐。
ClickHouse集群監(jiān)控通常使用ClickHouse Exporter + Prometheus +Grafana方式, Exporter負責信息采集,時序數(shù)據(jù)庫Prometheus存儲相關(guān)日志,并用Grafana進行展現(xiàn), Grafana基于ClickHouse的監(jiān)控主題可以查詢社區(qū)貢獻的插件。
我們定義監(jiān)控有2個維度:
(1)集群信息監(jiān)控
這里主要是ClickHouse服務的指標,我們除了通過Exporter采集的數(shù)據(jù)進行展現(xiàn)外,大家可以選擇合適的Grafana的主題同時自己也可以擴展通過ClickHouse直接訪問系統(tǒng)的配置信息進行展示。
(2) 業(yè)務信息監(jiān)控
這里我更想介紹的是業(yè)務信息的監(jiān)控,詳情見【業(yè)務查詢】。我們通過Nginx額外收集所有訪問日志,這些日志我們也同樣存儲到了ClickHouse,基于這個我們進行了并發(fā)、響應時間、長尾查詢相關(guān)的統(tǒng)計分析。
同時也針對業(yè)務表,進行配置了相關(guān)統(tǒng)計任務,統(tǒng)計信息存儲與ClickHouse的統(tǒng)計表。
基于Grafana我們將這些業(yè)務信息進行了可視化展現(xiàn)。
這里主要是ClickHouse服務的指標,我們除了通過Exporter采集的數(shù)據(jù)進行展現(xiàn)外,大家可以選擇合適的Grafana的主題同時自己也可以擴展通過ClickHouse直接訪問系統(tǒng)的配置信息進行展示,如圖所示,為我們的一個監(jiān)控頁面,展示著集群的數(shù)據(jù)量變化以及其他業(yè)務信息。
? 版本升級
在數(shù)據(jù)模型版本兼容的情況下,可以使用如下方式升級版本
總體流程:
注意:
ClickHouse正常部署完成有三個配置文件,分別是:
config.xml (基本配置)
metrika.xml (集群配置)
users.xml (用戶以及限額相關(guān)配置)
卸載原版本后會將users.xml刪除,并且將config.xml重命名為config.rpmsave,所以users.xml要注意備份,可以先將users.xml重命名,這樣就不會被刪除。
升級過程:
(1)停止進程,查看已安裝的ClickHouse:rpm -qa | grep clickhouse
clickhouse-client-19.15.3.6-1.el7.x86_64
clickhouse-server-common-19.15.3.6-1.el7.x86_64
clickhouse-server-19.15.3.6-1.el7.x86_64
clickhouse-common-static-19.15.3.6-1.el7.x86_64
(2)卸載以上安裝包
注意按照順序卸載:
rpm -e clickhouse-client-19.15.3.6-1.el7.x86_64
rpm -e clickhouse-server-19.15.3.6-1.el7.x86_64
rpm -e clickhouse-common-static-19.15.3.6-1.el7.x86_64
rpm-e clickhouse-server-common-19.15.3.6-1.el7.x86_64
卸載完成后提示:
warning:/etc/clickhouse-server/config.xml saved as/etc/clickhouse-server/config.xml.rpmsave
此時/etc/clickhouse-server/下只剩兩個配置文件,并且config.xml被重命名為config.rpmsave,users.xml被刪除。(若users.xml有更改要,卸載前要注意備份)
(3)安裝新版本
rpm -ivh *
此時/etc/clickhouse-server/下重新生成了新的config.xml與users.xml
使用原來的config.xml替換新生成的config.xml
rm -rf config.xml
mv config.xml.rpmsaveconfig.xml
使用用原來的users.xml替換新生成的users.xml
rm -rf users.xml
mv users.xml.bakusers.xml
(4)啟動ClickHouse
serviceclickhouse-server start
MergeTree是ClickHouse中最強大的表引擎。在大量數(shù)據(jù)寫入時數(shù)據(jù),數(shù)據(jù)高效的以批次的形式寫入,寫入完成后在后臺會按照一定的規(guī)則就行數(shù)據(jù)合并,并且MergeTree引擎家族還有很多擴展引擎*MergeTree,注意,Merge引擎不屬于*MergeTree系列。
建表:
index_granularity—索引粒度。即索引中相鄰『標記』間的數(shù)據(jù)行數(shù)。默認值,8192。
index_granularity_bytes—索引粒度,以字節(jié)為單位,默認值: 10Mb。
enable_mixed_granularity_parts—啟用或禁用通過index_granularity_bytes控制索引粒度的大小。
use_minimalistic_part_header_in_zookeeper—數(shù)據(jù)片段頭在ZooKeeper中的存儲方式。如果設置了use_minimalistic_part_header_in_zookeeper=1 ,ZooKeeper會存儲更少的數(shù)據(jù)。
min_merge_bytes_to_use_direct_io—使用直接I/O來操作磁盤的合并操作時要求的最小數(shù)據(jù)量。
merge_with_ttl_timeout—TTL合并頻率的最小間隔時間。默認值: 86400 (1天)。
write_final_mark—啟用或禁用在數(shù)據(jù)片段尾部寫入最終索引標記。默認值:1(不建議更改)。
storage_policy—存儲策略。
該引擎和MergeTree的不同之處在于它會刪除具有相同主鍵的重復項。數(shù)據(jù)的去重只會在合并的過程中出現(xiàn)。合并會在未知的時間在后臺進行,所以你無法預先作出計劃。有一些數(shù)據(jù)可能仍未被處理。因此,ReplacingMergeTree適用于在后臺清除重復的數(shù)據(jù)以節(jié)省空間,但是它不保證沒有重復的數(shù)據(jù)出現(xiàn)。同時ReplacingMergeTree在一定程度上可以彌補ClickHouse不能對數(shù)據(jù)做更新的操作。
建表:
如果ver 列未指定,選擇最后一條。
如果ver 列已指定,選擇 ver 值最大的版本。
該引擎繼承自MergeTree。區(qū)別在于,當合并 SummingMergeTree 表的數(shù)據(jù)片段時,ClickHouse 會把所有具有相同主鍵的行合并為一行,該行包含了被合并的行中具有數(shù)值數(shù)據(jù)類型的列的匯總值。如果主鍵的組合方式使得單個鍵值對應于大量的行,則可以顯著的減少存儲空間并加快數(shù)據(jù)查詢的速度。
建表:
如果沒有指定 `columns`,ClickHouse 會把所有不在主鍵中的數(shù)值類型的列都進行匯總。
副本是表級別的,不是整個服務器級的。所以,服務器里可以同時有復制表和非復制表。副本不依賴分片。每個分片有它自己的獨立副本。要使用副本,需在配置文件中設置 ZooKeeper 集群的地址。需要 ZooKeeper 3.4.5 或更高版本。
例如:
以上引擎都是數(shù)據(jù)存儲引擎,但是該引擎-分布式引擎本身不存儲數(shù)據(jù),但可以在多個服務器上進行分布式查詢。讀是自動并行的。讀取時,遠程服務器表的索引會被使用。
建表:
分布式引擎參數(shù):服務器配置文件中的集群名,遠程數(shù)據(jù)庫名,遠程表名,數(shù)據(jù)分布策略。
致 謝
在ClickHouse的學習、評測、應用及對集群的維護過程中,得到了來自同行以及ClickHouse中文社區(qū),還有ClickHouse研發(fā)團隊的巨大幫助,尤其感謝新浪高鵬的幫助,為我們解決使用過程中的難題提供了思路,同時還為我們的集群架構(gòu)提出了很多非常有建設性的指導建議。
【本文作者:鄒立民 趙群 】