ClickHouse学习笔记之分片集群

文章目录

  • 介绍
  • 集群写入流程
  • 集群读取流程
  • 配置集群
  • 使用集群

介绍

副本虽然可以提高数据的可用性,但每台服务器必须容纳全量数据,没有支持数据的横向扩容。要解决数据水平切分问题,需要引入分片的概念,通过分片把一份完整的数据进行切分,不同的分片分布到不同的节点上,再通过Distributed分布表引擎把数据拼接起来使用。
分布引擎本身不存储数据,而是通过分布式逻辑进行不同分片的分布式数据的写入、分发和路由。
因为ClickHouse的集群是表级别的,所以实际企业大部分做了高可用,但没有分片,以避免降低查询性能和操作集群的复杂度。

集群写入流程

以3分片,每个分片2个副本,共6个结点为例:
ClickHouse学习笔记之分片集群_第1张图片
绿色表示打开分片内部复制的情况,黄色表示关闭分片内部复制的情况。打开分片内部复制时,客户端向分布式表distribute hdp1发送写命令,distribute hdp1只会向三个切片的一个副本写入数据,上图中即为hdp1 s1r1hdp3 s2r3hdp5 s3r5,而后每个副本向该切片的另一个副本再写入数据,即hdp1 s1r1hdp2 s1r2hdp3 s2r3hdp4 s2r4hdp5 s3r5hdp6 s3r6写入数据。关闭分片内部复制时,distribute hdp1就得自己向所有副本写入数据。

集群读取流程

以3分片,每个分片2个副本,共6个结点为例:
ClickHouse学习笔记之分片集群_第2张图片
当客户端向分布表发送读命令时,分布表向每个分片预读取数据,并计算错误数errors_count,优先选择分片内错误数小的副本数据,如果存在多个拥有最小错误数的副本,则通过随机、顺序、第一顺位优先或host名称近似四种方式之一选择其中一个副本的数据,最后将每个分片的数据进行拼接,作为最终的读取结果返回给客户端。

配置集群

进入/etc/clickhouse-server目录

[root@scentos szc]# cd /etc/clickhouse-server
[root@scentos clickhouse-server]#

修改config.xml文件

[root@scentos clickhouse-server]# vim config.xml

标签修改成如下内容:

     <remote_servers>
       <szc_cluster>
         <shard>
           <internal_replication>trueinternal_replication>
           <replica>
             <host>scentoshost>
             <port>9000port>
           replica>
         shard>
       szc_cluster>
     remote_servers>

为集群名称,为分片,表示是否打开分片内部复制,为分片副本,分片内部可以配置多个副本,集群内部可以配置多个分片,但每个分片的副本数不用一样。
然后打开标签的注释,配置当前机器的分片id和副本id:

     <macros>
         <shard>01shard>
         <replica>rep_01_1replica>
     macros>

最后重启ClickHouse:

[root@scentos clickhouse-server]# systemctl restart clickhouse-server

使用集群

首先通过副本合并树创建数据表:

create table st_order_mt on cluster szc_cluster (
id UInt32,
sku_id String,
total_amount Decimal(16,2),
create_time Datetime
) engine
=ReplicatedMergeTree('/clickhouse/tables/01/st_order_mt','rep_01_1')
partition by toYYYYMMDD(create_time)
primary key (id)
order by (id,sku_id);

szc_cluster为使用的集群名称,ReplicatedMergeTree('/clickhouse/tables/01/st_order_mt','rep_01_1')中的参数含义如下:

  1. /clickhouse/tables/01/st_order_mt/clickhouse/tables固定,01为建表的分片id,st_order_mt为表名;
  2. rep_01_1为建表的副本ID

在某个副本建表后,所有分片的所有副本都会拥有这张表。
执行结果如下图所示:
ClickHouse学习笔记之分片集群_第3张图片
然后创建分布式表:

create table st_order_mt_all2 on cluster szc_cluster
(
id UInt32,
sku_id String,
total_amount Decimal(16,2),
create_time Datetime
)engine = Distributed(szc_cluster,default, st_order_mt,hiveHash(sku_id));

szc_cluster为集群名称,Distributed(szc_cluster,default, st_order_mt,hiveHash(sku_id)中参数含义如下:

  1. szc_cluster表示使用的集群名称;
  2. default表示使用的数据库名称;
  3. st_order_mt表示该分布式表控制的表名称;
  4. hiveHash(sku_id)表示分片方法,即通过计算sku_id的哈希值来确定数据所属的分片。

执行结果如下图所示:
ClickHouse学习笔记之分片集群_第4张图片
然后我们可以通过分布式表st_order_mt_all2插入数据:

insert into st_order_mt_all values
           (201,'sku_001',1000.00,'2020-06-01 12:00:00') ,
           (202,'sku_002',2000.00,'2020-06-01 12:00:00'),
           (203,'sku_004',2500.00,'2020-06-01 12:00:00'),
           (204,'sku_002',2000.00,'2020-06-01 12:00:00'),
           (205,'sku_003',600.00,'2020-06-02 12:00:00');

也可以通过分布式表st_order_mt_all2查询数据:
ClickHouse学习笔记之分片集群_第5张图片
数据表和分布式表存在于集群中所有结点上,如果我们读写数据表,就只能读写结点所在分片的数据,不能读写跨分片结点的数据,因此集群模式下,我们必须通过分布式表进行全局的跨分片读写。

你可能感兴趣的:(clickhouse)