Clickhouse冷热数据分离实践

俊达2年前技术文章2225

配置多卷存储策略

使用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磁盘。

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


相关文章

Trino资源组配置

Trino资源组配置

1 概述Presto作为一个大数据场景下的交互式查询引擎,当使用达到一定规模,就会更多考虑资源分配问题,即保障重要任务优先获取资源。Presto资源组: Presto的资源组机制,是从资源分配的角度...

CDH实操--CDH集成Trino(三)

CDH实操--CDH集成Trino(三)

1、将parcel包放到对应下载目录将parcel包放到/var/www/html/trino目录下修改httpd配置文件新增parcel文件类型然后通过命令启动httpd服务:systemctl s...

大数据组件--Hive与Impala的异同

大数据组件--Hive与Impala的异同

一、同数据存储:使用相同的存储数据池都支持把数据存储于HDFS, HBase。元数据:两者使用相同的元数据。SQL语法:基本类似。二、异1)、底层运行使用的技术hive底层默认使用mapreduce引...

Hbase映射为Hive外表

Hbase映射为Hive外表

Hbase对应Hive外表(背景:在做数据ETL中,可能原始数据在列式存储Hbase中,这个时候,如果我们想清洗数据,可以考虑把Hbase表映射为Hive的外表,然后使用Hive的HQL来清除处理数据...

CDP实操--Ranger Tag-based策略验证(四)

CDP实操--Ranger Tag-based策略验证(四)

1.1Ranger Tag-based策略验证在Ranger webui里给allan_admin和sam_sec用户赋权,给予添加classification的权限使用allan_admin或者sa...

Oozie web console is disabled 问题解决

Oozie web console is disabled 问题解决

一、问题一a、错误现象b、解决方案①、根据提示查看Oozie Quick Start 发现是缺少ExtJS 2.2库(必须是2.2版)下载ExtJS2.2下载地址:http://archive.clo...

发表评论    

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