ClickHouse集群部署实践---3分片2副本集群
ClickHouse集群部署实践—3分片2副本集群
未完待续。。。 喜欢的先点赞收藏!!
由于我们准备部署的是3分片2副本的集群,现在来解释一下配置参数的意思:
shard标签代表分片的意思,如上图我们有3个分片,clickhouse集群中每个分片会存储整个集群一部分的数据,每个分片中有这个标签:
代表副本的意思,什么是副本?比如我只有三台机器做三个分片,那么每个分片中只有这一台机器作为副本,这台机器存储这个分片的所有数据,若这台机器挂掉了,那么数据就丢了。
那如果我们有6台机器或者更多,每个分片里就可以配置两个副本机器,这两个副本存储的数据是一摸一样的,集群读取数据时会随机从其中选择一个读取。这样即使一台机器挂掉了,也不会影响正常使用,而且对业务来说是无感的,数据一切正常。
还有最重要的这个标签:
<internal_replication>true</internal_replication>
因为我们和zookeeper配合使用,internal_replication必须设置为true,原因等下解释。
2.基于Cluster的复制方式:
大致说一下这种方式,包括官方在内都不推荐这种方式。这种方式不需要配置zookeeper。
如果我们想使用这种方式,需要打开配置文件:
/etc/clickhouse-server/config.xml
找到<remote_servers>这个标签,下面的所有信息就是我们配置集群的配置信息,和上边基本一致,但这个标签<internal_replication>false</internal_replication>不一样,里面要写false
详细说一下:
(1)internal_replication=false时:
往分布式表(注意分布式表只是本地表的view,是不存放任何实体数据的)里面写入数据时,表层面自动同步开启,数据会写入所有备份中(同属一个shard内的表数据相同),但是这个时候是不校验数据一致性的(比如说写入server1的时候成功了,但是写入server1的备份server2的时候有一些没有写入成功,那么这两个互为备份的表就不一致了),也就是说,有可能出现两个备份数据略微不一致的情况,虽然这种可能性很小,另外出现了不一致的时候表之间不会自动同步需要自己手动。这种被官方称为poor man’s replication,如果喜欢简单而且特别讨厌配置zookeeper的话可以使用
(2)internal_replication=true,且没有zookeeper的配合:
不使用zookeeper,那么往分布式表写入数据时,是只写入一组备份中的(也就是说同一个shard内部只有一个表写入了数据,其他的表均不会写入数据,除非有一个宕机另外的作为补充下入,但是这个时候表之间的数据就不同了,需要人工手动统一(备份合并就是shard总体)。实际测试中,当向分布式表写入数据时,replica group 1 被写入了数据,replica group 2 没有被写入数据。在此种条件下(internal_replication=true时且不使用zookeeper),存在海量风险,极其不建议使用: 实际测试中,所有节点均正常工作的情况下,使用分布式表查询,同样的sql语句会出现前后结果不一致的情况 当有节点挂掉时候,那么挂掉之前的数据是写入备份A,挂掉之后数据写入了备份B(此时集群还是正常工作的),当你去使用分布表查询数据时,是肯定会得到错误结果的,因为分布表的查询方式是每个shard中选取一个表来查询并合并结果,由于备份A和备份B之间没同步,那么你查询的只是一部分数据。这种方法切记不能使用!
(3)internal_replication=true时:
使用ReplicatedMergeTree表引擎+zookeeper,这种方案看起来配置很多但是也是最稳定的方案。
三、总结:
对比clickhouse集群部署提供的两种方案,基于zookeeper的部署方案更稳重更安全。所以建议采用这种。
另外在搭建完成后,我们创建了分布式表和本地表,在上述实验中,我们是直接写分布式表,分布式表会将数据发送到其他机器的本地表上。有人建议不要直接这么做,我查阅了很多文章,总结一下原因:
1.数据量很大时:
当每天数据量很大时,比如每天上亿级别或以上。由于分布式表的逻辑简单,仅仅是转发请求,所以在转发安全性上,会有风险,并且rand的方式,可能会造成不均衡,而且Distributed表在写入时会在本地节点生成临时数据,会产生写放大,所以会对CPU及内存造成一些额外消耗,分布式表接收到数据后会将数据拆分成多个parts, 并转发数据到其它服务器, 会引起服务器间网络流量增加、服务器merge的工作量增加, 导致写入速度变慢, 并且增加了Too many parts的可能性。因此数据量大时建议通过轮询的方式写本地表,这样最保险和均衡,这也是很多人建议使用的。
1.数据量并不大时:
直接写分布式表和轮询写本地表都差不多,想用哪种方式都可以。
其实分布式表的本质就是一个视图,设计的目的就是为了查询的,虽然数据量不大时没有什么影响。
2.综上所述,我觉得集群部署使用的最佳建议:
(1)采用基于zookeeper的方式部署集群
(2)每个分片最少有两个副本来保证数据一致性
(3)读分布式表,分布式表只做查询
(4)通过负载均衡的方式写本地表
(5)尽量做1000条以上批量的写入,避免逐行insert或小批量的insert,update,delete操作,因为ClickHouse底层会不断的做异步的数据合并,会影响查询性能。
报错信息1:
moban 😃 CREATE TABLE test_ck ON CLUSTER ck_cluster (EventDate DateTime, Number UInt32, id UInt32 ) ENGINE = ReplicatedMergeTree(‘/clickhouse/tables/{shard}/test_ck’, ‘{replica}’) PARTITION BY toYYYYMM(EventDate) ORDER BY (Number, EventDate, intHash32(id)) SAMPLE BY intHash32(id);
CREATE TABLE test_ck ON CLUSTER ck_cluster
(
EventDate
DateTime,
Number
UInt32,
id
UInt32
)
ENGINE = ReplicatedMergeTree(‘/clickhouse/tables/{shard}/test_ck’, ‘{replica}’)
PARTITION BY toYYYYMM(EventDate)
ORDER BY (Number, EventDate, intHash32(id))
SAMPLE BY intHash32(id)
Query id: b190fcda-108c-4d1a-8dfd-c56326b14701
0 rows in set. Elapsed: 0.002 sec.
Received exception from server (version 21.7.3):
Code: 139. DB::Exception: Received from localhost:9000. DB::Exception: There is no Zookeeper configuration in server config.
问题解决:
上面的报错 是由于config.xml listen_host配置错误问题。
报错信息2:
Code: 210, e.displayText() = DB::NetException: Connection refused (bta2:9000) (version 21.7.3.14 (official build))
问题解决:
上面的报错 是由于config.xml listen_host配置错误问题。
报错信息3:
clickhouse误删同步表,重新创建时 报副本已经存在。
解决方案:
使用 ZooKeeper 客户端直接清理
连接到 ZooKeeper
zkCli.sh -server <zk_host>:2181
删除残留路径(替换实际路径)
rmr /clickhouse/tables/your_table_path