背景
ClickHouse节点之间互相访问,或者集成其它的关系型数据库,我们一般通过remote函数或者clickhouse-jdbc-bridge来实现,前期有介绍过clickhouse-jdbc-bridge实现机制存在性能问题,所以不建议使用。而使用remote函数又存在一些问题。今天无意间在官方上,看到分布式表引擎的介绍,感觉使用分布式表引擎来替代remote函数实现节点间通信,是一个非常好的解决方案。
Remote函数问题
使用remote函数存在一些问题:
1、DDL中包含远程机器的用户名密码,存在安全隐患。
2、存在单点问题,无负载均衡机制。
3、不适合数据量过大的数据访问,不适合处理大量请求。
官方给的remote函数适用场景:
- 一次性数据从一个系统迁移到另一个系统
- 访问特定服务器进行数据比较、调试和测试,即 ad-hoc 连接。
- 用于研究目的的各种 ClickHouse 集群之间的查询。
- 手动发出的不频繁的分布式请求。
- 每次都重新定义服务器集的分布式请求。
使用分布式表
1、配置分布式表服务
xx-cluster.xml配置文件,配置示例如下(来自官方):
<!-- 旧版本根节点为yandex,后续新版本统一修改为clickhouse -->
<yandex>
<remote_servers>
<!-- 集群名 -->
<xx-cluster>
<!-- 分布式查询的服务器间集群密码
默认值:无密码(将不执行身份验证)
如果设置了,那么分布式查询将在分片上验证,所以至少:
- 这样的集群应该存在于shard上
- 这样的集群应该有相同的密码。
而且(这是更重要的),initial_user将作为查询的当前用户使用。
-->
<!-- <secret></secret> -->
<shard>
<!-- 可选的。写数据时分片权重。 默认: 1. -->
<weight>1</weight>
<!-- 可选的。是否只将数据写入其中一个副本。默认值:false(将数据写入所有副本)。 -->
<internal_replication>false</internal_replication>
<replica>
<!-- 可选的。负载均衡副本的优先级,请参见(load_balancing 设置)。默认值:1(值越小优先级越高)。 -->
<priority>1</priority>
<host>example01-01-1</host>
<port>9000</port>
<!-- user.xml定义的用户名和密码 -->
<user>xxx_read</user>
<password>...</password>
</replica>
<replica>
<host>example01-01-2</host>
<port>9000</port>
<user>xxx_read</user>
<password>...</password>
</replica>
</shard>
<shard>
<weight>2</weight>
<internal_replication>false</internal_replication>
<replica>
<host>example01-02-1</host>
<port>9000</port>
<user>xxx_read</user>
<password>...</password>
</replica>
<replica>
<host>example01-02-2</host>
<secure>1</secure>
<port>9000</port>
<user>xxx_read</user>
<password>...</password>
</replica>
</shard>
</xx-cluster>
</remote_servers>
</yandex>
配置文件拷贝到/etc/clickhouse-server/config.d下,clickhouse会自动加载。可以通过查看system.cluster表来查看是否加载成功。
2、创建分布式表
由于我们只是使用分布式表来解决数据查询问题,所以建表语句较简单,没有配置相关参数。
CREATE TABLE dim_common_xxx
(
`name` Nullable(String),
`id` Nullable(Int64)
)ENGINE = Distributed(xx-cluster, database_name, table_name);
总结
无论在多分片还是单分片的场景,分布式表都能很好的替代Remote函数的使用。在clickhouse集群内数据互访的时候,推荐使用分布式表的解决方案。