Clickhouse TTL的那些事

TTL简介

ClickHouse原生支持数据生命周期(TTL)管理的功能
TTL即Time To Live,表示数据的存活时间。在MergeTree中,可以为某个列字段或者整张表设置TTL。当时间达到时,若列字段级别的TTL则会删除这一列的数据;若表级别的TTL则会删除整张表的数据;若同时设置了列级别的和表级别的TTL则以先到期的为准。
无论列级别还是表级别的TTL,都需要依托某个Datetime或者date类型的字段,通过对这个时间字段的INTERVAL操作来表述TTL的过期时间.
示例:

TTL time_column
TTL time_column + interval

要定义interval, 需要使用 时间间隔 操作符。

TTL date_time + INTERVAL 1 MONTH
TTL date_time + INTERVAL 15 HOUR

列TTL

当列中的值过期时, ClickHouse会将它们替换成该列数据类型的默认值。如果数据片段中列的所有值均已过期,则ClickHouse 会从文件系统中的数据片段中删除此列。
TTL子句不能被用于主键字段。
示例:
创建表时指定 TTL

CREATE TABLE example_table
(
    d DateTime,
    a Int TTL d + INTERVAL 1 MONTH,
    b Int TTL d + INTERVAL 1 MONTH,
    c String
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(d)
ORDER BY d;

为表中已存在的列字段添加 TTL:

ALTER TABLE example_table
    MODIFY COLUMN
    c String TTL d + INTERVAL 1 DAY;

修改列字段的 TTL:

ALTER TABLE example_table
    MODIFY COLUMN
    c String TTL d + INTERVAL 1 MONTH;

表TTL

表可以设置一个用于移除过期行的表达式,以及多个用于在磁盘或卷上自动转移数据片段的表达式。当表中的行过期时,ClickHouse 会删除所有对应的行。对于数据片段的转移特性,必须所有的行都满足转移条件。
TTL 规则的类型紧跟在每个 TTL 表达式后面,它会影响满足表达式时(到达指定时间时)应当执行的操作:

  • DELETE - 删除过期的行(默认操作);
  • TO DISK 'aaa' - 将数据片段移动到磁盘 aaa;
  • TO VOLUME 'bbb' - 将数据片段移动到卷 bbb.

示例:
创建时指定 TTL

CREATE TABLE example_table
(
    d DateTime,
    a Int
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(d)
ORDER BY d
TTL d + INTERVAL 1 MONTH [DELETE],
    d + INTERVAL 1 WEEK TO VOLUME 'aaa',
    d + INTERVAL 2 WEEK TO DISK 'bbb';

修改表的 TTL:

ALTER TABLE example_table
    MODIFY TTL d + INTERVAL 1 DAY;

删除数据

ClickHouse 在数据片段合并时会删除掉过期的数据。
当ClickHouse发现数据过期时, 它将会执行一个计划外的合并。要控制这类合并的频率, 可以设置 merge_with_ttl_timeout。如果该值被设置的太低, 它将引发大量计划外的合并,这可能会消耗大量资源。
如果在合并的过程中执行 SELECT 查询, 则可能会得到过期的数据。为了避免这种情况,可以在 SELECT 之前使用 OPTIMIZE 查询。

测试分析

首先准备一个已经做好冷热盘的clickhouse:

创建一个test ttl表,数据1分钟过期,超时时间1分钟。

CREATE TABLE test2
(
    `d` DateTime,
    `a` Int
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(d)
ORDER BY d
TTL d to volume 'default',
    d + toIntervalMinute(1) TO VOLUME 'cold'
SETTINGS storage_policy = 'hot_and_cold';

更改merge_with_ttl_timeout:

ALTER TABLE test MODIFY SETTING merge_with_ttl_timeout = 60;

插入数据:

INSERT INTO TABLE test2 VALUES (now(),1),(now()-interval 1 minute,2),(now()-interval 2 minute,3),(now()-interval 3 minute,4);

这4条数据分别会在1分钟后、2分钟后、3分钟后过期。
现在查询test2的数据分布:

因为有1分钟前的数据写入,所以有部分数据直接被写在了冷盘。
等ttl到期后,再次查看test2表的数据分布:

可以看到数据全部被转移到了冷盘。

后记

此篇是对之前clickhouse做冷热分区的一个补充。希望大家一起学习,共同进步!

作者:Mr.Ares
个性签名:许多人的付出都是浅尝辄止!
原文地址:https://www.cnblogs.com/aresxin/p/clickhouse-ttl.html