ClickHouse/docs/ja/guides/developer/ttl.md
2024-11-18 11:58:58 +09:00

11 KiB
Raw Blame History

slug sidebar_label sidebar_position keywords description
/ja/guides/developer/ttl 有効期限 (TTL) 2
ttl
time to live
clickhouse
古い
データ
TTL (time-to-live) は、一定期間経過後に行やカラムを移動、削除、または集約する機能を指します。

有効期限 (TTL) を用いたデータ管理

TTLの概要

TTL (time-to-live) は、一定期間経過後に行やカラムを移動、削除、または集約する機能を指します。「time-to-live」という表現は古いデータを削除することだけを意味しているように聞こえますが、TTLにはいくつかの用途があります

  • 古いデータの削除: 予想どおり、指定された時間経過後に行やカラムを削除できます
  • ディスク間のデータ移動: 一定時間経過後にストレージボリューム間でデータを移動できます - ホット/ウォーム/コールドアーキテクチャの展開に役立ちます
  • データのロールアップ: 古いデータを削除する前に、有用な集計や計算にまとめます

:::note TTLは、テーブル全体または特定のカラムに適用できます。 :::

TTLの構文

TTL句は、カラム定義の後および/またはテーブル定義の最後に記述できます。INTERVAL句を使用して、時間の長さを定義します(これにはDateまたはDateTimeデータ型が必要です)。たとえば、次のテーブルにはTTL句を持つ二つのカラムがあります:

CREATE TABLE example1 (
   timestamp DateTime,
   x UInt32 TTL timestamp + INTERVAL 1 MONTH,
   y String TTL timestamp + INTERVAL 1 DAY,
   z String
)
ENGINE = MergeTree
ORDER BY tuple()
  • xカラムは、timestampカラムから1か月の有効期限があります
  • yカラムは、timestampカラムから1日の有効期限があります
  • インターバルが経過すると、カラムは期限切れになります。ClickHouseはデフォルト値に置き換え、データ部分の全カラム値が期限切れになると、そのカラムをファイルシステムから削除します。

:::note TTLルールは変更または削除できます。詳細はテーブルTTLの操作ページを参照してください。 :::

TTLイベントのトリガー

期限切れの行を削除または集約する操作は即時には行われず、テーブルマージ時にのみ実行されます。アクティブにマージされていないテーブルがある場合、TTLイベントをトリガーする2つの設定があります

  • merge_with_ttl_timeout: 削除TTLで再度マージするまでの最小遅延時間。デフォルトは14400秒4時間です。
  • merge_with_recompression_ttl_timeout: 再圧縮TTL削除前にデータをロールアップするルールで再度マージするまでの最小遅延時間。デフォルト値は14400秒4時間です。

したがって、デフォルトでは、TTLルールは少なくとも4時間ごとにテーブルに適用されます。より頻繁にTTLルールを適用する必要がある場合は、上記の設定を変更してください。

:::note 推奨する頻繁な使用法ではありませんが、OPTIMIZEを使用してマージを強制することもできます:

OPTIMIZE TABLE example1 FINAL

OPTIMIZEはテーブルの部分の予定外のマージを初期化し、FINALはテーブルがすでに単一部分になっている場合に再最適化を強制します。 :::

行の削除

一定時間経過後にテーブル全体の行を削除するには、テーブルレベルでTTLルールを定義します

CREATE TABLE customers (
timestamp DateTime,
name String,
balance Int32,
address String
)
ENGINE = MergeTree
ORDER BY timestamp
TTL timestamp + INTERVAL 12 HOUR

さらに、レコードの値に基づくTTLルールを定義することも可能です。 これは、条件を指定することで簡単に実装できます。 複数の条件を許可しています:

CREATE TABLE events
(
    `event` String,
    `time` DateTime,
    `value` UInt64
)
ENGINE = MergeTree
ORDER BY (event, time)
TTL time + INTERVAL 1 MONTH DELETE WHERE event != 'error',
    time + INTERVAL 6 MONTH DELETE WHERE event = 'error'

カラムの削除

行全体を削除する代わりに、balanceとaddressカラムだけを期限切れにしたいとします。customersテーブルを変更し、両方のカラムに2時間のTTLを追加します

ALTER TABLE customers
MODIFY COLUMN balance Int32 TTL timestamp + INTERVAL 2 HOUR,
MODIFY COLUMN address String TTL timestamp + INTERVAL 2 HOUR

ロールアップの実装

特定の期間経過後に行を削除したいが、報告目的のために一部のデータを保持したい場合を考えてみましょう。すべての詳細が欲しいわけではなく、履歴データの集約された結果を少し欲しいだけです。これは、TTL式にGROUP BY句を追加し、テーブルのカラムを使用して集約結果を保存することで実装できます。

以下のhitsテーブルでは、古い行を削除しますが、削除する前にhitsカラムの合計と最大を保持したいとします。それらの値を保存するフィールドが必要であり、それに加えて合計と最大をロールアップするTTL句にGROUP BY句を追加する必要があります:

