[go: up one dir, main page]

メインコンテンツまでスキップ
メインコンテンツまでスキップ

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

TTLの概要

TTL(有効期限)とは、特定の時間が経過した後に行やカラムを移動、削除、または要約する機能を指します。「有効期限」という表現は古いデータの削除にのみ適用されるように思えますが、TTLにはいくつかのユースケースがあります:

  • 古いデータの削除:驚くことではありませんが、指定された時間間隔の後に行やカラムを削除できます。
  • ディスク間でのデータ移動:一定の時間が経過した後、ストレージボリューム間でデータを移動できます - ホット/ウォーム/コールドアーキテクチャを展開するのに便利です。
  • データのロールアップ:古いデータを削除する前に、さまざまな有用な集計や計算にロールアップします。
注記

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

TTLの構文

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

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カラムはタイムスタンプカラムから1ヶ月の有効期限があります。
  • yカラムはタイムスタンプカラムから1日の有効期限があります。
  • インターバルが経過すると、カラムは期限切れになります。ClickHouseはカラムの値をそのデータ型のデフォルト値に置き換えます。データ部分内のすべてのカラム値が期限切れになると、ClickHouseはこのカラムをファイルシステムのデータ部分から削除します。
注記

TTLルールは変更または削除できます。詳細については、テーブルTTLの操作ページをご覧ください。

TTLイベントのトリガー

期限切れの行の削除または集計は即座には行われず、テーブルのマージの際にのみ行われます。アクティブにマージされていないテーブルがある場合(その理由に関わらず)、TTLイベントをトリガーする2つの設定があります:

  • merge_with_ttl_timeout:削除TTLを伴うマージを繰り返す前の最小遅延(秒単位)。デフォルトは14400秒(4時間)です。
  • merge_with_recompression_ttl_timeout:再圧縮TTL(削除前にデータをロールアップするルール)を伴うマージを繰り返す前の最小遅延(秒単位)。デフォルト値:14400秒(4時間)。

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

注記

あまり良い解決策ではありません(または頻繁に使用することをお勧めしません)が、OPTIMIZEを使って強制的にマージすることもできます:

OPTIMIZE TABLE example1 FINAL

OPTIMIZEは、テーブルのパーツの未定義のマージを初期化し、FINALは、すでに1つのパーツになっている場合の再最適化を強制します。

行の削除

特定の期間経過後にテーブルから完全な行を削除するには、テーブルレベルでTTLルールを定義します:

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

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

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'

カラムの削除

行全体を削除する代わりに、残高と住所のカラムだけが期限切れになることを望むとしましょう。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)が主キーに追加されました。
  • 集計結果を格納する2つのフィールドmax_hitssum_hitsを追加しました。
  • SET句の定義に基づいてmax_hitssum_hitsのデフォルト値をhitsに設定することが必要です。

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

Not supported in ClickHouse Cloud
注記

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

大量のデータを扱う際の一般的な慣行は、データが古くなるにつれてそれを移動させることです。以下は、TTLコマンドのTO DISKおよびTO VOLUME句を使用してClickHouseでホット/ウォーム/コールドアーキテクチャを実装する手順です。(ちなみに、ホットおよびコールドである必要はありません - TTLを使用して、さまざまなユースケースに応じてデータを移動できます。)

  1. TO DISKおよびTO 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  │
└─────────────┴───────────┘