相关知识参考:https://cloud.tencent.com/developer/article/1797196
1、Clickhouse集群安装部署,首先安装单机版,可参考之前:https://cloud.tencent.com/developer/article/1795091,我是先安装了一台虚拟机,然后克隆了两台机器,所以,克隆完成,配置好ip地址,三台服务器的Clickhouse就安装完毕了,如果是正式环境,三台机器的安装方式就按照单机版先安装即可。此时,三台服务器的Clickhouse安装完成。
代码语言:javascript复制1 查看安装信息,目录结构。
2 /etc/clickhouse-server:服务端的配置文件目录,包括全局配置config.xml和用户配置users.xml等。
3 /etc/clickhouse-client:客户端配置,包括conf.d文件夹和config.xml文件。
4 /var/lib/clickhouse:默认的数据存储目录(通常会修改默认路径配置,将数据保存到大容量磁盘挂载的路径)。
5 /var/log/clickhouse-server:默认保存日志的目录(通常会修改路径配置,将日志保存到大容量磁盘挂载的路径)。
2、开始安装Zookeeper,集群安装参考:https://cloud.tencent.com/developer/article/1010727,Zookeeper集群搭建完成之后,开始整合Clickhouse和Zookeeper。启动Zookeeper集群。
代码语言:javascript复制 1 [root@master apache-zookeeper-3.6.1-bin]# ls
2 bin conf data docs lib LICENSE.txt logs NOTICE.txt README.md README_packaging.md
3 [root@master apache-zookeeper-3.6.1-bin]# cd bin/
4 [root@master bin]# ls
5 README.txt zkCli.cmd zkEnv.cmd zkServer.cmd zkServer.sh zkSnapShotToolkit.sh zkTxnLogToolkit.sh
6 zkCleanup.sh zkCli.sh zkEnv.sh zkServer-initialize.sh zkSnapShotToolkit.cmd zkTxnLogToolkit.cmd
7 [root@master bin]#
8 [root@master bin]#
9 [root@master bin]# ./zkServer.sh status
10 ZooKeeper JMX enabled by default
11 Using config: /usr/local/soft/apache-zookeeper-3.6.1-bin/bin/../conf/zoo.cfg
12 Client port found: 2181. Client address: localhost.
13 Error contacting service. It is probably not running.
14 [root@master bin]#
15 [root@master bin]#
16 [root@master bin]# systemctl status firewalld.service
17 ● firewalld.service - firewalld - dynamic firewall daemon
18 Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
19 Active: inactive (dead)
20 Docs: man:firewalld(1)
21 [root@master bin]# ./zkServer.sh status
22 ZooKeeper JMX enabled by default
23 Using config: /usr/local/soft/apache-zookeeper-3.6.1-bin/bin/../conf/zoo.cfg
24 Client port found: 2181. Client address: localhost.
25 Mode: follower
记得关闭三台机器的防火墙哦!
3、首先,修改/etc/clickhouse-server/目录下的config.xml。
代码语言:javascript复制<!-- 如果禁用了ipv6,使用下面配置 -->
<listen_host>0.0.0.0</listen_host>
<!-- 如果没有禁用ipv6,使用下面配置,我使用的下面的配置 -->
<listen_host>::</listen_host>
然后,在/etc/下创建集群配置文件metrika.xml文件(这个文件需要创建),在Clickhouse启动的时候会加载这个配置文件以集群的形式启动Clickhouse,可以选择配置不包含副本的分片配置,还可以为分片配置多个副本。
代码语言:javascript复制 1 <yandex>
2 <!-- /etc/clickhouse-server/config.xml 中配置的remote_servers的incl属性值,-->
3 <clickhouse_remote_servers>
4 <!-- 集群名称,可以修改 -->
5 <doit_ch_cluster1>
6 <!-- 配置三个分片,每个分片对应一台机器,为每个分片配置一个副本 -->
7 <shard>
8 <internal_replication>true</internal_replication>
9 <replica>
10 <host>master</host>
11 <port>9000</port>
12 </replica>
13 </shard>
14 <shard>
15 <replica>
16 <internal_replication>true</internal_replication>
17 <host>slaver1</host>
18 <port>9000</port>
19 </replica>
20 </shard>
21 <shard>
22 <internal_replication>true</internal_replication>
23 <replica>
24 <host>slaver2</host>
25 <port>9000</port>
26 </replica>
27 </shard>
28 </doit_ch_cluster1>
29 </clickhouse_remote_servers>
30
31
32 <!-- zookeeper相关配置 -->
33 <!-- 该标签与config.xml的<zookeeper incl="zookeeper-servers" optional="true" /> 保持一致 -->
34 <zookeeper-servers>
35 <node index="1">
36 <host>master</host>
37 <port>2181</port>
38 </node>
39
40 <node index="2">
41 <host>slaver1</host>
42 <port>2181</port>
43 </node>
44 <node index="3">
45 <host>slaver2</host>
46 <port>2181</port>
47 </node>
48 </zookeeper-servers>
49
50 <!-- 分片和副本标识,shard标签配置分片编号,<replica>配置分片副本主机名,需要修改对应主机上的配置 -->
51 <macros>
52 <replica>doit01</replica>
53 </macros>
54 <networks>
55 <ip>::/0</ip>
56 </networks>
57
58 <clickhouse_compression>
59 <case>
60 <min_part_size>10000000000</min_part_size>
61 <min_part_size_ratio>0.01</min_part_size_ratio>
62 <method>lz4</method>
63 </case>
64 </clickhouse_compression>
65
66 </yandex>
然后,将/etc/下metrika.xml文件scp到另外两个机器上,如下所示:
代码语言:javascript复制1 [root@master etc]#
2 [root@master etc]# scp /etc/metrika.xml slaver1:/etc/
3 root@slaver1's password:
4 metrika.xml 100% 1427 779.3KB/s 00:00
5 [root@master etc]# scp /etc/metrika.xml slaver2:/etc/
6 root@slaver2's password:
7 metrika.xml 100% 1427 844.8KB/s 00:00
8 [root@master etc]#
在每台机器上启动Clickhouse服务,以集群的形式启动,如果想要再以单节点的形式启动那么就删除/etc/下的metrika.xml文件即可单节点的形式启动。
代码语言:javascript复制 1 [root@slaver1 bin]# service clickhouse-server status
2 clickhouse-server service is running
3 [root@slaver1 bin]#
4 [root@slaver1 bin]# service clickhouse-server stop
5 Stop clickhouse-server service: DONE
6 [root@slaver1 bin]#
7 [root@slaver1 bin]#
8 [root@slaver1 bin]# service clickhouse-server start
9 Start clickhouse-server service: Path to data directory in /etc/clickhouse-server/config.xml: /var/lib/clickhouse/
10
11 DONE
12 [root@slaver1 bin]#
13 [root@slaver1 bin]#
14 [root@slaver1 bin]#
15 [root@slaver1 bin]# service clickhouse-server status
16 clickhouse-server service is running
17 [root@slaver1 bin]#
如果遇到servie:未找到命令的话,可以使用下面的方法解决,如下所示:
代码语言:javascript复制1 [root@master ~]# service
2 bash: service: 未找到命令...
3 [root@master ~]#
首先,要知道,su 或者 su root:的话只是将当前身份转为root,用户shell并没有改变,所以有些系统命令不能使用。
如果使用,su -或者su -l或者su -l root,可以完全的将当前环境转为root环境,如同root直接登陆。
其次,service的路径为/sbin/service,如果shell没有改变,那么你的PATH中默认没有/sbin,所以不行,而如果用su -命令环境改为root,PATH中就包含/sbin。
4、确定Zookeeper集群启动,启动三台Clickhouse的服务,然后在任意一台启动Clickhouse的客户端,使用查看集群信息的sql进行查看信息,如下所示:
代码语言:javascript复制 1 [root@master ~]# clickhouse-client -m
2 ClickHouse client version 20.8.3.18.
3 Connecting to localhost:9000 as user default.
4 Connected to ClickHouse server version 20.8.3 revision 54438.
5
6 master :)
7 master :)
8 master :)
9 master :) select * from system.clusters;
10
11 SELECT *
12 FROM system.clusters
13
14 ┌─cluster───────────────────────────┬─shard_num─┬─shard_weight─┬─replica_num─┬─host_name─┬─host_address────┬─port─┬─is_local─┬─user────┬─default_database─┬─errors_count─┬─estimated_recovery_time─┐
15 │ doit_ch_cluster1 │ 1 │ 1 │ 1 │ master │ 192.168.110.133 │ 9000 │ 1 │ default │ │ 0 │ 0 │
16 │ doit_ch_cluster1 │ 2 │ 1 │ 1 │ slaver1 │ 192.168.110.134 │ 9000 │ 0 │ default │ │ 0 │ 0 │
17 │ doit_ch_cluster1 │ 3 │ 1 │ 1 │ slaver2 │ 192.168.110.135 │ 9000 │ 0 │ default │ │ 0 │ 0 │
18 │ test_cluster_two_shards │ 1 │ 1 │ 1 │ 127.0.0.1 │ 127.0.0.1 │ 9000 │ 1 │ default │ │ 0 │ 0 │
19 │ test_cluster_two_shards │ 2 │ 1 │ 1 │ 127.0.0.2 │ 127.0.0.2 │ 9000 │ 0 │ default │ │ 0 │ 0 │
20 │ test_cluster_two_shards_localhost │ 1 │ 1 │ 1 │ localhost │ ::1 │ 9000 │ 1 │ default │ │ 0 │ 0 │
21 │ test_cluster_two_shards_localhost │ 2 │ 1 │ 1 │ localhost │ ::1 │ 9000 │ 1 │ default │ │ 0 │ 0 │
22 │ test_shard_localhost │ 1 │ 1 │ 1 │ localhost │ ::1 │ 9000 │ 1 │ default │ │ 0 │ 0 │
23 │ test_shard_localhost_secure │ 1 │ 1 │ 1 │ localhost │ ::1 │ 9440 │ 0 │ default │ │ 0 │ 0 │
24 │ test_unavailable_shard │ 1 │ 1 │ 1 │ localhost │ ::1 │ 9000 │ 1 │ default │ │ 0 │ 0 │
25 │ test_unavailable_shard │ 2 │ 1 │ 1 │ localhost │ ::1 │ 1 │ 0 │ default │ │ 0 │ 0 │
26 └───────────────────────────────────┴───────────┴──────────────┴─────────────┴───────────┴─────────────────┴──────┴──────────┴─────────┴──────────────────┴──────────────┴─────────────────────────┘
27
28 11 rows in set. Elapsed: 0.019 sec.
29
30 master :)
或者使用指定字段的查询语句,方便观察,如下所示:
代码语言:javascript复制 1 master :)
2 master :) select cluster,shard_num,replica_num,host_name,port,user from system.clusters;
3
4 SELECT
5 cluster,
6 shard_num,
7 replica_num,
8 host_name,
9 port,
10 user
11 FROM system.clusters
12
13 ┌─cluster───────────────────────────┬─shard_num─┬─replica_num─┬─host_name─┬─port─┬─user────┐
14 │ doit_ch_cluster1 │ 1 │ 1 │ master │ 9000 │ default │
15 │ doit_ch_cluster1 │ 2 │ 1 │ slaver1 │ 9000 │ default │
16 │ doit_ch_cluster1 │ 3 │ 1 │ slaver2 │ 9000 │ default │
17 │ test_cluster_two_shards │ 1 │ 1 │ 127.0.0.1 │ 9000 │ default │
18 │ test_cluster_two_shards │ 2 │ 1 │ 127.0.0.2 │ 9000 │ default │
19 │ test_cluster_two_shards_localhost │ 1 │ 1 │ localhost │ 9000 │ default │
20 │ test_cluster_two_shards_localhost │ 2 │ 1 │ localhost │ 9000 │ default │
21 │ test_shard_localhost │ 1 │ 1 │ localhost │ 9000 │ default │
22 │ test_shard_localhost_secure │ 1 │ 1 │ localhost │ 9440 │ default │
23 │ test_unavailable_shard │ 1 │ 1 │ localhost │ 9000 │ default │
24 │ test_unavailable_shard │ 2 │ 1 │ localhost │ 1 │ default │
25 └───────────────────────────────────┴───────────┴─────────────┴───────────┴──────┴─────────┘
26
27 11 rows in set. Elapsed: 0.011 sec.
28
29 master :)
5、分布式DDL操作,默认情况下,CREATE、DROP、ALTER、RENAME操作仅仅在当前执行该命令的server上生效。在集群环境下,可以使用ON CLUSTER语句,这样就可以在整个集群发挥作用。
可以创建一张分布式表,如下所示:
代码语言:javascript复制CREATE TABLE IF NOT EXISTS user_cluster ON CLUSTER doit_ch_cluster1
(
id Int32,
name String
)ENGINE = Distributed(doit_ch_cluster1, default, user_local,id);
Distributed表引擎的定义形式如下所示:
代码语言:javascript复制1 Distributed(cluster_name, database_name, table_name[, sharding_key])
各个参数的含义分别如下:
a)、cluster_name:集群名称,与集群配置中的自定义名称相对应。
b)、database_name:数据库名称。
c)、table_name:表名称。
d)、sharding_key:可选的,用于分片的key值,在数据写入的过程中,分布式表会依据分片key的规则,将数据分布到各个节点的本地表。
代码语言:javascript复制 1 master :)
2 master :)
3 master :) CREATE TABLE IF NOT EXISTS user_cluster ON CLUSTER doit_ch_cluster1
4 :-] (
5 :-] id Int32,
6 :-] name String
7 :-] )ENGINE = Distributed(doit_ch_cluster1, default, user_local,id);
8
9 CREATE TABLE IF NOT EXISTS user_cluster ON CLUSTER doit_ch_cluster1
10 (
11 `id` Int32,
12 `name` String
13 )
14 ENGINE = Distributed(doit_ch_cluster1, default, user_local, id)
15
16 ┌─host────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
17 │ slaver2 │ 9000 │ 0 │ │ 2 │ 0 │
18 │ master │ 9000 │ 0 │ │ 1 │ 0 │
19 │ slaver1 │ 9000 │ 0 │ │ 0 │ 0 │
20 └─────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
21
22 3 rows in set. Elapsed: 0.188 sec.
23
24 master :)
25 master :)
26 master :)
注意:创建分布式表是读时检查的机制,也就是说对创建分布式表和本地表的顺序并没有强制要求。同样值得注意的是,在上面的语句中使用了ON CLUSTER分布式DDL,这意味着在集群的每个分片节点上,都会创建一张Distributed表,这样便可以从其中任意一端发起对所有分片的读、写请求。
6、创建完成上面的分布式表时,在每台机器上查看表,发现每台机器上都存在一张刚刚创建好的表。
代码语言:javascript复制 1 master :) use default;
2
3 USE default
4
5 Ok.
6
7 0 rows in set. Elapsed: 0.007 sec.
8
9 master :) show tables;
10
11 SHOW TABLES
12
13 ┌─name─────────┐
14 │ user_cluster │
15 └──────────────┘
16
17 1 rows in set. Elapsed: 0.019 sec.
18
19 master :) desc user_cluster;
20
21 DESCRIBE TABLE user_cluster
22
23 ┌─name─┬─type───┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
24 │ id │ Int32 │ │ │ │ │ │
25 │ name │ String │ │ │ │ │ │
26 └──────┴────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
27
28 2 rows in set. Elapsed: 0.010 sec.
29
30 master :)
接下来就需要创建本地表了,在每台机器上分别创建一张本地表,就是在三台机器上都创建一个本地表:
代码语言:javascript复制 1 master :) CREATE TABLE IF NOT EXISTS user_local
2 :-] (
3 :-] id Int32,
4 :-] name String
5 :-] )ENGINE = MergeTree()
6 :-] ORDER BY id
7 :-] PARTITION BY id
8 :-] PRIMARY KEY id;
9
10 CREATE TABLE IF NOT EXISTS user_local
11 (
12 `id` Int32,
13 `name` String
14 )
15 ENGINE = MergeTree()
16 PARTITION BY id
17 PRIMARY KEY id
18 ORDER BY id
19
20 Ok.
21
22 0 rows in set. Elapsed: 0.009 sec.
23
24 master :)
25 master :)
首先,先在一台机器上,对user_local表进行插入数据,然后再查询user_cluster表,如下所示:
代码语言:javascript复制 1 -- 插入数据
2 master :) INSERT INTO user_local VALUES(1,'tom'),(2,'jack');
3
4 INSERT INTO user_local VALUES
5
6 Ok.
7
8 2 rows in set. Elapsed: 0.011 sec.
9
10 -- 查询user_cluster表,可见通过user_cluster表可以操作所有的user_local表
11 master :) select * from user_cluster;
12
13 SELECT *
14 FROM user_cluster
15
16 ┌─id─┬─name─┐
17 │ 1 │ tom │
18 └────┴──────┘
19 ┌─id─┬─name─┐
20 │ 2 │ jack │
21 └────┴──────┘
22
23 2 rows in set. Elapsed: 0.044 sec.
24
25 master :)
接下来,我们再向user_cluster中插入一些数据,观察user_local表数据变化,可以发现数据被分散存储到了其他节点上了。
代码语言:javascript复制 1 ----------------- 向user_cluster插入数据
2 master :)
3
4 ----------------- 查看master节点的user_cluster数据
5 master :) select * from user_cluster;
6
7 SELECT *
8 FROM user_cluster
9
10 ┌─id─┬─name─┐
11 │ 2 │ jack │
12 └────┴──────┘
13 ┌─id─┬─name─┐
14 │ 1 │ tom │
15 └────┴──────┘
16 ┌─id─┬─name──┐
17 │ 3 │ lilei │
18 └────┴───────┘
19 ┌─id─┬─name──┐
20 │ 4 │ lihua │
21 └────┴───────┘
22
23 4 rows in set. Elapsed: 0.029 sec.
24
25 master :)
26
27 ----------------- 查看master节点的user_local数据
28 master :) select * from user_local;
29
30 SELECT *
31 FROM user_local
32
33 ┌─id─┬─name─┐
34 │ 2 │ jack │
35 └────┴──────┘
36 ┌─id─┬─name─┐
37 │ 1 │ tom │
38 └────┴──────┘
39 ┌─id─┬─name──┐
40 │ 3 │ lilei │
41 └────┴───────┘
42
43 3 rows in set. Elapsed: 0.011 sec.
44
45 master :)
46
47
48 ----------------- 查看slave1节点的数据信息
49 slaver1 :) select * from user_local;
50
51 SELECT *
52 FROM user_local
53
54 ┌─id─┬─name──┐
55 │ 4 │ lihua │
56 └────┴───────┘
57
58 1 rows in set. Elapsed: 0.015 sec.
59
60 slaver1 :)
61 slaver1 :)
7、如何使用DBeaver查看Clickhouse集群的数据和信息呢,如下所示:
集群名称user_cluster,本地表user_local,在DBeaver工具连接Clickhouse的时候,在视图可以查看集群的数据信息,在表下面可以查看本地表的数据信息,其中集群数据会分布到不同的分片上。