Clickhouse副本與分片
一 副本與分片概述
副本(replica) 是指兩個相同資料的表或表一部分,作用是為了資料備份與安全
分片(shard) 是指不同的伺服器儲存同一張表的不同部分,作用是為了水平切分表,緩解單一服務的壓力.
針對於副本的需求,有兩種不同的方式,後面會一一概述.
二 下載並安裝zookeeper
clickhouse要實現副本與分片需要依賴於zookeeper,並且zookeeper版本要3.4.5以及以上.
ZK的下載與安裝參考我另外一篇博文Zookeeper的下載與安裝
三 ClickHouse配置zookeeper
安裝啟動好zookeeper後,我們需要在clickhouse中配置zookeeper
clickhouse兩種配置zookeeper方式,一種是直接在config.xml中配置,另外一種是在外部檔案中配置好了,在config.xml中進行引用.
1 內部配置方式:
vim /etc/clickhouse-server/config.xml
新增如下配置:
<zookeeper>
<node index="1"> #index是連線zk的順序
<host>node01</host> #znode地址
<port>2181</port> #znode埠
</node>
<node index="2">
<host>node02</host>
<port>2181</port>
</node>
<node index="3">
<host>node03</host>
<port>2181</port>
</node>
2 外部配置方式:
建立外部配置檔案:
vim /etc/clickhouse-server/config.d/zks.xml
<?xml version="1.0"?>
<yandex>
<zks>
<node index="1">
<host>node01</host>
<port>2181</port>
</node>
<node index="2">
<host>node02</host>
<port>2181</port>
</node>
<node index="3">
<host>node03</host>
<port>2181</port>
</node>
</zks>
</yandex>
引入外部配置檔案中的配置
vim /etc/clickhouse-server/config.xml
#檔案的路徑
<include_from>/etc/clickhouseserver/config.d/zks.xml</include_from>
#incl中指的是配置在外部配置檔案中的標籤
<zookeeper incl="zks" optional="true" />
上方是麻煩的寫法,如果在zks中的標籤<zks>...</zks>
改為<zookeeper>..</zookeeper>
,那麼可以不要config.xml中的<zookeeper incl...>
標籤,只需要引用外部配置檔案即可.
zk的配置不支援熱更改,必須要重啟clickhouse服務,但是在重啟之前可以先使用以下sql查詢:
select * from system.zookeeper where path = '/';
會報表不存在.
重啟服務後,再還執行上方sql,就可以查詢到zookeeper表,說明zookeeper配置好了.
4 副本實現方式
1 複製合併樹引擎實現副本
當前直接支援副本的引擎之後Replicatedxxx複製合併樹引擎,對於複製合併樹引擎實現副本我已經寫過了,所以這裡只上鍊接
ClickHouse ReplicatedMergeTree家族引擎
2 通過分片配置實現副本
首先要配置cluster.
vim /etc/clickhouse-server/config.xml
在vim模式下輸入:/remote_servers
快速查詢到配置cluster的標籤
在<remote_servers>標籤之中就是我們配置shard與replica的地方
先看下面配置,說明
<remote_servers incl="clickhouse_remote_servers" >
<my_shard>
<shard>
<replica>
<host>node01</host>
<port>9000</port>
</replica>
<replica>
<host>node02</host>
<port>9000</port>
</replica>
</shard>
<shard>
<replica>
<host>node03</host>
<port>9000</port>
</replica>
<replica>
<host>node04</host>
<port>9000</port>
</replica>
</shard>
</my_shard>
</remote_servers>
</my_shard>
是cluster名稱,任意填寫,在後面通過這個名字引用如 on cluster my_shard
<shard>
指分片,有幾個分片就配置幾個<shard>
標籤
<replica>
指副本,有幾個副本就有幾個<replica>
標籤.
上方的配置是有兩個分片,每個分片兩個副本.這裡理解也可以是有兩個分片,每個分片一個副本.
打個比方說,一張test表基於以上配置,共有id 1,2,3,4 四條資料,那麼node01中有1,2兩條,node02中有1,2兩條,node03中有3,4兩條,node04中有3,4兩條,這樣子舉例比較好理解.,至於到底是兩個分片兩個副本,還是兩個分片一個副本,隨意,但是本文會說是兩個副本.
因為這裡我們是演示副本的實現,所以就不考慮分片了,分片後面說,所以現在只建立一個分片,分片中有三個副本.
每臺伺服器中都增加以下配置,host換成自己的ip
<remote_servers incl="clickhouse_remote_servers" >
<my_shard>
<shard>
<replica>
<host>node01</host>
<port>9000</port>
<!-- 預設為default
<user></user>
預設為空
<password></password> -->
</replica>
<replica>
<host>node02</host>
<port>9000</port>
</replica>
<replica>
<host>node03</host>
<port>9000</port>
</replica>
</shard>
</my_shard>
</remote_servers>
上面配置好了以後,cluster可以熱載入,所以不需要重啟服務,通過系統表可以檢視cluster
select * from system.clusters where cluster='my_shard';
接下來的任務,需要藉助於分散式表來完成,但是介紹分散式表之前,先說一下分散式ddl
分散式ddl指的是在一臺伺服器上執行sql,其他伺服器同步執行,需要藉助於cluster,如下方
create table tableName on cluster my_shard (id Int8,name String)engine=xxx ;
上面建立的一張表,除了on cluster my_shard
以外就是正常的建立表語句,my_shard我們上面配置過,裡面一共包含了node01,node02,node03 三個replica,那麼在執行的時候,就會到my_shard配置下的所有伺服器中執行create table
語句.也就是這三臺伺服器任意一臺執行以上sql,三臺的表都會建立好,這就是分散式ddl,分散式ddl也需要zookeeper的支援,同樣也支援drop table…
瞭解了分散式ddl,我們可以在任意一臺機器上建立表:
create table default.replicaTest on cluster my_shard(id Int8,name String) engine =MergeTree order by id;
此時發現my_shard配置的node01,node02,node03上面都建立好了replicaTest表.表建立好了以後,接下來要建立分散式表,分散式表本身不儲存任何資料,可以把它當成資料操作的工具,他會分發到被分散式表代理的其他表.
Distributed(cluster_name, db_name, table_name[, sharding_key[, policy_name]])
第一個是配置的cluster名稱,第二個第三個分別代表代理的資料庫,資料表,第四個引數是資料插入分發策略,指定一個欄位名(必須是Int型別)或者rand(),第五個引數是策略名稱.
下面基於上面的replicaTest建立一個分散式表:
create table replicaTest_all as replicaTest
engine = Distributed(my_shard,default,replicaTest,id);
我在node01機器上建立了一張分散式表(當然也可以通過分散式ddl,每臺機器上都建立一張分散式表)
建立好了,我們插入資料:
insert into replicaTest_all values(1,'zhang');
插入成功後,每臺機器查詢replicaTest表資料,返現三臺機器上都有1,zhang
這條資料.而查詢replicaTest_all分散式表,也只查詢到了1,zhang
一條資料.
插入分散式表時,基於my_shard的配置,會把插入的資料全部分發到代理的每一臺伺服器的replicaTest表,這也就是為什麼我們插入replicaTest_all結果三臺機器都有這條資料的原因.而查詢時,會從副本中選擇一個查詢(查詢有策略可以選擇,感興趣可以查詢load_balancing
).針對於insert與select會作用於本地表,其他的操作基本都只會作用於分散式表.
通過分散式表的方式完成副本的實現,總結一下,1 配置檔案配置cluster 2 cluster中配置的伺服器上建立表 3 通過分散式表代理本地表,實現資料插入後分發到本地表.
這種資料副本的實現可以是任何引擎,但是對於某臺Clickhouse的壓力比較大,而第一種的副本實現必須是Repicated*合併樹引擎,壓力稍小於分散式表的方式.
通過分散式表的方式實現資料副本時,寫入我們配置的分散式表時,分散式表會往shard下的所有replica都寫入一份資料.如果我們這裡的replicaTest表改成ReplicatedMergeTree
引擎,那麼我們就只需要分散式表選擇一個replica寫入即可,由ReplicatedMergeTree完成資料同步,而不需要每個replica都要寫入,這項配置需要新增 <internal_replication>true<internal_replication>
<my_shard>
<shard>
<internal_replication>true</internal_replication>
......
</shard>
</my_shard>
五 分片
上面我們只使用了一個分片,接下來說一下分片
<remote_servers incl="clickhouse_remote_servers" >
<my_shard_2>
<shard>
<replica>
<host>node01</host>
<port>9000</port>
</replica>
</shard>
<shard>
<replica>
<host>node02</host>
<port>9000</port>
</replica>
</shard>
<shard>
<replica>
<host>node03</host>
<port>9000</port>
</replica>
</shard>
</my_shard_2>
</remote_servers>
我們每臺伺服器新增以上配置,此時沒有使用副本,只是三個分片.
查詢分片:
配置好後,通過分散式ddl先建立表
create table replicaTest2 on cluster my_shard_2 (id Int,name String)
engine=MergeTree order by id;
建立分散式表:
create table replicaTest2_all as replicaTest2
engine =Distributed(my_shard_2,default,replicaTest2,rand());
插入資料
insert into replicaTest2_all values(1,'zhang'),(2,'li'),(3,'zhao'),
(4,'qian'),(5,'sun'),(6,'wang'),(7,'tian'),(8,'he'),(9,'zheng'),(10,'dong');
檢視資料:
node01:
node01.hadoop.com :) select * from replicaTest2;
┌─id─┬─name─┐
│ 4 │ qian │
│ 10 │ dong │
└────┴──────┘
node02:
node02.hadoop.com :) select * from replicaTest2;
┌─id─┬─name──┐
│ 1 │ zhang │
│ 2 │ li │
│ 3 │ zhao │
│ 5 │ sun │
│ 9 │ zheng │
└────┴───────┘
node03:
node03.hadoop.com :) select * from replicaTest2;
┌─id─┬─name─┐
│ 6 │ wang │
│ 7 │ tian │
│ 8 │ he │
└────┴──────┘
由此可見資料被replicaTest2_all分散式表隨機分發到了三個分片中.
分發有策略,需要做配置<weight>
<shard>
<weight>2</weight>
<replica>
<host>node01</host>
<port>9000</port>
</replica>
</shard>
weight
預設為1
,既node01 node02 node03 都為1,那麼總的權重為3,每個分片通過分散式表第四個引數sharding_key
分配到資料的概率是一樣.
如果我們權重分別設定為1,2,3 那麼總權重是6,那麼總區間就是[0,6),排在shard配置第一位的node01,權重佔比為1/6,所以屬於區間[0,1),排在shard配置第二位的node02,佔比2/6,所以區間為[1,3),至於最後的node03就是[3,6).所以如果rand()產生的數字除以6取餘落在哪個區間,資料就會分發到哪個shard,通過權重配置,可以實現資料按照想要的比重分配.
六 副本與分片
上面分別講述了副本與分片的實現,其實最合適的方法就是利用分散式表實現分片資料的寫入,而每一分片內通過Replicated*引擎實現副本資料的同步,下面實現這個:
三臺伺服器配置my_shard_3
<my_shard_3>
<shard>
<internal_replication>true</internal_replication>
<weight>1</weight>
<replica>
<host>node01</host>
<port>9000</port>
</replica>
</shard>
<shard>
<internal_replication>true</internal_replication>
<weight>1</weight>
<replica>
<host>node02</host>
<port>9000</port>
</replica>
<replica>
<host>node03</host>
<port>9000</port>
</replica>
</shard>
</my_shard_3>
此時有兩個shard 第二shard有兩個副本.(因為本人只有三臺伺服器,故這樣分配)
利用分散式ddl建立ReplicatedMergeTree表
CREATE TABLE default.replicaTest3 on cluster my_shard_3
( `id` Int32,`name` String)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard_name}/replicaTest3', '{replica_name}')
ORDER BY id
上方的建立表以及巨集變數在上方貼的ClickHouse ReplicatedMergeTree家族引擎
連結中已經講過了,這裡不再贅述,下面是我的配置的巨集變數:
node01:
node01.hadoop.com :) select * from system.macros;
┌─macro────────┬─substitution─┐
│ replica_name │ 01 │
│ shard_name │ 01 │
└──────────────┴──────────────┘
node02:
node02.hadoop.com :) select * from system.macros;
┌─macro────────┬─substitution─┐
│ replica_name │ 01 │
│ shard_name │ 02 │
└──────────────┴──────────────┘
node03
node03.hadoop.com :) select * from system.macros;
┌─macro────────┬─substitution─┐
│ replica_name │ 02 │
│ shard_name │ 02 │
└──────────────┴──────────────┘
建立好本地表後,建立分散式表:
CREATE TABLE default.replicaTest3_all
( `id` Int32, `name` String)
ENGINE = Distributed('my_shard_3', 'default', 'replicaTest3', id)
插入資料:
insert into replicaTest3_all values(1,'zhangfei'),(2,'guanyu'),(3,'liubie'),(4,'zhaoyun'),
(5,'machao'),(6,'caocao'),(7,'lvbu'),(8,'zhuge'),(9,'dianwei');
檢視資料:
node01:
┌─id─┬─name────┐
│ 2 │ guanyu │
│ 4 │ zhaoyun │
│ 6 │ caocao │
│ 8 │ zhuge │
└────┴─────────┘
node02和node03
┌─id─┬─name─────┐
│ 1 │ zhangfei │
│ 3 │ liubie │
│ 5 │ machao │
│ 7 │ lvbu │
│ 9 │ dianwei │
└────┴──────────┘
至此,最適合生產的分片與副本機制就配置好了.
相關文章
- ClickHouse學習系列之四【副本&分片部署說明】
- ClickHouse資料副本引擎
- 高可用mongodb叢集(分片+副本)MongoDB
- Mongodb分散式叢集副本集+分片MongoDB分散式
- linux下Mongodb叢集搭建:分片+副本集LinuxMongoDB
- Elasticsearch 7.x 之節點、叢集、分片及副本Elasticsearch
- 【最佳實踐】高可用mongodb叢集(1分片+3副本):規劃及部署MongoDB
- ClickHouse與Elasticsearch壓測實踐Elasticsearch
- ClickHouse與威脅日誌分析
- MongoDB 分片鍵的選擇與案例MongoDB
- ClickHouse與ES的優劣對比
- 初識ClickHouse——安裝與入門
- mongodb 分片叢集建立分片集合MongoDB
- [Clickhouse] Clickhouse 報SQLException : Read timed outSQLException
- ClickHouse(04)如何搭建ClickHouse叢集
- UDP分片和丟包與TCP效果對比UDPTCP
- MongoDB副本集MongoDB
- ClickHouse(01)什麼是ClickHouse,ClickHouse適用於什麼場景
- 使用 NineData GUI 建立與修改 ClickHouse 表結構GUI
- [clickhouse] Clickhouse之開窗函式篇函式
- MongoDB副本集replica set (二)--副本集環境搭建MongoDB
- Install clickhouse
- 【clickhouse專欄】clickhouse效能為何如此卓越
- ClickHouse(03)ClickHouse怎麼安裝和部署
- Clickhouse Engine kafka 將kafka資料同步clickhouseKafka
- 從 MySQL 到 ClickHouse 實時複製與實現MySql
- springboot liquibase整合mysql與clickhouse多資料來源Spring BootUIMySql
- Python使用ClickHouse的實踐與踩坑記錄Python
- 副本集部署
- 副本集要點
- 副本集選舉
- 搭建MongoDB副本集MongoDB
- mongdb副本集搭建
- MongoDB 副本集搭建MongoDB
- mongo副本集搭建Go
- MongoDB部署副本集MongoDB
- MongoDB 副本集管理MongoDB
- Nginx分片限流Nginx