ClickHouse官方文档翻译_引擎-表引擎-MergeTree系列-自定义分区键

Posted by Lance Lee on Tuesday, June 2, 2020

TOC

自定义分区键

可以对MergeTree系列的表(包括复制表)进行分区。基于MergeTree表的物化视图也支持分区。

分区是表中按指定条件划分记录的逻辑组合。可以根据任意条件设置分区,例如按月、按日或按事件类型。每个分区单独存储,以简化对数据的处理。在访问数据时,ClickHouse尽可能使用最小的分区子集。

在创建表时,分区在PARTITION BY expr子句中指定。分区键可以是表的所有列的任何表达式。 例如,要按月指定分区,可以使用表达式toYYYYMM(date_column)

CREATE TABLE visits
(
    VisitDate Date,
    Hour UInt8,
    ClientID UUID
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(VisitDate)
ORDER BY Hour;

分区键也可以是表达式元组(类似于主键)。例如:

ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/name', 'replica1', Sign)
PARTITION BY (toMonday(StartDate), EventType)
ORDER BY (CounterID, StartDate, intHash32(UserID));

在本例中,我们根据一周内发生的事件类型设置分区。

向表中插入新数据时,数据存储在按主键排序的单独数据片段中(块)。在插入后的10-15分钟内,同一分区的各个数据片段被合并到整个分区中。

合并只适用于分区表达式具有相同值的数据片段。这意味着您不应该创建粒度过细的分区(超过1000个分区)。否则,由于文件系统中的大量文件和打开的文件描述符,SELECT查询执行得很差。

使用system.parts表查看表的数据片段和分区。例如,假设我们有一个按月分区的visit表。在system.parts表执行SELECT查询:

SELECT
    partition,
    name,
    active
FROM system.parts
WHERE table = 'visits'
┌─partition─┬─name───────────┬─active─┐
│ 201901    │ 201901_1_3_1   │      0 │
│ 201901    │ 201901_1_9_2   │      1 │
│ 201901    │ 201901_8_8_0   │      0 │
│ 201901    │ 201901_9_9_0   │      0 │
│ 201902    │ 201902_4_6_1   │      1 │
│ 201902    │ 201902_10_10_0 │      1 │
│ 201902    │ 201902_11_11_0 │      1 │
└───────────┴────────────────┴────────┘

partition列包含分区的名称。本例中有两个分区:201901201902。可以使用这个列的值在ALTER … PARTITION查询中指定分区名。

name列包含分区数据片段的名称。可以使用此列来指定ALTER ATTACH PART查询中数据片段的名称。

让我们分解第一个数据片段的名称:201901_1_3_1

  • 201901 是分区名称
  • 1 是数据块的最小编号。
  • 2 是数据库的最大编号。
  • 1 是块级别(它形成合并树的深度)。

旧类型表的数据片段名称为:20190117_20190123_2_2_0(最小日期—最大日期—最小块遍号—最大块遍号—块级别)。

active列显示数据片段的状态。1是激活状态;0是未激活状态。例如,未激活的数据片段是合并到更大的数据片段后剩下的源数据片段。损坏的数据判断也指示为未激活状态。

如示例中所看到的,同一个分区有多个独立的数据片段(例如,201901_1_3_1201901_1_9_2)。这意味着这些部分现在还没有合并。ClickHouse定期合并插入的数据片段,大概是插入后15分钟。此外,可以使用优化查询执行非计划的合并。例如:

OPTIMIZE TABLE visits PARTITION 201902;
┌─partition─┬─name───────────┬─active─┐
│ 201901    │ 201901_1_3_1   │      0 │
│ 201901    │ 201901_1_9_2   │      1 │
│ 201901    │ 201901_8_8_0   │      0 │
│ 201901    │ 201901_9_9_0   │      0 │
│ 201902    │ 201902_4_6_1   │      0 │
│ 201902    │ 201902_4_11_2  │      1 │
│ 201902    │ 201902_10_10_0 │      0 │
│ 201902    │ 201902_11_11_0 │      0 │
└───────────┴────────────────┴────────┘

未激活的数据片段将在合并完成大概10分钟后删除。

查看一组数据片段和分区的另一种方法是进入表的目录:/var/lib/clickhouse/data/<database>/<table>/。例如:

/var/lib/clickhouse/data/default/visits$ ls -l
total 40
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  1 16:48 201901_1_3_1
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 16:17 201901_1_9_2
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 15:52 201901_8_8_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 15:52 201901_9_9_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 16:17 201902_10_10_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 16:17 201902_11_11_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 16:19 201902_4_11_2
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 12:09 201902_4_6_1
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  1 16:48 detached

文件夹'201901_1_1_0 '' 201901_1_7_1'等是数据片段的目录。 每个数据片段都与相应的分区相关,并且只包含特定月份的数据(本例中的表按月分区)。

detached目录包含使用DETACH查询从表中卸载的数据片段。损坏的数据片段不是被删除,而同样被移动到这个目录。服务器不使用来自detached目录的数据片段。可以在随时添加、删除或修改此目录中的数据 —— 直到运行ATTACH查询时服务器才会知道这一点。

注意,在操作服务器上,您不能手动更改文件系统上的数据片段集或其数据,因为服务器不会感知到这些修改。对于非复制表,可以在服务器停止时执行此操作,但不建议这样做。对于复制的表,在任何情况下都不能更改数据片段集。

ClickHouse 支持对分区执行这些操作:删除分区,从一个表复制到另一个表,或创建备份。了解分区的所有操作,参考操作分区和数据片段一节。

「如果这篇文章对你有用,请支持一下哦」

Attack On Programmer

如果这篇文章对你有用,请支持一下哦

使用微信扫描二维码完成支付