在使用副本功能的时候,我们往往需要手动在每个节点创建
ReplicatedMergeTree,或者利用 CREATE xx ON CLUSTER 语法自动的在集群内创建。
但是当集群中增加了新节点的时候,ClickHouse 并不会在新节点上自动的创建 ReplicatedMergeTree,这样十分的不方便,好在这个问题现在有了新解。
在新版本的 ClickHouse 中,多了一个名为 Replicated 的 Database Engine 类型。注意,是数据库的引擎,不是表引擎哦。
该类型的数据库在创建的时候,需要指定3个参数,分别是 Zookeeper上的 path、shard 名称和 replica 名称。例如:
代码语言:javascript复制CREATE DATABASE test_r ENGINE=Replicated('/clickhouse/dbs/test_r','01','ch9.nauu.com')
在不同的 ClickHouse 服务器节点上,拥有相同 Zookeeper path 的 Replicated Database,会自动同步创建 ReplicatedMergeTree
接下来用一个示例来演示 Replicated Database 如何工作。要使用这项功能,首先要在配置中将其开启,在 user.xml 中增加:
代码语言:javascript复制<allow_experimental_database_replicated>1</allow_experimental_database_replicated>
在第一个节点创建 Replicated Database:
代码语言:javascript复制ch9.nauu.com :) CREATE DATABASE test_r ENGINE=Replicated('/clickhouse/dbs/test_r','01','ch9.nauu.com')
查询 Zookeeper,会发现其同步原理和 ReplicatedMergeTree 一样,都是利用监听指定 path 下的 log 实现的:
代码语言:javascript复制SELECT
name,
value
FROM system.zookeeper AS z
WHERE path = '/clickhouse/dbs/test_r'
Query id: 5661cf11-2020-47e0-b154-5f3b239246a7
┌─name─────────┬─value─┐
│ replicas │ │
│ max_log_ptr │ 1 │
│ counter │ │
│ logs_to_keep │ 1000 │
│ log │ │
│ metadata │ │
└──────────────┴───────┘
接着在 test_r 数据库下,创建 ReplicatedMergeTree :
代码语言:javascript复制CREATE TABLE test_r.rmt (n UInt64)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/rmt','{replica}') ORDER BY n;
注意,如果是在 Replicated Database 下,创建 ReplicatedMergeTree ,且 ReplicatedMergeTree 明确指定了 Zookeeper path,则 shard 和 replica 必须使用 macros 宏,否则会得到如下错误:
代码语言:javascript复制Explicit zookeeper_path and replica_name are specified in ReplicatedMergeTree arguments. "
"If you really want to specify it explicitly, then you should use some macros "
"
现在去另外一个 ClickHouse 节点,创建相同 Zookeeper path 的 Replicated Database:
代码语言:javascript复制ch10.nauu.com :) CREATE DATABASE test_r ENGINE=Replicated('/clickhouse/dbs/test_r','01','ch10.nauu.com')
CREATE DATABASE test_r
ENGINE = Replicated('/clickhouse/dbs/test_r', '01', 'ch10.nauu.com')
Query id: fbfc30e7-460a-4552-95ef-ed9798ab1e83
Ok.
0 rows in set. Elapsed: 0.006 sec.
会发现 test_r.rmt 已经在第二个节点自动被创建了:
代码语言:javascript复制ch10.nauu.com :) select count() from test_r.tb1
SELECT count()
FROM test_r.tb1
Query id: 1cc512a2-ec9f-443e-82aa-77838320d070
┌─count()─┐
│ 0 │
└─────────┘
这招学到了吗? 是不是比以前方便了很多?