ClickHouse TTL for Columns and Tables
导语
ClickHouse原生支持数据生命周期(TTL)管理的功能。
可以为整个表或每个单独的列设置TTL子句。表级TTL也可以指定在磁盘和分区之间自动移动数据的逻辑。 表达式的计算结果必须为Date
或DateTime
数据类型。
示例:
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表
Table可以具有一个用于删除过期行的表达式,并可以具有多个用于在磁盘或分区之间自动移动数据块的表达式。当表格中的行到期时,ClickHouse会删除所有对应的行。对于数据块移动功能,数据块中的所有行都必须满足移动表达式条件。
TTL expr [DELETE|TO DISK 'aaa'|TO VOLUME 'bbb'], ...
TTL动作在TTL时间表达式之后给出,它决定在TTL表达式满足后(到达了当前的时间)将要执行的操作:
DELETE
- 删除过期行 (默认动作);
TO DISK 'aaa'
- 移动数据至磁盘A;
TO VOLUME 'bbb'
- 移动数据至磁盘B.
示例:
创建一个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合并数据块时,将删除TTL过期的数据。
对于已过期的数据,ClickHouse将执行“计划外(off-schedule)”的合并。可以通过设置merge_with_ttl_timeout
控制这种合并的频率。如果该值设定的太低,可能会执行许多计划外的合并,消耗大量资源。
如果在两个合并间隔之间执行SELECT
查询,则可能会获取到过期的数据。为了避免这种情况,请在SELECT之前使用OPTIMIZE
查询主动触发合并。
使用案例
某用户反馈TTL表不生效,设定的过期时间已经达到了,通过SELECT
还是能查到过期的数据,通过上文可以看出用户可能是在两个合并间隔之间执行的查询,这样就可能会获取到过期的数据。为了进一步确认过期数据是否被清除以及计划外的合并有没有执行,可通过查询日志来进行诊断。
grep "expired TTL" /data/clickhouse/clickhouse-server/logs/clickhouse-server.log
上诉命令可以在ClickHouse日志文件中查到过期数据被处理的情况,如果有相关的日志信息则说明ClickHouse已经进行了off-schedule
合并,再查询时就不会获取到过期的数据了。
测试分析
如果日志文件中查不到到ClickHouse对过期数据的处理日志就需要进一步测试该项功能是否work了,对此可在集群中创建一个TTL表进行测试。
CREATE TABLE ttl_table_test
(
Ds DateTime,
Id Int
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(Ds)
ORDER BY Ds
TTL Ds + INTERVAL 10 MINUTE;
ALTER TABLE ttl_table_test MODIFY SETTING merge_with_ttl_timeout = 60;
INSERT INTO TABLE ttl_table_test VALUES(now()-interval 9 minute,1),(now()-interval 8 minute,2),(now()-interval 7 minute,3);
SELECT * FROM ttl_table_test;
上诉sql指令首先创建了一个TTL表ttl_table_test
并设置了超时时间为10分钟,后续修改了计划外合并的周期为60秒(默认为86400秒,一天),之后向表中插入了3条数据,这3条数据分别会在1分钟后、2分钟后、3分钟后过期。最后查询表中的数据。
INSERT INTO TABLE ttl_table_test VALUES(now()-interval 10 minute,1),(now()-interval 9 minute,2),(now()-interval 8 minute,3);
如果往TTL表里插入已过时数据,则已过时数据不会被存储下来。
merge_with_ttl_timeout
时间窗口内未进行后台或强制OPTIMIZE
合并表,已经过期的数据就会还在,所以会查询到过期的数据。
使用
ALTER TABLE ttl_table_test MODIFY SETTING merge_with_ttl_timeout = 60;
将merge_with_ttl_timeout
设定为60秒,可以很快验证过期数据是否被删除(P.S. 设定过低会频繁执行合并,耗费系统资源。)或者先进行OPTIMIZE
再查询
OPTIMIZE TABLE ttl_table_test final;
可以看到过期数据已经不存在了。
参考文献
- ASP.NET Core 阶段性总结
- Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程案例演示
- C# 窗体常用API函数 应用程序窗体查找
- C#进阶系列——WebApi接口测试工具:WebApiTestClient
- 由Dapper QueryMultiple 返回数据的问题
- 【初探IONIC】不会Native可不可以开发APP?
- MVC视图展现模式之移动布局解析-续集
- 在 ASP.NET MVC 中使用异步控制器
- MVC5 Entity Framework学习之异步和存储过程
- ConcurrentDictionary 对决 Dictionary+Locking
- 在ASP.NET 5中使用SignalR
- 避免在ASP.NET Core中使用服务定位器模式
- 直传文件到Azure Storage的Blob服务中
- 闭路电视探头究竟有多不安全?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法