TTL 概述
- 删除旧数据:不出所料,你可以在指定时间间隔后删除行或列
- 在磁盘之间移动数据:经过一段时间后,你可以在不同存储卷之间移动数据——这对于部署热/温/冷架构非常有用
- 数据 rollup:在删除旧数据之前,先将其 rollup 为各种有用的聚合结果和计算结果
TTL 可以应用于整个表,也可以应用于特定列。
TTL 语法
TTL 子句可以出现在列定义之后和/或表定义末尾。使用 INTERVAL 子句来定义时间长度 (对应的值必须是 Date 或 DateTime 数据类型) 。例如,下表有两列
带有 TTL 子句:
- x 列的生存时间 (TTL) 为自 timestamp 列起 1 个月
- y 列的生存时间 (TTL) 为自 timestamp 列起 1 天
- 当时间间隔到期时,该列就会过期。ClickHouse 会将该列的值替换为其数据类型的默认值。如果数据分区片段中该列的所有值都已过期,ClickHouse 会从文件系统中的该数据分区片段删除这一列。
生存时间 (TTL) 规则可以修改或删除。更多详情请参见表生存时间 (TTL) 的操作页面。
触发生存时间 (TTL) 事件
merge_with_ttl_timeout:再次执行带有删除生存时间 (TTL) 的合并前,最少需要等待的秒数。默认值为 14400 秒 (4 小时) 。merge_with_recompression_ttl_timeout:再次执行带有重压缩生存时间 (TTL) 的合并前,最少需要等待的秒数 (即在删除前先对数据进行汇总的规则) 。默认值:14400 秒 (4 小时) 。
这不是一种理想的方案 (我们也不建议频繁使用) ,不过你也可以使用
OPTIMIZE 强制执行一次合并:OPTIMIZE 会对表中的 parts 启动一次计划外合并;如果你的表已经只剩一个 part,FINAL 会强制重新优化。删除行
WHERE 条件即可轻松实现。
也可以使用多个条件:
删除列
balance 和 address 这两列过期。现在来修改 customers 表,将这两列的生存时间 (TTL) 设置为 2 小时:
实现 rollup
TTL 表达式中添加 GROUP BY 子句来实现,同时在表中添加一些列来存储聚合结果。
假设在下面的 hits 表中,我们想要删除旧行,但在删除这些行之前保留 hits 列的总和与最大值。我们需要一个字段来存储这些值,并且需要在 TTL 子句中添加一个 GROUP BY 子句,以便对总和与最大值进行 rollup:
hits 表的几点说明:
TTL子句中的GROUP BY列必须是PRIMARY KEY的前缀,而我们希望按天起始时间对结果进行分组。因此,我们将toStartOfDay(timestamp)添加到了主键中- 我们添加了两个字段来存储聚合结果:
max_hits和sum_hits - 根据
SET子句的定义方式,必须将max_hits和sum_hits的默认值设为hits,逻辑才能正常工作
实现热/温/冷架构
如果你使用的是 ClickHouse Cloud,本课中的步骤并不适用。在 ClickHouse Cloud 中,你无需操心旧数据的移动。
TTL 命令的 TO DISK 和 TO VOLUME 子句实现热/温/冷架构。 (顺便一提,这并不一定非要采用热/冷分层——无论你的具体场景是什么,都可以用生存时间 (TTL) 来移动数据。)
TO DISK和TO VOLUME选项指的是你在 ClickHouse 配置文件中定义的磁盘或卷名称。创建一个名为my_system.xml的新文件 (文件名也可以自定义) ,在其中定义磁盘,再定义使用这些磁盘的卷。将该 XML 文件放到/etc/clickhouse-server/config.d/中,以使配置应用到你的系统:
- 上述配置中提到了三个磁盘,它们分别指向 ClickHouse 可读写的文件夹。卷可以包含一个或多个磁盘——我们为这三个磁盘分别定义了一个卷。下面来看这些磁盘:
- 接下来……验证一下卷:
- 现在我们将添加一条
TTL规则,在热、温、冷存储卷之间移动数据:
- 新的
TTL规则应该会自动生效,但你也可以手动强制执行以确保这一点:
- 使用
system.parts表验证数据是否已移动到预期的磁盘上: