简介
在生产环境使用ClikcHouse必须考虑高性能、高可用
本文演示如何配置使用复制表和分布式表
1.通过负载均衡策略(轮询、hash等)将数据写入到多个分片的Buffer引擎中
2.Buffer引擎按照设定的触发条件将数据同步到ReplicatedMergeTree引擎中
3.同一分片中,副本直接会同步ReplicatedMergeTree引擎数据
4.只需查询任意分片中Distributed引擎,即可获取整个集群所有数据
准备2台已安装ClickHouse的服务器
node1 172.16.101.134
node2 172.16.101.130
修改配置文件/etc/clickhouse-server/config.xml
,设置可以远程连接
<listen_host>::</listen_host>
高可用
Replicated系列引擎,比如ReplicatedMergeTree 提供数据备份,防止数据丢失
高性能
Distributed引擎
数据分片保存在多台服务上,在查询时先在多台服务处理数据再聚合
Replicated系列引擎
修改配置文件
vim /etc/clickhouse-server/config.xml
添加zookeeper信息
<zookeeper>
<node index="1">
<host>jiao.com</host>
<port>2181</port>
</node>
<node index="2">
<host>jiao.com</host>
<port>2182</port>
</node>
<node index="3">
<host>jiao.com</host>
<port>2183</port>
</node>
</zookeeper>
定义1分片1副本
<test_shard_localhost>
<shard>
<replica>
<host>172.16.101.134</host>
<port>9000</port>
</replica>
<replica>
<host>172.16.101.130</host>
<port>9000</port>
</replica>
</shard>
</test_shard_localhost>
创建表
1.在任意节点创建表/新增数据,另一个节点将会通过zookeeper
进行数据同步
clickhouse/tables/01/replicated_sales_3 zookeeper
路径{replica}
宏定义,会引用配置文件中replica下面的host
create table test.replicated_sales_3 on cluster test_shard_localhost(
id String,
prince Float64,
create_time DateTime
) engine = ReplicatedMergeTree('clickhouse/tables/01/replicated_sales_3', '{replica}')
partition by toYYYYMM(create_time)
order by id;
插入数据
在node1插上数据
insert into test.replicated_sales_3 values ('A001', 100, '2020-09-15 15:30:00');
在node2
查询,发现数据已经同步过来了
在node2
插入数据同样会同步到node1
数据同步核心流程
查看zookeeper信息
可安装zk-web查看
也可通过命令查看
select * from system.zookeeper where path='clickhouse/tables/01/replicated_sales_3';
Distributed引擎
修改配置文件
定义2分片0副本
<test_cluster_two_shards_localhost>
<shard>
<replica>
<host>172.16.101.134</host>
<port>9000</port>
</replica>
</shard>
<shard>
<replica>
<host>172.16.101.130</host>
<port>9000</port>
</replica>
</shard>
</test_cluster_two_shards_localhost>
创建表
1.创建Distributed
表
Distributed
表不存储数据
插入时会将数据路由到本地表
查询时会将现在本地表处理时间再聚合到一起进行处理
test_cluster_two_shards_localhost
是在config.xml
定义的集群名称test
是数据库名称test_shard_2_local
是本地表名称
负载均衡算法rand
: ck拥有一个全局计数器errors_count,当服务发送任何异常时,该计数累计1,randmo算法会选择errors_count错误数量最少的replica,如果多个replica计数相同,则随机选一个nearest_hostname
: 选择errors_count最少的replica,若errors_count相同,则选择集群中host名称和当前host最相似的,相似规则按字节逐位比较,找出不同字节数最少的一个
CH2-1-1
Ch2-1-2
有一个字节不同in_order
: 选择errors_count最少的replica,若errors_count相同,则安集群配置文件中replica定义的顺序选择first_or_randmo
: 选择errors_count最少的replica,若errors_count相同,则安集群配置文件中replica定义的顺序选择,若该replica不可用,则进一步随机选择一个其他的replica
create table test.test_shard_2_all on cluster test_cluster_two_shards_localhost(
id UInt32,
name String
)ENGINE Distributed(test_cluster_two_shards_localhost, test, test_shard_2_local, rand());
2.创建本地表
create table test.test_shard_2_local on cluster test_cluster_two_shards_localhost(
id UInt32,
name String
)ENGINE = MergeTree() order by id PARTITION BY id;
插入数据
插入数据,数据随机插入到node1/node2
的本地表test_shard_2_local
insert into test.test_shard_2_all values (1, 'xiaoli'),(2, 'xiaoli')(3, 'xiaoli');
删除表命令也要带上on cluster
drop table test.test_shard_2_all on cluster test_cluster_two_shards_localhost;
多分片查询流程
当执行select * from test.test_shard_2_all
时
1.在本地和远端分片执行查询
select * from test.test_shard_2_local
2.合并返回结果
但若执行
select uniq(id) from test_shard_2_all where name='xiaoli' and id in (select id from test_shared_2_all where name = 'xiaomi')
test_shared_2_all会被拆解成本地表,in自查询中test_shared_2_all也成被拆解成本地表,造成查询放大,性能大受影响
使用GLOBAL优化查询
select uniq(id) from test_shard_2_all where name='xiaoli' and GLOBAL id in (select id from test_shared_2_all where name = 'xiaomi')
1.将in字句单独提出,发起一次分布式查询,将结果汇总保存到内存临时表中
2.将内存表发送个各个远端节点
3.执行完整sql
注意内存临时表数据量不能太大
参考
《ClickHouse原理解析与应用实践》