ClickHouse 中的所有MergeTree家族引擎前面加上Replicated就成了支持副本的合并树引擎.
本文以ReplicatedMergeTree引擎作为演示,其他副本合并树引擎是一个道理.
ReplicatedMergeTree如果有两个副本的话,相当于分布在两台clickhosue节点中的两个表,但是这个两个表具有协调功能,无论是哪个表执行insert或者alter操作,都会同步到另外一张表,这样子很好理解,副本就是相互同步数据的表.
复制合并树只有进行INSERT
或者ALTER
或者TRUNCATE
操作才会同步,DROP
,ATTACH
,DETACH
和 RENAME
只会作用于本地表(RENAME
说明表名可以不同)
复制合并树引擎需要借助zookeeper实现数据的同步,所以要使用它就必须要先配置zookeeper.
zookeeper要求3.4.5以及以上版本,zookeeper的下载与安装Zookeeper的下载与安装 clickhouse两种配置zookeeper方式,一种是直接在config.xml中配置,另外一种是在外部文件中配置好了,在config.xml中进行引用.
1 内部配置方式:
vim /etc/clickhouse-server/config.xml
添加如下配置:
<zookeeper>
<node index="1"> #index是连接zk的顺序
<host>node01</host> #znode地址
<port>2181</port> #znode端口
</node>
<node index="2">
<host>node02</host>
<port>2181</port>
</node>
<node index="3">
<host>node03</host>
<port>2181</port>
</node>
2 外部配置方式:
创建外部配置文件:
vim /etc/clickhouse-server/config.d/zks.xml
<?xml version="1.0"?>
<yandex>
<zks>
<node index="1">
<host>node01</host>
<port>2181</port>
</node>
<node index="2">
<host>node02</host>
<port>2181</port>
</node>
<node index="3">
<host>node03</host>
<port>2181</port>
</node>
</zks>
</yandex>
引入外部配置文件中的配置
vim /etc/clickhouse-server/config.xml
#文件的路径
<include_from>/etc/clickhouseserver/config.d/zks.xml</include_from>
#incl中指的是配置在外部配置文件中的标签
<zookeeper incl="zks" optional="true" />
上方是麻烦的写法,如果在zks中的标签<zks>...</zks>
改为<zookeeper>..</zookeeper>
,那么可以不要config.xml中的<zookeeper incl...>
标签,只需要引用外部配置文件即可.
zk的配置不支持热更改,必须要重启clickhouse服务,但是在重启之前可以先使用以下sql查询:
select * from system.zookeeper where path = '/';
会报表不存在.
重启服务后,再还执行上方sql,就可以查询到zookeeper表,说明zookeeper配置好了.
Replicated建表语句:
ENGINE = ReplicatedMergeTree('/clickhouse/tables/shard/table_name', 'replica')
除了上方,其他部分与MergeTree建表语句无异.
zookeeper路径/clickhouse/tables/shard/table_name
中/clickhouse/tables
为固定前缀(虽然可以不这样写,但是官网中建议这样做,所以我们就这样配置,减少不必要的麻烦)/shard
需要自己配置shard(分片)名称,table_name
指表的名称replica
代表副本的名称.
因为这里不做分片,所以我三台服务分别这样指定三个副本
(’/clickhouse/tables/01/table_name’, ‘node01’)
(’/clickhouse/tables/01/table_name’, ‘node02’)
(’/clickhouse/tables/01/table_name’, ‘node03’)
分别在三台服务上执行
create table replicatedTest(id Int16)
engine=ReplicatedMergeTree('/clickhouse/tables/01/replicatedTest','node01')
order by id;
create table replicatedTest(id Int16)
engine=ReplicatedMergeTree('/clickhouse/tables/01/replicatedTest','node02')
order by id;
create table replicatedTest(id Int16)
engine=ReplicatedMergeTree('/clickhouse/tables/01/replicatedTest','node03')
order by id;
创建好了以后在任意一台服务上执行:
insert into replicatedTest values(1);
之后三台分别查询,结果一致
select * from replicatedTest;
┌─id─┐
│ 1 │
└────┘
需要注意的是,如果在同一台服务上面执行两次一样i的insert,第二次执行会被忽略掉,这是为了防止因为异常导致的重试让一次数据多次写入.
上方创建表语句很麻烦是不是,需要分别到不同的机器上面执行不同的创建表语句,其实可以通过宏变量的方式来创建.
('/clickhouse/tables/{shard_name}/table_name','{replica_name}')
上方的{shard_name}与{replica_name}是对宏变量shard_name和replica_name的引用,每台服务器的配置文件中分别配置好这两个宏变量,那么每台服务需要执行的sql语句就编程一致的了.
分别在三台服务器上的config.xml中添加配置
<macros>
<shard_name>01</shard_name>
<replica>node01</replica>
</macros>
<macros>
<shard_name>01</shard_name>
<replica>node02</replica>
</macros>
<macros>
<shard_name>01</shard_name>
<replica>node03</replica>
</macros>
此配置支持热加载,所以不需要重启服务
之后每台服务上面都执行下面的sql语句就可以起到一样的效果:
create table replicatedTest1(id Int16)
engine=ReplicatedMergeTree('/clickhouse/tables/{shard_name}/replicatedTest1','{replica_name}')
order by id;
如果针对于其他的合并数引擎可能会有额外的参数,这里拿ReplacingMergeTree来说,它可以有一个选择保留版本的参数,对于ReplicatedReplacingMergeTree
来说,额外的参数就添加在后面,如:
engine=ReplicatedMergeTree('/clickhouse/tables/{shard_name}/replicatedTest1','{replica_name}',**score**)
其他有额外参数的MergeTree引擎也是一样,将参数添加.replica参数后面