ClickHouse 实战笔记 第04期:ClickHouse 高可用集群搭建

2022-04-25 08:52:35 浏览数 (1)

作者简介

马听,多年 DBA 实战经验,对 MySQL、 Redis、ClickHouse 等数据库有一定了解,专栏《一线数据库工程师带你深入理解 MySQL》、《Redis 运维实战》作者。

在海量数据的场景下,单节点的 CH 可能不能满足我们的需求了,因此可以考虑使用 CH 集群,从而解决单节点存储和查询的瓶颈。

这一节就来聊聊 CH 集群的部署。

实验环境

  • CentOS 7.4
  • ClickHouse 20.7.2.30

首先来看下本节内容大致的架构:

如上图,整个集群一共 4 个节点,分为两个分片,每个分片一个副本。除了在每个节点创建 ReplicatedMergeTree 表,还会创建 Distributed 引擎的总表(建表方式在本文后面会讲解),各个节点上的本地表代理,写入、查询、分发等操作都经过分布式总表路由。

1 安装 zk

由于 ReplicatedMergeTree 引擎依赖 zk,有数据写入或者修改时,就借助 zk 的分布式协同能力,实现多个副本之间的同步。因此需要安装 zk。

ZooKeeper 安装参考:https://zookeeper.apache.org/doc/r3.4.14/zookeeperStarted.html

2 安装 ClickHouse

4 台机器都先安装好单机版 ClickHouse,ClickHouse 单机版安装参考:https://clickhouse.tech/docs/zh/getting-started/install/。

编辑配置文件

代码语言:javascript复制
vim /etc/clickhouse-server/config.xml

去掉下面这行的注释

代码语言:javascript复制
<listen_host>::</listen_host>

3 增加集群配置文件

代码语言:javascript复制
vim /etc/clickhouse-server/config.d/metrika.xml

加入如下内容:

代码语言:javascript复制
<?xml version="1.0"?>

<yandex>
  <zookeeper-servers>
    <node index="1">
      <host>192.168.150.232</host>
      <port>2181</port>
    </node>
  </zookeeper-servers>


<clickhouse_remote_servers>
  <!-- 2分片1副本 -->
  <cluster_test>
    <!-- 数据分片1 -->
    <shard>
      <weight>1</weight>
      <!-- Optional. Whether to write data to just one of the replicas. Default: false (write data to all replicas). -->
      <internal_replication>true</internal_replication>
      <replica>
        <host>192.168.150.232</host>
        <port>9000</port>
      </replica>
      <replica>
         <host>192.168.150.253</host>
         <port>9000</port>
      </replica>

    </shard>
    <!-- 数据分片2 -->
    <shard>
      <weight>1</weight>
      <internal_replication>true</internal_replication>
      <replica>
        <host>192.168.150.123</host>
        <port>9000</port>
      </replica>
      <replica>
        <host>192.168.21.126</host>
        <port>9000</port>
      </replica>

    </shard>
  </cluster_test>

</clickhouse_remote_servers>


<macros>
  <cluster>cluster_test</cluster>
  <shard>01</shard>
  <replica>replica01</replica>
</macros>

</yandex>

注意修改 zk 以及各个节点的信息。

其中 192.168.150.232 和 192.168.150.253 为分片 01 的两个副本;192.168.150.123 和 192.168.21.126 为分片 02 的两个副本。

4 台机器除了下面这一段需要修改成对应的 shard 和 replica,其他都一样。

代码语言:javascript复制
<macros>
<cluster>cluster_test</cluster>
<shard>01</shard>
<replica>replica01</replica>
</macros>

4 修改 ClickHouse 主配置文件

代码语言:javascript复制
vim /etc/clickhouse-server/config.xml

增加

代码语言:javascript复制
<include_from>/etc/clickhouse-server/config.d/metrika.xml</include_from> 

<zookeeper incl="zookeeper-servers" optional="false" />

启动服务

代码语言:javascript复制
/etc/init.d/clickhouse-server start

5 查看集群信息

随便选择一个节点,登录 ClickHouse

代码语言:javascript复制
clickhouse-client

然后查看集群信息

代码语言:javascript复制
select * from system.clusters;

6 创建本地表

先解释一下 ReplicatedMergeTree 引擎用法:

代码语言:javascript复制
ENGINE = ReplicatedMergeTree('zk_path', 'replica_name')

zk_path 用于指定在 zk 中创建数据表的路径,一般 zk_path 建议配置成如下形式:

代码语言:javascript复制
/clickhouse/{cluster}/{shard}/{table_name}
  • {cluster} 表示集群名;
  • {shard} 表示分片编号;
  • {table_name} 表示数据表的名称。

replica_name 的定义,需要注意的是同一分片不同副本,需要定义不同的名称;

而 zk_path 的定义,需要注意的是同一分片不同副本,需要定义相同的路径。

上面两句话如果感觉有点绕,可以对比下面这 4 个节点的本地表建表语句,应该就可以理解啦。

在 192.168.150.232 上:

代码语言:javascript复制
CREATE DATABASE likecolumn; 

CREATE TABLE likecolumn.table_test ( label_id UInt32, label_name String, insert_time Date) ENGINE = ReplicatedMergeTree('/clickhouse/cluster_test/01/table_test','replica01',insert_time, (label_id, insert_time), 8192)

在 192.168.150.253 上:

代码语言:javascript复制
CREATE DATABASE likecolumn; 

CREATE TABLE likecolumn.table_test ( label_id UInt32, label_name String, insert_time Date) ENGINE = ReplicatedMergeTree('/clickhouse/cluster_test/01/table_test','replica02',insert_time, (label_id, insert_time), 8192)

在 192.168.150.123 上:

代码语言:javascript复制
CREATE DATABASE likecolumn;

CREATE TABLE likecolumn.table_test ( label_id UInt32, label_name String, insert_time Date) ENGINE = ReplicatedMergeTree('/clickhouse/cluster_test/02/table_test','replica01',insert_time, (label_id, insert_time), 8192)

在 192.168.21.126 上:

代码语言:javascript复制
CREATE DATABASE likecolumn;

CREATE TABLE likecolumn.table_test ( label_id UInt32, label_name String, insert_time Date) ENGINE = ReplicatedMergeTree('/clickhouse/cluster_test/02/table_test','replica02',insert_time, (label_id, insert_time), 8192)

7 创建分布式总表

任选一个集群内的节点创建分布式总表:

代码语言:javascript复制
CREATE TABLE likecolumn.table_test_all AS likecolumn.table_test ENGINE = Distributed(cluster_test, likecolumn, table_test, rand())

这里解释一下 Distributed 引擎用法: ENGINE = Distributed(cluster, database, table, sharding_key)

  • cluster:集群名
  • database 和 table:库表名
  • sharding_key:分片键,选填。

8 数据测试

在创建了分布式总表的节点写入数据:

代码语言:javascript复制
insert into likecolumn.table_test_all values (1,'111','2020-11-17');
insert into likecolumn.table_test_all values (2,'111','2019-11-18');
insert into likecolumn.table_test_all values (3,'111','2020-11-19');
insert into likecolumn.table_test_all values (4,'111','2020-11-20');

查询总表数据

代码语言:javascript复制
select * from likecolumn.table_test_all ;

查询各个分片本地表的数据。

代码语言:javascript复制
select * from likecolumn.table_test ;

01 分片两个节点的数据如下:

02 分片两个节点的数据如下:

9 高可用测试

停掉 192.168.150.123 的 ClickHouse 服务:

代码语言:javascript复制
/etc/init.d/clickhouse-server stop

发现整个集群仍然可以正常写入和查询:

0 人点赞