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做冷熱分區的一個補充。希望大家一起學習,共同進步!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM