使用 TTL (time-to-live) 管理数据
TTL 概述
TTL (time-to-live) 指的是在经过一定时间间隔后,行或列被移动、删除或汇总的能力。虽然“time-to-live”这个表达听起来只适用于删除旧数据,但 TTL 有多种用例
- 删除旧数据:无需多言,可以在指定的时间间隔后删除行或列
- 在磁盘之间移动数据:在经过一定时间后,可以将数据在存储卷之间移动 - 对于部署热/温/冷架构非常有用
- 数据汇总:在删除之前,将较旧的数据汇总成各种有用的聚合和计算
TTL 可以应用于整个表或特定列。
TTL 语法
TTL 子句可以出现在列定义之后和/或表的定义末尾。使用 INTERVAL 子句定义一个时间长度(需要是 Date 或 DateTime 数据类型)。例如,下表有两个带有 TTL 子句的列
- x 列从时间戳列开始的生存时间为 1 个月
- y 列从时间戳列开始的生存时间为 1 天
- 当间隔期满时,该列会过期。ClickHouse 会用其数据类型的默认值替换该列的值。如果数据部分中的所有列值都过期,ClickHouse 会从文件系统中的数据部分中删除该列。
可以更改或删除 TTL 规则。有关更多详细信息,请参阅 表 TTL 操作 页面。
当使用表级 TTL 删除旧行时,我们建议您**按与 TTL 表达式中使用的相同时间字段的日期或月份对表进行分区**。
ClickHouse 可以比删除单个行更有效地删除整个分区。当您的分区键与 TTL 表达式对齐时,ClickHouse 可以在分区过期时一次性删除整个分区,而不是重写数据部分以删除过期行。
根据您的 TTL 周期选择您的分区粒度
- 对于天/周的 TTL:使用
toYYYYMMDD(date_field)按天分区 - 对于月/年的 TTL:使用
toYYYYMM(date_field)或toStartOfMonth(date_field)按月分区
触发 TTL 事件
过期行的删除或聚合不是立即发生的 - 它仅在表合并期间发生。如果您有一个没有主动合并的表(出于任何原因),有两种设置可以触发 TTL 事件
merge_with_ttl_timeout:重复使用删除 TTL 合并的最小延迟(秒)。默认值为 14400 秒(4 小时)。merge_with_recompression_ttl_timeout:重复使用重新压缩 TTL 合并的最小延迟(秒)(规则在删除之前汇总数据)。默认值:14400 秒(4 小时)。
因此,默认情况下,您的 TTL 规则至少每 4 小时应用于您的表一次。如果需要更频繁地应用 TTL 规则,请修改上述设置。
这不是一个很好的解决方案(或者我们不建议您经常使用),但您也可以使用 OPTIMIZE 强制合并
OPTIMIZE 初始化表各部分的非计划合并,而 FINAL 如果您的表已经是单个部分,则强制重新优化。
删除行
要删除表中在经过一段时间后的一整行,请在表级别定义 TTL 规则
此外,也可以根据记录的值定义 TTL 规则。这很容易通过指定 where 条件来实现。允许多个条件
删除列
与其删除整行,不如假设您只想让 balance 和 address 列过期。让我们修改 customers 表,并为这两个列添加一个 TTL,使其为 2 小时
实现汇总
假设我们想在经过一段时间后删除行,但保留一些数据用于报告目的。我们不想要所有细节 - 只需要一些历史数据的聚合结果。这可以通过在 TTL 表达式中添加 GROUP BY 子句,以及在表中存储聚合结果的一些列来实现。
假设在以下 hits 表中,我们想删除旧行,但在删除行之前保留 hits 列的总和和最大值。我们需要一个字段来存储这些值,并且需要在 TTL 子句中添加一个 GROUP BY 子句来汇总总和和最大值
关于 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 子句在 ClickHouse 中实现热/温/冷架构的步骤。(顺便说一下,它不必是热和冷的 - 您可以使用 TTL 移动数据以满足您的任何用例。)
TO DISK和TO VOLUME选项指的是在 ClickHouse 配置文件中定义的磁盘或卷的名称。创建一个名为my_system.xml(或任何文件名)的新文件,该文件定义您的磁盘,然后定义使用您的磁盘的卷。将 XML 文件放在/etc/clickhouse-server/config.d/中,以便将配置应用于您的系统
- 上面的配置引用了三个指向 ClickHouse 可以从中读取和写入的文件夹的磁盘。卷可以包含一个或多个磁盘 - 我们为每个磁盘定义了一个卷。让我们查看磁盘
- 并且...让我们验证卷
- 现在我们将添加一个 TTL 规则,该规则将在热、温和冷卷之间移动数据
- 新的 TTL 规则应该生效,但您可以强制使其以确保
- 使用
system.parts表验证您的数据是否已移动到其预期的磁盘
响应将如下所示