Clickhouse冷热数据分离实践

俊达1年前技术文章1469

配置多卷存储策略

使用Clickhouse的存储策略功能,可以实现冷热数据分离存储。


我们可以将业务上访问频繁的数据放到热存储区(如高性能SSD磁盘),将业务上较少访问的数据放在冷存储区(如价格更便宜、空间更大的磁盘上,Clickhouse还支持挂着S3协议的存储)。


本文将详细介绍具体的配置方法:

1、配置磁盘

2、配置存储策略

3、指定表的存储策略


1、配置磁盘

配置默认磁盘

默认磁盘路径在标签<clickhouse><path></path></clickhouse>下配置:

<clickhouse>
    <path>/data/clickhouse/clickhouse/</path>
</clickhouse>


这个配置可以放在主配置文件config.xml中,也可以放在config.d目录下的某个文件中。


在clickhouse的系统表system.disks中,可以看到当前实例默认磁盘的存储路径,以及空间使用情况。

ck01 :) select * from system.disks;

SELECT *
FROM system.disks

Query id: d27a898b-6d6f-4322-b491-f80f5eeee922

┌─name────┬─path─────────────────────────┬──free_space─┬──total_space─┬─keep_free_space─┬─type──┬─cache_path─┐
│ default │ /data/clickhouse/clickhouse/ │ 66161168384 │ 103240073216 │               0 │ local │            │
└─────────┴──────────────────────────────┴─────────────┴──────────────┴─────────────────┴───────┴────────────┘

1 row in set. Elapsed: 0.036 sec.


配置额外的磁盘

额外的磁盘需要在<storage_configuration>标签下配置:

<clickhouse>
  <storage_configuration>
    <disks>
       <default> </default>
       <disk2>
         <path>/data2/</path>
       </disk2>
    </disks>
  </storage_configuration>
</clickhouse>

disks配置有几点需要注意

  • 路径要以/结尾

  • 磁盘的名称和路径不能重复,也不能和默认磁盘的路径重复。否则会导致clickhouse启动失败



2、配置存储策略

需要配置存储策略,才能使用新添加的磁盘。

我们可以在系统表system.storage_policies表里查到当前的策略:

ck01 :) select * from system.storage_policies;

SELECT *
FROM system.storage_policies

Query id: 7674ae4d-b4b2-49fe-98be-117c39e7f519

┌─policy_name─┬─volume_name─┬─volume_priority─┬─disks───────┬─volume_type─┬─max_data_part_size─┬─move_factor─┬─prefer_not_to_merge─┐
│ default     │ default     │               1 │ ['default'] │ JBOD        │                  0 │           0 │                   0 │
└─────────────┴─────────────┴─────────────────┴─────────────┴─────────────┴────────────────────┴─────────────┴─────────────────────┘


默认情况下有一条default策略:所有的数据都写入到default磁盘中。


配置存储策略:

<clickhouse>
  <storage_configuration>
    <disks>
       <default> </default>
       <disk2>
         <path>/data2/</path>
       </disk2>
    </disks>

    <policies>
        <from_default_to_disk2>
            <volumes>
                   <vol_default>
                      <disk>default</disk>
                      <max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
                      <load_balancing>round_robin</load_balancing>
                   </vol_default>
                   <vol_disk2>
                      <disk>disk2</disk>
                   </vol_disk2>
            </volumes>
            <move_factor>0.2</move_factor>
        </from_default_to_disk2>
    </policies>
  </storage_configuration>
</clickhouse>


配置后,可以到配置表中确认配置信息

ck01 :) select * from system.storage_policies;

SELECT *
FROM system.storage_policies

Query id: d3143ebb-14f9-4836-be16-7a5ab11a52a5

┌─policy_name───────────┬─volume_name─┬─volume_priority─┬─disks───────┬─volume_type─┬─max_data_part_size─┬─move_factor─┬─prefer_not_to_merge─┐
│ default               │ default     │               1 │ ['default'] │ JBOD        │                  0 │           0 │                   0 │
│ from_default_to_disk2 │ vol_default │               1 │ ['default'] │ JBOD        │         1073741824 │         0.2 │                   0 │
│ from_default_to_disk2 │ vol_disk2   │               2 │ ['disk2']   │ JBOD        │                  0 │         0.2 │                   0 │
└───────────────────────┴─────────────┴─────────────────┴─────────────┴─────────────┴────────────────────┴─────────────┴─────────────────────┘


在上面的例子中,我们配置了一个存储策略:

1、包含了2个卷(volume)。数据默认写入到default磁盘。

2、move factor设置为0.2。当default磁盘空间小于20%时,将数据迁移到磁盘data2。

3、默认卷max_data_part_size_bytes设置为1G,大于1G的part数据,不会写入到默认卷。



