ClickHouse 分片与副本

一、数据副本

1.1 概述

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

image-20240824163701854

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

image-20240824163824290

​ 在MergeTree中,一个数据分区由开始创建到全部完成,会经历两类存储区域:

​ 1. 内存:数据首先会被写入内存缓冲区;

​ 2. 本地磁盘:数据接着会被写入到tmp临时目录分区,待全部完成后再将临时目录重命名为正式分区。

​ ReplicatedMergeTree在上述基础之上增加了Zookeeper的部分,它会进一步在Zookeeper内创建一系列的监听节点,并以此实现多个实例之间的通信。在整个过程中,Zookeeper并不会涉及表数据的传输。

1.2 副本的特点

​ 作为数据副本的主要实现载体,ReplicatedMergeTree在设计上有一些显著特点。

  • 依赖Zookeeper:在执行INSERTALTER查询的时候,ReplicatedMergeTree需要借助Zookeeper的分布式协同能力,以实现多个副本之间的同步。但是在查询副本的时候,并不需要借助Zookeeper
  • 表级别的副本:副本是表级别定义的,所以每张表的副本配置都可以按照它的实际需求进行个性化定义,包括副本的数量,以及副本在集群内的分布位置等。
  • 多主架构:可以在任意一个副本上执行INSERTALTER查询,它们的效果是相同的。这些操作会借助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所示。

image-20240824174547626

  1. 创建第一个副本实例

    假设首先从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/插入子节点,第一个插入成功的副本就是主副本。
  2. 创建第二个副本实例

    接着,在CH6节点下执行下面的语句,创建第二个副本实例。表结构和zk_path需要与第一个副本相同,而replica_name则需要设置成CH6的域名:

    CREATE TABLE replicated_sales_1(
    //相同结构
    
### 如何在 ClickHouse 中设置 3 分片 2 副本架构 #### 创建集群配置文件 为了实现3分片2副本的结构,在`config.xml`或通过环境变量定义的配置文件中指定集群参数。具体来说,对于每一个ClickHouse服务器实例都需要有对应的配置来指明其所在的分片(shard)以及该分片内的副本(replica),如下所示: ```xml <remote_servers> <three_shards_two_replicas> <!-- 定义集群名称 --> <shard> <!-- 第一分片 --> <replica> <host>120.xxx.xxx.49</host> <port>9000</port> </replica> <replica> <host>120.xx.xxx.202</host> <port>9000</port> </replica> </shard> <shard> <!-- 第二分片 --> <replica> <host>其他IP地址</host> <port>9000</port> </replica> <replica> <host>其他IP地址</host> <port>9000</port> </replica> </shard> <shard> <!-- 第三分片 --> <replica> <host>其他IP地址</host> <port>9000</port> </replica> <replica> <host>其他IP地址</host> <port>9000</port> </replica> </shard> </three_shards_two_replicas> </remote_servers> ``` 上述XML片段展示了如何为三个不同的分片各自分配两个副本[^1]。 #### 数据库表引擎的选择 当创建分布式表时,应选择适合于多分片和多副本场景下的MergeTree族中的一个作为存储引擎,并且要特别注意使用Distributed引擎来指向之前所定义好的集群名——在这个例子中就是`three_shards_two_replicas`: ```sql CREATE TABLE my_table ON CLUSTER '{cluster}' ( `id` UInt64, ... ) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/hits', '{replica}') ORDER BY id; ``` 这里假设已经有一个名为`{cluster}`的宏被用来代替实际的集群名字;而`ReplicatedMergeTree`则用于确保数据的一致性和高可用性[^3]。 #### 准备工作节点 根据提供的机器列表,除了已有的两台运行着ClickHouse服务的主机外,还需要额外准备四台设备以满足总共六个节点的需求(每一对分片对应一台主服务器加一台备份)。这些新增设的服务端同样需要按照官方文档指导完成软件包安装、目录结构调整等一系列前期准备工作[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值