一、数据副本
1.1 概述
只有使用了ReplicatedMergeTree复制表系列引擎,才能应用副本的能力;或者换言之,即使用ReplicatedMergeTree的数据表就是副本。

ReplicatedMergeTree时MergeTree的派生引擎,它在MergeTree的基础上加了分布式协同的能力,如图10-5所示。

在MergeTree中,一个数据分区由开始创建到全部完成,会经历两类存储区域:
1. 内存:数据首先会被写入内存缓冲区;
2. 本地磁盘:数据接着会被写入到tmp临时目录分区,待全部完成后再将临时目录重命名为正式分区。
ReplicatedMergeTree在上述基础之上增加了Zookeeper的部分,它会进一步在Zookeeper内创建一系列的监听节点,并以此实现多个实例之间的通信。在整个过程中,Zookeeper并不会涉及表数据的传输。
1.2 副本的特点
作为数据副本的主要实现载体,ReplicatedMergeTree在设计上有一些显著特点。
- 依赖Zookeeper:在执行INSERT和ALTER查询的时候,ReplicatedMergeTree需要借助Zookeeper的分布式协同能力,以实现多个副本之间的同步。但是在查询副本的时候,并不需要借助Zookeeper。
- 表级别的副本:副本是表级别定义的,所以每张表的副本配置都可以按照它的实际需求进行个性化定义,包括副本的数量,以及副本在集群内的分布位置等。
- 多主架构:可以在任意一个副本上执行INSERT和ALTER查询,它们的效果是相同的。这些操作会借助Zookeeper的协同能力被分发至每个副本以本地形式执行。
- Block数据块:在执行INSERT命令写入数据时,会依据max_insert_block_size的大小(默认1048576行)将数据切分成若干个Block数据块。所以Block数据块是数据写入的基本单元,并且具有写入的原子性和唯一性。
- 原子性:在数据写入时,一个Block块那的数据要么全部写入成功,要么全部失败。
- 唯一性:在写入一个Block数据块的时候,会按照当前Block数据块的顺序、数据行和数据大小等指标,计算Hash信息摘要并记录。在此之后,如果某个待写入的Block数据块与之前已被写入的Block数据块拥有相同的Hash摘要(Block数据块内数据顺序、数据大小和数据行均相同),则该Block数据块会被忽略。这项设计可以预防由异常原因引起的Block数据块重复写入的问题。
1.3 RepilcatedMergeTree原理解析
在ReplicatedMergeTree的核心逻辑中,大量运用了Zookeeper的能力,以实现多个ReplicatedMergeTree副本实例之间的协同,包括主副本选举、副本状态感知、操作日志分发、任务队列和BlockID去重判断等。在执行INSERT数据写入、MERGE分区、MUTATION操作(数据修改)、ALTER操作的时候,都会涉及与Zookeeper的通信。但是在通信过程中,并不会涉及任何表数据的传输,在查询数据的时候也不会访问Zookeeper,所以不必担心Zookeeper的承载能力。
首先,拟定一个演示场景,即使用ReplicatedMergeTree实现一张拥有1分片、1副本的数据表,并以次来贯穿整个讲解过程(对于大于1个副本的场景,流程以次类推)。
接着,通过对ReplicatedMergeTree分别执行INSERT、MERGE、MUTATION和ALTER操作,以此来讲解相应的工作原理。
1.3.1 INSERT的核心执行流程
当需要和ReplicatedMergeTree中执行INSERT查询以写入数据时,即会进入INSERT核心流程,其整体示意如图10-6所示。

-
创建第一个副本实例
假设首先从CH5节点开始,对CH5节点执行下面的语句后,会创建第一个副本实例:
CREATE TABLE replicated_sales_1( id String, price Float64, create_time DateTime ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/01/replicated_sales_1','ch5.nauu.com') PARTITION BY toYYYMM(create_time) ORDER BY id在创建过程中,ReplicatedMergeTree会进行一些初始化操作,例如:
- 根据zk_path初始化所有的Zookeeper节点。
- 在/replicas/节点下注册自己的副本实例ch5.nauu.com。
- 启动监听节点,监听/log日志节点。
- 参与副本选举,选举出主副本,选举的方式是向/leader_election/插入子节点,第一个插入成功的副本就是主副本。
-
创建第二个副本实例
接着,在CH6节点下执行下面的语句,创建第二个副本实例。表结构和zk_path需要与第一个副本相同,而replica_name则需要设置成CH6的域名:
CREATE TABLE replicated_sales_1( //相同结构

最低0.47元/天 解锁文章
7171

被折叠的 条评论
为什么被折叠?