写入数据时,会根据策略下定义的卷的顺序,来确定数据写入到哪个卷。


3、添加表的存储策略

创建表的时候,如果不指定存储策略,则会使用default存储策略。


我们可以在系统表system.tables中查看表的存储策略:

ck01 :) select database, table, engine, storage_policy from system.tables where table='metrics' and database='local';

SELECT
    database,
    table,
    engine,
    storage_policy
FROM system.tables
WHERE (table = 'metrics') AND (database = 'local')

Query id: 7a7fe08f-8297-40d4-952c-ad454c50e56e

┌─database─┬─table───┬─engine────┬─storage_policy─┐
│ local    │ metrics │ MergeTree │ default        │
└──────────┴─────────┴───────────┴────────────────┘

1 row in set. Elapsed: 0.002 sec.


可以在简表时指定表的存储策略,也可以修改已有的表的存储策略。


修改表的存储策略:


修改存储策略时,新的存储策略需要包含老的存储策略的所有数据卷,否则会报错:

ck01 :) alter table local.metrics modify setting storage_policy='from_default_to_disk2';

ALTER TABLE local.metrics
    MODIFY SETTING storage_policy = 'from_default_to_disk2'

Query id: a0e034c6-8955-4cf9-b47a-399611a35523


0 rows in set. Elapsed: 0.002 sec.

Received exception from server (version 22.6.3):
Code: 36. DB::Exception: Received from localhost:9000. DB::Exception: New storage policy `default` shall contain volumes of old one. (BAD_ARGUMENTS)


我们需要修改一下存储策略的定义:

<policies>
	<from_default_to_disk2>
	    <volumes>
		   <default>
		      <disk>default</disk>
                      <max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
                      <load_balancing>round_robin</load_balancing>
                   </default>
		   <vol_disk2>
		      <disk>disk2</disk>
		   </vol_disk2>
	    </volumes>
	   <move_factor>0.2</move_factor>
	</from_default_to_disk2>
    </policies>


再次修改存储策略时,就可以成功了:

ck01 :) alter table local.metrics modify setting storage_policy='from_default_to_disk2';
ALTER TABLE local.metrics
    MODIFY SETTING storage_policy = 'from_default_to_disk2'

Query id: a0e034c6-8955-4cf9-b47a-399611a35523


0 rows in set. Elapsed: 0.002 sec.


ck01 :) select database, table, engine, storage_policy from system.tables where table='metrics' and database='local';

SELECT
    database,
    table,
    engine,
    storage_policy
FROM system.tables
WHERE (table = 'metrics') AND (database = 'local')

Query id: 18b7ddf6-cce8-4c51-b1ee-d04619ecb1f1

┌─database─┬─table───┬─engine────┬─storage_policy────────┐
│ local    │ metrics │ MergeTree │ from_default_to_disk2 │
└──────────┴─────────┴───────────┴───────────────────────┘

1 row in set. Elapsed: 0.002 sec.


移动表的数据

有几种方式可以将表中的数据移动到制定存储卷中:

1、基于存储策略的move_factor,系统自动移动数据。

2、使用命令手动将数据移动到指定存储卷。

3、建表时指定TTL,将超过TTL时间的数据存储到指定的存储卷。


使用命令移动数据

可以使用alter table move partition命令将指定分区移动到指定的卷或磁盘。当然,表的当前存储策略必须存在指定的卷或磁盘。


ck01 :) select partition, name from system.parts where table = 'metrics';

SELECT
    partition,
    name
FROM system.parts
WHERE table = 'metrics'

Query id: 26f55d64-6ff5-4dc5-9ba0-ec5340693c0c

┌─partition─┬─name─────────────┐
│ 20221130  │ 20221130_16_19_1 │
└───────────┴──────────────────┘

1 row in set. Elapsed: 0.002 sec.

ck01 :) alter table metrics move partition 20221130 to volume 'vol_disk2';

ALTER TABLE metrics
    MOVE PARTITION 20221130 TO VOLUME 'vol_disk2'

Query id: 5ee042d5-a2e0-44d4-b98f-8db0d8265355

Ok.


移动后,可以看到相关数据文件也进行了移动:

ck01 :) select partition, name, disk_name, path from system.parts where table = 'metrics';

SELECT
    partition,
    name,
    disk_name,
    path
FROM system.parts
WHERE table = 'metrics'

Query id: df4c3140-4ece-457d-9364-249719ba5105

┌─partition─┬─name─────────────┬─disk_name─┬─path────────────────────────────────────────────────────────────────────┐
│ 20221130  │ 20221130_16_19_1 │ disk2     │ /data2/store/def/def88518-fd7b-418d-a7dd-6564e38bba39/20221130_16_19_1/ │
└───────────┴──────────────────┴───────────┴─────────────────────────────────────────────────────────────────────────┘


