我这里准备了四台机器,准备搭建3分片2副本集群(其中只有一台机器有副本,其他两台没有副本)
机器ip信息如下所示:
| 机器名称 | 机器ip |
|---|---|
| 102(部署ck作为分片1和zookeeper) | 192.168.141.102 |
| 103 (ck作为分片2) | 192.168.141.103 |
| 104 (ck作为分片2副本) | 192.168.141.104 |
| 105 (ck作为分片3) | 192.168.141.105 |
用这个环境来分别部署以下集群来进行验证,至于集群的部署在本文不细说。
集群模式 单分片多副本模式mergeTree+distribute[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wzQ9yFIc-1657597822191)(uploadimage-20220708174015397.png)]
特点集群中只有一个分片,多个节点组成此分片的副本,每个节点保留全量的数据,通过在创建Distributed表不声明分片键实现全量写入
数据流向读:由于每个节点都拥有全量数据,因此读请求通过负载均衡到达任意一个节点的本地表或分布式表(由于是单分片,distributed只需要根据负载均衡算法选择某个副本的本地表后查询即可,不需要查询其他分片数据)都可查询到数据
写:写请求通过负载均衡到某个节点的distributed表,经过distributed向所有节点里的本地表写入数据。
优缺点优点:由于每个节点都有全量数据,因此容灾性非常好,只剩一台节点也能对外提供查询,在数据量不是极大的情况下单节点查询性能也还行。
缺点:
- 写的时候由于是往所有节点进行写入,若某些节点出错了,容易导致整个集群节点的数据不一致现象
- 由于数据需要分别写入所有节点,因此写的性能较差
- 没有利用到分布式存储分片和分布式计算性能,存储容易达到瓶颈,计算在极大数据量时也容易有瓶颈
在各节点创建表192.168.141.102 9000 default clickhouse 192.168.141.103 9000 default clickhouse 192.168.141.104 9000 default clickhouse 192.168.141.105 9000 default clickhouse shard-01 replica-01
CREATE TABLE test_ck_single_burst (EventDate DateTime, Number UInt32, id UInt32 ) ENGINE = MergeTree PARTITION BY toYYYYMM(EventDate) ORDER BY (Number, EventDate, intHash32(id)) SAMPLE BY intHash32(id);
创建分布式表CREATE TABLE distributed_test_single_burst ENGINE = Distributed(ck_cluster, default, test_ck_single_burst , rand())
在102节点往分布式表插入数据insert into distributed_test_single_burst values (‘2021-07-01 11:00:00’, 1,11);
insert into distributed_test_single_burst values (‘2021-07-01 12:00:00’, 2,22);
insert into distributed_test_single_burst values (‘2021-07-01 13:00:00’, 3,33);
insert into distributed_test_single_burst values (‘2021-07-01 14:00:00’, 4,44);
insert into distributed_test_single_burst values (‘2021-07-01 15:00:00’, 5,55);
insert into distributed_test_single_burst values (‘2021-07-01 16:00:00’, 6,66);
在102中写入分布式表的数据,在103,104,105不管查分布式表还是查本地表都能看到,证明在写入分布式表时,分布式表会将其写入分片下的所有副本,任意一节点的数据都为全量数据。
多分片单副本模式mergeTree+distribute[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JaMB8OIm-1657597822192)(uploadimage-20220708174218471.png)]
特点集群中多个分片,每个分片只有一个节点,没有副本。
数据流向读:读请求通过负载均衡到达任意一个节点的分布式表distributed,distributed根据查询的语句进行分片处理,往每个分片对应的目标节点(因为没有副本,所以跳过了分片后的负载均衡步骤)发送查询请求,节点收到查询请求后直接查询本地表后返回数据给请求节点做合并。
写:写请求通过负载均衡到某个节点的distributed表,经过distributed对查询语句分片处理后,往符合分片策略的目标节点(一个shard只有一个目标节点)里的本地表写入数据。
优缺点优点:
- 由于做了数据分片,因此没有冗余,且由于单分片没有副本,一个分片只需写一份,因此在写入性能是最高的。
- 由于做了数据分片,因此读请求时能充分利用分布式集群的计算性能,查询速度较快
缺点:
- 由于数据没有副本,可靠性极低,有极大的数据丢失风险。
mv /etc/clickhouse-server/config.d/metrika.xml.single-copy /etc/clickhouse-server/config.d/metrika.xml
在各节点创建表192.168.141.102 9000 default clickhouse 192.168.141.103 9000 default clickhouse 192.168.141.105 9000 default clickhouse shard-01 replica-01
CREATE TABLE test_ck_single_copy (EventDate DateTime, Number UInt32, id UInt32 ) ENGINE = MergeTree PARTITION BY toYYYYMM(EventDate) ORDER BY (Number, EventDate, intHash32(id)) SAMPLE BY intHash32(id);
创建分布式表CREATE TABLE distributed_test_single_copy ENGINE = Distributed(ck_cluster, default, test_ck_single_copy, rand())
在102节点往分布式表插入数据insert into distributed_test_single_copy values (‘2021-07-01 11:00:00’, 1,11);
insert into distributed_test_single_copy values (‘2021-07-01 12:00:00’, 2,22);
insert into distributed_test_single_copy values (‘2021-07-01 13:00:00’, 3,33);
insert into distributed_test_single_copy values (‘2021-07-01 14:00:00’, 4,44);
insert into distributed_test_single_copy values (‘2021-07-01 15:00:00’, 5,55);
insert into distributed_test_single_copy values (‘2021-07-01 16:00:00’, 6,66);
在102中写入分布式表的数据,在103,105不管查分布式表都能看到,但如果分别在102、103、105节点查询本地表test_ck_single_copy ,则会发现每个节点都有局部数据,组合起来就是所有的数据,验证了在此集群下写入分布式表为多分片写入。
多分片多副本模式mergeTree+distribute[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-svoetwYO-1657597822193)(uploadimage-20220708175744231.png)]
特点在上一个方案的基础上增加了副本,集群中多个分片多副本。
数据流向读:读请求通过负载均衡到达任意一个节点的分布式表distributed,distributed准备往每个分片发送查询请求,但此时由于每个分片都有副本,因此还需要从分片的副本中负载均衡算法选取合适的副本节点发送查询请求,节点收到查询请求后直接查询本地表后返回数据给请求节点做合并。
写:写请求通过负载均衡到某个节点的distributed表,经过distributed对写入的数据进行分片处理,由于分片有副本,因此需要往符合分片策略的所有副本节点里的本地表写入数据。
优缺点优点:
- 由于做了数据分片,没有冗余,数据存储能力增强了;由于多了副本做数据备份,因此可靠性也增加了。
- 由于做了数据分片,因此读请求时能充分利用分布式集群的计算性能,查询速度较快
缺点:
- distributed在处理写请求时,除了写分片之外,还要负责分片的所有副本节点的写入,对distributed来说压力比较大,容易造成写入瓶颈。
- 如果某台节点挂了且不可恢复问题,由于没有自动同步机制,虽然有副本备份,但恢复需要手工操作,略为繁琐。
在每个节点都执行配置文件重命名
mv /etc/clickhouse-server/config.d/metrika.xml.mult-burst-copy /etc/clickhouse-server/config.d/metrika.xml
在各节点创建表192.168.141.102 9000 default clickhouse 192.168.141.103 9000 default clickhouse 192.168.141.104 9000 default clickhouse 192.168.141.105 9000 default clickhouse shard-01 replica-01
CREATE TABLE test_ck_mult_burst_copy (EventDate DateTime, Number UInt32, id UInt32 ) ENGINE = MergeTree PARTITION BY toYYYYMM(EventDate) ORDER BY (Number, EventDate, intHash32(id)) SAMPLE BY intHash32(id);
创建分布式表CREATE TABLE distributed_test_mult_burst_copy ENGINE = Distributed(ck_cluster, default, test_ck_mult_burst_copy, rand())
在102节点往分布式表插入数据insert into distributed_test_mult_burst_copy values (‘2021-07-01 11:00:00’, 1,11);
insert into distributed_test_mult_burst_copy values (‘2021-07-01 12:00:00’, 2,22);
insert into distributed_test_mult_burst_copy values (‘2021-07-01 13:00:00’, 3,33);
insert into distributed_test_mult_burst_copy values (‘2021-07-01 14:00:00’, 4,44);
insert into distributed_test_mult_burst_copy values (‘2021-07-01 15:00:00’, 5,55);
insert into distributed_test_mult_burst_copy values (‘2021-07-01 16:00:00’, 6,66);
在102中写入分布式表的数据,在103,104,105查分布式表都能看到,但如果分别在102、103、105节点查询本地表test_ck_single_copy ,则会发现每个节点都有局部数据,组合起来就是所有的数据,验证了在此集群下写入分布式表为多分片写入。
103与104在同一分片下,在这两个节点上经查询发现看到的数据是一样的,说明Distributed分布式表在写入时除了写分片外,还会写分片下的所有副本。
多分片多副本ReplicatedMergeTree+distribute[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S7ZTA2dH-1657597822194)(uploadimage-20220708181721006.png)]
特点集群拥有多分片多副本,副本之间的同步使用zookeeper实现,写入不再通过distributed进行写入,而是通过负载均衡直接写入节点。
数据流向读:读请求通过负载均衡到达任意一个节点的分布式表distributed,distributed准备往每个分片发送请求,但由于每个分片都有副本,因此还需要从分片的副本中负载均衡算法选取合适的副本节点才可以发送查询请求,节点收到查询请求后直接查询本地表后返回数据给请求节点做合并。
写:写请求通过负载均衡到所属某个分片的节点直接写入本地表,然后该节点的本地表通过replicatedMergeTree副本同步机制同步到同个分片的其他所有副本中。
优缺点优点:
- 由于做了数据分片,没有冗余,数据存储能力增强了;副本做数据备份,因此可靠性也增加了。
- 由于做了数据分片,因此读请求时能充分利用分布式集群的计算性能,查询速度较快。
- 写入时不经过distributed,而是通过负载均衡直接写入指定分片的某节点,数据只写一份,因此写入速度相比上个方案提高了。
缺点:
-
引入了zookeeper,在超大数据量写入后,副本之间对写入的同步可能会存在问题。
-
负载均衡策略需要脱离clickhouse集群在客户端或者独立的负载均衡上实现。
在每个节点都执行配置文件重命名
mv /etc/clickhouse-server/config.d/metrika.xml.mergeTree /etc/clickhouse-server/config.d/metrika.xml
true 192.168.141.102 9000 default clickhouse true 192.168.141.103 9000 default clickhouse 192.168.141.104 9000 default clickhouse true 192.168.141.105 9000 default clickhouse 192.168.141.102 2181 shard-01 replica-01
其中机器ip与macros字段配置如下图所示:
192.168.141.102: shard=01, replica=01
192.168.141.103: shard=02, replica=01
192.168.141.104: shard=02, replica=02
192.168.141.105: shard=03, replica=02
由于此集群模式加入了zookeeper,因此可以使用分布式ddl来实现执行一次即可在集群中所有节点创建表:
CREATE TABLE test_ck_mergetree ON CLUSTER ck_cluster (EventDate DateTime, Number UInt32, id UInt32 ) ENGINE = ReplicatedMergeTree(‘/clickhouse/tables/{shard}/test_ck_mergetree’, ‘{replica}’) PARTITION BY toYYYYMM(EventDate) ORDER BY (Number, EventDate, intHash32(id)) SAMPLE BY intHash32(id);
创建分布式表CREATE TABLE distributed_test_mergetree ON CLUSTER ck_cluster (EventDate DateTime, Number UInt32, id UInt32 ) ENGINE = Distributed(ck_cluster, default, test_ck_mergetree , rand())
往各节点的本地表插入数据102节点:
insert into test_ck_mergetree values (‘2021-07-01 11:00:00’, 1,11);
insert into test_ck_mergetree values (‘2021-07-01 12:00:00’, 2,22);
103节点:
insert into test_ck_mergetree values (‘2021-07-01 13:00:00’, 3,33);
insert into test_ck_mergetree values (‘2021-07-01 14:00:00’, 4,44);
105节点:
insert into test_ck_mergetree values (‘2021-07-01 15:00:00’, 5,55);
insert into test_ck_mergetree values (‘2021-07-01 16:00:00’, 6,66);
在102,103,105本地表插入数据的自然就在本地了,这毋庸置疑。而在103插入的数据,由于使用了zookeeper来同步,因此在104查询本地表能看到与103一样的数据,说明同步成功了。
在任意一个节点查询分布式表distributed_test_mult_burst_copy,可以查到全部数据,说明查询没问题。
方案总结经过上述的比较,我们已经有所倾向于选择多分片多副本的模式,再综合读写性能比较,方案四是比较符合我们期望的,而方案四的第一个问题zookeeper目前ck已经开发了ck keeper,将来计划取代zookeeper以解决大数据量下集群性能问题,未来可通过迁移至ck keeper来解决此问题,而第二个问题,可通过自己实现客户端或引入chproxy进行负载均衡分片,在这里我们倾向使用chproxy来处理读写分发。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KvPz98rD-1657597822195)(uploadimage-20220708183823471.png)]
数据流向读:读请求通过chproxy负载均衡(策略为轮询+最小负载)到达四个节点中的任意一个节点的分布式表distributed,distributed准备往每个分片发送请求,但由于每个分片都有副本,因此还需要从分片的副本中负载均衡算法选取合适的副本节点才可以发送查询请求,节点收到查询请求后直接查询本地表后返回数据给请求节点做合并。
写:写请求通过负载均衡(策略为轮询+最小负载)到两台节点(每个分片一个节点)中直接写入本地表,然后该节点的本地表通过replicatedMergeTree副本同步机制同步到同个分片的其他所有副本中。
优缺点优点:
- chproxy会定期发送心跳检测ck节点,自动判断节点是否进行路由分发,节点状态可自动检测。
- chproxy内置多种负载均衡策略,还可以实现用户管理和限流管理,减少了自己开发客户端的成本,也满足使用要求。
- 继承了方案四的所有优点。
缺点:
- zookeeper的问题依然存在。
chproxy官网文档:https://www.chproxy.org/cn