CREATE TABLE hits (
   timestamp DateTime,
   id String,
   hits Int32,
   max_hits Int32 DEFAULT hits,
   sum_hits Int64 DEFAULT hits
)
ENGINE = MergeTree
PRIMARY KEY (id, toStartOfDay(timestamp), timestamp)
TTL timestamp + INTERVAL 1 DAY
    GROUP BY id, toStartOfDay(timestamp)
    SET
        max_hits = max(max_hits),
        sum_hits = sum(sum_hits);

hitsテーブルに関するいくつかの注意点:

  • TTL句のGROUP BYカラムはPRIMARY KEYのプレフィックスである必要があり、結果を日付の開始時点でグループ化したいです。そのため、toStartOfDay(timestamp)が主キーに追加されました
  • 集約結果を保存するためのフィールドmax_hitssum_hitsを追加しました
  • max_hitssum_hitsのデフォルト値をhitsに設定することは、SET句に基づいて、ロジックが機能するために必要です

ホット/ウォーム/コールドアーキテクチャの実装

:::note ClickHouse Cloudを使用している場合、このレッスンの手順は適用されません。ClickHouse Cloudでは、古いデータを移動するといったことを気にする必要はありません。 :::

大量のデータを扱う際に一般的な手法として、データが古くなるにつれてデータを移動する方法があります。以下はTTLコマンドのTO DISKTO VOLUME句を使用して、ClickHouseでホット/ウォーム/コールドアーキテクチャを実装する手順です。ちなみに、これをホットとコールドのものとする必要はなく、どのようなユースケースでもデータを移動するためにTTLを使用できます。

  1. TO DISKTO VOLUMEオプションは、ClickHouseの構成ファイルに定義されているディスクまたはボリュームの名前を指します。ディスクを定義する新しいファイルmy_system.xmlまたは任意のファイル名を作成し、そのディスクを使用するボリュームを定義します。このXMLファイルを/etc/clickhouse-server/config.d/に配置して、システムに構成を適用します:
<clickhouse>
    <storage_configuration>
        <disks>
            <default>
            </default>
           <hot_disk>
              <path>./hot/</path>
           </hot_disk>
           <warm_disk>
              <path>./warm/</path>
           </warm_disk>
           <cold_disk>
              <path>./cold/</path>
           </cold_disk>
        </disks>
        <policies>
            <default>
                <volumes>
                    <default>
                        <disk>default</disk>
                    </default>
                    <hot_volume>
                        <disk>hot_disk</disk>
                    </hot_volume>
                    <warm_volume>
                        <disk>warm_disk</disk>
                    </warm_volume>
                    <cold_volume>
                        <disk>cold_disk</disk>
                    </cold_volume>
                </volumes>
            </default>
        </policies>
    </storage_configuration>
</clickhouse>
  1. 上記の設定は、ClickHouseが読み書きできるフォルダを指す三つのディスクを指しています。ボリュームは一つ以上のディスクを含むことができ、私たちは三つのディスクのためにそれぞれのボリュームを定義しました。ディスクを確認してみましょう
SELECT name, path, free_space, total_space
FROM system.disks
┌─name────────┬─path───────────┬───free_space─┬──total_space─┐
│ cold_disk   │ ./data/cold/   │ 179143311360 │ 494384795648 │
│ default     │ ./             │ 179143311360 │ 494384795648 │
│ hot_disk    │ ./data/hot/    │ 179143311360 │ 494384795648 │
│ warm_disk   │ ./data/warm/   │ 179143311360 │ 494384795648 │
└─────────────┴────────────────┴──────────────┴──────────────┘
  1. そして…ボリュームを確認しましょう:
SELECT
    volume_name,
    disks
FROM system.storage_policies
┌─volume_name─┬─disks─────────┐
│ default     │ ['default']   │
│ hot_volume  │ ['hot_disk']  │
│ warm_volume │ ['warm_disk'] │
│ cold_volume │ ['cold_disk'] │
└─────────────┴───────────────┘
  1. では、データをホット、ウォーム、そしてコールドボリューム間で移動するTTLルールを追加します:
ALTER TABLE my_table
   MODIFY TTL
      trade_date TO VOLUME 'hot_volume',
      trade_date + INTERVAL 2 YEAR TO VOLUME 'warm_volume',
      trade_date + INTERVAL 4 YEAR TO VOLUME 'cold_volume';
  1. 新しいTTLルールは材料化されるはずですが、確認のために強制することもできます:
ALTER TABLE my_table
    MATERIALIZE TTL
  1. system.partsテーブルを使って、データが期待通りのディスクに移動したかを確認してください:
Using the system.parts table, view which disks the parts are on for the crypto_prices table:

SELECT
    name,
    disk_name
FROM system.parts
WHERE (table = 'my_table') AND (active = 1)

レスポンスは以下のようになります:

┌─name────────┬─disk_name─┐
│ all_1_3_1_5 │ warm_disk │
│ all_2_2_0   │ hot_disk  │
└─────────────┴───────────┘

関連コンテンツ