三條服務器,每台服務器安裝兩個clickhouse實例
一、服務器規划
單機兩個clickhouse實例安裝,參考Clickhouse 單機雙實例
zookeeper集群安裝,參考: Zookeeper 集群搭建--單機偽分布式集群
我這里用的是三台服務器,分別為第一台sever1 118.xx.xx.101,第二台 server2 49.xx.xx.125, 第三台server3 110.xx.xx.67
二、配置
1、集群配置 config.xml
<remote_servers> <perftest_3shards_2replicas> <shard> <internal_replication>true</internal_replication> <replica> <host>server1</host> <port>9000</port> <user>larrylin2</user> <password>123456</password> </replica> <replica> <host>server2</host> <port>9001</port> <user>larrylin2</user> <password>123456</password> </replica> </shard> <shard> <internal_replication>true</internal_replication> <replica> <host>server2</host> <port>9000</port> <user>larrylin2</user> <password>123456</password> </replica> <replica> <host>server3</host> <port>9001</port> <user>larrylin2</user> <password>123456</password> </replica> </shard> <shard> <internal_replication>true</internal_replication> <replica> <host>server3</host> <port>9000</port> <user>larrylin2</user> <password>123456</password> </replica> <replica> <host>server1</host> <port>9001</port> <user>larrylin2</user> <password>123456</password> </replica> </shard> </perftest_3shards_2replicas> </remote_servers>
2、zk集群配置 config.xml
<zookeeper> <node> <host>server1</host> <port>2181</port> </node> <node> <host>server2</host> <port>2181</port> </node> <node> <host>server3</host> <port>2181</port> </node> </zookeeper>
3、副本配置 config.xml
<macros> <layer>01</layer> <shard>01</shard> <replica>01-01-1</replica> </macros>
另外5個實例的副本配置分別為
<macros> <layer>01</layer> <shard>01</shard> <replica>01-01-2</replica> </macros> <macros> <layer>01</layer> <shard>02</shard> <replica>01-02-1</replica> </macros> <macros> <layer>01</layer> <shard>02</shard> <replica>01-02-2</replica> </macros> <macros> <layer>01</layer> <shard>03</shard> <replica>01-03-1</replica> </macros> <macros> <layer>01</layer> <shard>03</shard> <replica>01-03-2</replica> </macros>
4、用戶配置 users.xml
<users> <larrylin2> <password>123456</password> <networks incl="networks" replace="replace"> <ip>0.0.0.0</ip> </networks> <profile>default</profile> <quota>default</quota> </larrylin2> </users>
三、創建本地表
CREATE TABLE IF NOT EXISTS default.test_local ON CLUSTER 'perftest_3shards_2replicas' ( ts_date Date, ts_date_time DateTime, user_id Int64, event_type String, site_id Int64, groupon_id Int64, category_id Int64, merchandise_id Int64, search_text String ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/default/test_local','{replica}') PARTITION BY ts_date ORDER BY (ts_date,toStartOfHour(ts_date_time),site_id,event_type) SETTINGS index_granularity = 8192;
ON CLUSTER 表示分布式DDL, 一次執行所有實例上創建同樣的本地表。
perftest_3shards_2replicas為集群名稱
{shard} 分片標識符
{replica} 副本標識符,來自config.xml 中的macros
ReplicatedMergeTree引擎接收兩個參數:
1、ZK中該表相關數據的存儲路徑,Clickhouse官方建議格式 /clickhouse/tables/{shard}/[database_name]/[table_name]
2、副本名稱,一般用{replica}
四、ZK路徑的znode結構和內容
metadata的value值
metadata format version: 1 date column: sampling expression: index granularity: 8192 mode: 0 sign column: primary key: ts_date, toStartOfHour(ts_date_time), site_id, event_type data format version: 1 partition key: ts_date granularity bytes: 10485760
colums的value值
columns format version: 1 9 columns: `ts_date` Date `ts_date_time` DateTime `user_id` Int64 `event_type` String `site_id` Int64 `groupon_id` Int64 `category_id` Int64 `merchandise_id` Int64 `search_text` String
ReplicatedMergeTree引擎在ZK中存儲了大量的數據,包括表結構信息,元數據、操作日志、副本狀態、數據塊校驗值、數據part merge過程中的選主信息等。
ZK在復制表機制下有元數據存儲、日志框架、分布式協調器服務三種角色,任務很重,所以要保證ZK集群的可用性以及資源(尤其是硬盤資源)。
五、創建分布式表
CREATE TABLE IF NOT EXISTS default.test_all ON CLUSTER 'perftest_3shards_2replicas' AS default.test_local ENGINE = Distributed(perftest_3shards_2replicas, default, test_local,rand());
Distributed引擎需要以下幾個參數
1) 集群標識符
2)本地表所在的數據庫名稱
3) 本地表名稱
4)分片鍵sharding key(可選)
該鍵與config.xml 中配置的分片權重(weight) 一同決定寫入分布式表時的路由。它可以時表中的一列原始數據(如site_id),也可以是函數調用的結果,如上面的SQL語句采用了隨機值rand()。 注意該鍵要盡量保證數據均勻分布,另外一個常用的操作是采用區分度較高的列的哈希值,如intHash64(user_id).
直接寫分布式表的優點自然是可以讓clickhouse控制數據到分片的路由,
缺點:
數據是先寫到一個分布式表的實例中緩存起來,再逐漸分發到各個分片上去,實際是雙寫了數據(寫入放大),浪費資源。
數據寫入默認是異步的,短時間內可能造成不一致。
目標表中會產生較多的小parts,使merge(即compaction)過程壓力增大。
相對而言,直接寫本地表是同步操作,更快,parts的大小也比較合適,但是要求應用層額外實現路由邏輯,如輪詢或者隨機等。
六、驗證
在第一台9000中增加數據
insert into test_local (ts_date, ts_date_time, user_id, event_type, site_id, groupon_id, category_id, merchandise_id, search_text) values ('2021-11-11','2021-11-11 10:00:00',5,'stand',1,1,1,1,'world');
可以看到數據已經添加select * from test_local where user_id= 5;
查詢分布式表
在另外一台查看本地表 select * from test_local where user_id= 5;
說明數據已經復制到副本了。