将分区移动到指定磁盘:

ck01 :) alter table metrics move partition 20221130 to disk 'default';

ALTER TABLE metrics
    MOVE PARTITION 20221130 TO DISK 'default'

Query id: 0e71441c-9182-46f2-9393-84acb1ed6ed7

Ok.

0 rows in set. Elapsed: 0.002 sec.



ck01 :) select partition, name, disk_name, path from system.parts where table = 'metrics';

SELECT
    partition,
    name,
    disk_name,
    path
FROM system.parts
WHERE table = 'metrics'

Query id: 304271c2-0b06-4689-8c77-340fde6f3585

┌─partition─┬─name─────────────┬─disk_name─┬─path─────────────────────────────────────────────────────────────────────────────────────────┐
│ 20221130  │ 20221130_16_19_1 │ default   │ /data/clickhouse/clickhouse/store/def/def88518-fd7b-418d-a7dd-6564e38bba39/20221130_16_19_1/ │
└───────────┴──────────────────┴───────────┴──────────────────────────────────────────────────────────────────────────────────────────────┘


根据TTL指定存储卷

CREATE TABLE example_table
(
    d DateTime,
    a Int
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(d)
ORDER BY d
TTL d + INTERVAL 1 MONTH DELETE,
    d + INTERVAL 1 WEEK TO VOLUME 'default',
    d + INTERVAL 2 WEEK TO DISK 'disk2'
settings storage_policy='from_default_to_disk2'


注意,TTL里指定的disk, volume必须是指定storage_policy里存在的。


写入一些数据:


insert into example_table values(now(), 1);
insert into example_table values(now() - interval 5 day, 2);
insert into example_table values(now() - interval 10 day, 3);
insert into example_table values(now() - interval 15 day, 4);
insert into example_table values(now() - interval 20 day, 5);
insert into example_table values(now() - interval 25 day, 6);
insert into example_table values(now() - interval 30 day, 7);
insert into example_table values(now() - interval 35 day, 8);


查看数据存储在哪个磁盘:

ck01 :) select partition, name,active, disk_name from system.parts where table = 'example_table' order by partition;

SELECT
    partition,
    name,
    active,
    disk_name
FROM system.parts
WHERE table = 'example_table'
ORDER BY partition ASC

Query id: cf10d901-c41b-4094-9761-02f0a8ac916e

┌─partition─┬─name───────────┬─active─┬─disk_name─┐
│ 20221114  │ 20221114_8_8_0 │      0 │ disk2     │
│ 20221119  │ 20221119_7_7_0 │      0 │ disk2     │
│ 20221124  │ 20221124_6_6_0 │      1 │ disk2     │
│ 20221129  │ 20221129_5_5_0 │      1 │ disk2     │
│ 20221204  │ 20221204_4_4_0 │      1 │ disk2     │
│ 20221209  │ 20221209_3_3_0 │      1 │ default   │
│ 20221214  │ 20221214_2_2_0 │      1 │ default   │
│ 20221219  │ 20221219_1_1_0 │      1 │ default   │
└───────────┴────────────────┴────────┴───────────┘


可以看到,离当前时间(2022-12-19)近(1周内)的数据,存在在default磁盘。其他数据存储在disk2磁盘。

过期的分区会自动被删除。


相关文章

oracle字符集简介

一、字符集介绍字符集和国家字符集字符集在创建数据库实例时指定,可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。1、字符集(CHARACTER...

trino组件对接alluxio(三)

trino组件对接alluxio(三)

本文是基于已经部署了trino和alluxio的基础上,进行的trino与alluxio的组件对接,alluxio已经开启了高可用模式。安装部署1、增加alluxio配置在core-site.xml和...

gin框架连接mysql数据库连接池泄露

gin框架连接mysql数据库连接池泄露

1、故障爆发12月1号上午10点出头,我们收到阿里云监控告警:客户官网探测异常,如图所示:然后我们DBA查看了后端数据库实例,发现数据库连接已经被用尽了,导致服务出现异常,如图所示:当时我们和客户协商...

ES运维(八)添加IK分词器

ES运维(八)添加IK分词器

一、概述ES自带standard analyzer、simple analyzer、whitespace analyzer、stop analyzer、language analyzer、patter...

数据建模用的哪些模型?

星型模型星形模式(Star Schema)是最常用的维度建模方式。星型模式是以事实表为中心,所有的维度表直接连接在事实表上,像星星一样。星形模式的维度建模由一个事实表和一组维表成,且具有以下特点:a....

Flume使用案例之Flume与Flume之间数据传递(单Flume多Channel、Sink)

目标:使用flume1监控文件变动,flume1将变动内容传递给flume-2,flume-2负责存储到HDFS。同时flume1将变动内容传递给flume-3,flume-3负责输出到local分步...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。