Clickhouse复制表引擎ReplicatedMergeTree
概述
ReplicatedMergeTree
复制表引擎是MergeTree
的派生引擎,他在MergeTree
的基础上加入了分布式协同的能力
在MergeTree
中,一个数据分区由开始创建到全部完成,会经历两类存储区域
(1) 内存:数据首先会被写入内存缓冲区
(2) 本地磁盘:数据接着会被写入tmp临时目录分区,待全部完成后再将临时目录重新命名为正式分区
ReplicatedMergeTree
在上述基础上增加了Zookeeper
的部分,它会进一步在Zookeeper
内创建一系列的监听节点,并以此实现多个实例之间的通信。在整个通信过程中,Zookeeper
不会涉及表数据的传输
特点
-
依赖Zookeeper:在执行
INSERT
和ALTER
查询时,ReplicatedMergeTree
需要借助Zookeeper的分布式协同能力来实现多个副本之间的同步,但是在SELECT
查询时并不需要使用Zookeeper -
表级别的副本:副本是定义在表级别的,所以,服务器里可以同时有复制表和非复制表
-
多主架构(Multi Master):可以在任意一个副本上执行
INSERT
和ALTER
查询,他们的执行效果是相同的,这些操作会借助Zookeeper的协同能力被分发至每个副本 -
Block数据块:在执行
INSERT
命令写入数据时,会依据max_insert_block_size
的大小将数据切分成若干个Block数据块。Block数据块是数据写入的基本单元,并且具有写入的原子性和唯一性 -
原子性:在数据写入时,一个Block块内的数据要么全部写入成功,要么全部失败
-
唯一性:
数据块会去重。对于被多次写的相同数据块(大小相同且具有相同顺序的相同行的数据块),该块仅会写入一次。这样设计的原因是万一在网络故障时客户端应用程序不知道数据是否成功写入DB,此时可以简单地重复
INSERT
。把相同的数据发送给多个副本 INSERT 并不会有问题。因为这些INSERT
是完全相同的(会被去重)。去重参数参看服务器设置 merge_tree。(注意:Replicated*MergeTree 才会去重,不需要 zookeeper 的不带 MergeTree 不会去重)
ReplicatedMergeTree定义形式
在使用副本时,不需要依赖任何集群配置,ReplicatedMergeTree的定义如下
ENGINE = ReplicatedMergeTree('zk_path', 'replica_name')
其中zk_path
用于指定在Zookeeper
中创建的数据表的路径,该路径是自定义的,但是Clickhouse提供了一些约定俗成的配置模板,如
/clickhouse/tables/{ shard }/table_name
其中
-
/clickhouse/tables
是约定俗成的固定前缀,表示存放表数据的根路径 -
{shard}
表示分片号,通常用数值代替,如01,02,03。一张数据表可以有多个分片,每个分片都拥有自己的副本 -
tablename
表示数据表的名称,官方建议该名称与物理表应相同table_name
是该表在 ZooKeeper 中的名称。使其与 ClickHouse 中的表名相同比较好。 这里它被明确定义,跟 ClickHouse 表名不一样,它并不会被 RENAME 语句修改
replica_name
表示在Zookeeper中该表的副本名称
对于zk_path
而言,同一张数据表的同一个分片的不同副本,应定义相同的路径
对于replica_name
而言,同一张数据表的同一个分片的不同副本,应定义不同的名称
如
-- 单分片 单副本 zk_path相同 replica_name不同
ReplicatedMergeTree('/clickhouse/tables/01/test_1', 'replica01')
ReplicatedMergeTree('/clickhouse/tables/01/test_1', 'replica02')
-- 2分片 单副本
-- 分片01 zk_path相同 shard为01 replica_name不同
ReplicatedMergeTree('/clickhouse/tables/01/test_1', 'replica01')
ReplicatedMergeTree('/clickhouse/tables/01/test_1', 'replica01')
-- 分片02 zk_path相同 shard为02 replica_name不同
ReplicatedMergeTree('/clickhouse/tables/02/test_1', 'replica03')
ReplicatedMergeTree('/clickhouse/tables/02/test_1', 'replica04')
单分片单副本集群搭建
Clickhouse配置
开放外网访问
编辑Clickhouse全局配置文件,找到<listen_host>::</listen_host>
并将其注释放开
vi /etc/clickhouse-server/config.xml
配置副本同步IP
在Clickhouse全局配置文件中找到<interserver_http_host>
,将其更改为本机IP
<interserver_http_host>xx.xx.xx.xx</interserver_http_host>
编辑完毕后按Esc并输入:wq!
保存
Zookeeper集群搭建
添加Zookeeper配置
在服务器中进入/etc/clickhouse-server/config.d
目录并在该位置新建名为metrika.xml
的配置文件
cd /etc/clickhouse-server/config.d/
vi metrika.xml
<?xml version="1.0"?>
<yandex>
<zookeeper-servers> <!-- 节点名称 可以自定义 -->
<node index="1">
<host>ZooKeeper ip</host>
<port>Zookeeper port</port>
</node>
<node index="2">
<host>xx.xx.xx.xx</host>
<port>2181</port>
</node>
</zookeeper-servers>
</yandex>
编辑完毕后按Esc并输入:wq!
保存
接着在Clickhouse全局配置文件中引入新建的配置文件,并引入Zookeeper配置的定义
vim /etc/clickhouse-server/config.xml
<include_from>/etc/clickhouse-server/config.d/metrika.xml</include_from><zookeeper incl="zookeeper-servers" optional="false" />
其中,incl
应与metrika.xml
中定义的节点名称一致
修改完毕后按Esc并输入:wq!
保存
以上操作需要在Clickhouse集群中的所有机器上配置
Clickhouse全局配置文件修改后,需要重启Clickhouse服务使其生效
复制表只会同步数据,并不会同步表结构,所以需要在所有机器上创建复制表,创建完毕后在任意一台机器上尝试INSERT
操作,查看插入结果,若其他机器能够查询到插入信息,则复制表搭建完成
错误记录
clickhouse日志
tail -f /var/log/clickhouse-server/clickhouse-server.log
插入时报错Table is in readonly mode
如果服务器启动时 ZooKeeper 不可用,则复制表会切换为只读模式。系统会定期尝试去连接 ZooKeeper。
如果在
INSERT
期间 ZooKeeper 不可用,或者在与 ZooKeeper 交互时发生错误,则抛出异常。
查看Zookeeper集群是否搭建完成,在Zookeeper集群启动时尝试重启Clickhouse服务
若依旧存在问题,查看Zookeeper配置是否存在问题
插入数据不同步
查看Clickhouse日志,若出现报错 no interserver io endpoint named datapartsexchange
,检查Clickhouse全局配置中的interserver_http_host
是否配置或出现问题,以及interserver_port
是否正在监听或是否被防火墙拦截,注意interserver_http_host
配置完毕后放开包围他的注释
评论