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

260 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
slug: /ja/guides/developer/ttl
sidebar_label: 有効期限 (TTL)
sidebar_position: 2
keywords: [ttl, time to live, clickhouse, 古い, データ]
description: TTL (time-to-live) は、一定期間経過後に行やカラムを移動、削除、または集約する機能を指します。
---
# 有効期限 (TTL) を用いたデータ管理
## TTLの概要
TTL (time-to-live) は、一定期間経過後に行やカラムを移動、削除、または集約する機能を指します。「time-to-live」という表現は古いデータを削除することだけを意味しているように聞こえますが、TTLにはいくつかの用途があります
- 古いデータの削除: 予想どおり、指定された時間経過後に行やカラムを削除できます
- ディスク間のデータ移動: 一定時間経過後にストレージボリューム間でデータを移動できます - ホット/ウォーム/コールドアーキテクチャの展開に役立ちます
- データのロールアップ: 古いデータを削除する前に、有用な集計や計算にまとめます
:::note
TTLは、テーブル全体または特定のカラムに適用できます。
:::
## TTLの構文
`TTL`句は、カラム定義の後および/またはテーブル定義の最後に記述できます。`INTERVAL`句を使用して、時間の長さを定義します(これには`Date`または`DateTime`データ型が必要です)。たとえば、次のテーブルには`TTL`句を持つ二つのカラムがあります:
```sql
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の操作](/docs/ja/sql-reference/statements/alter/ttl.md)ページを参照してください。
:::
## TTLイベントのトリガー
期限切れの行を削除または集約する操作は即時には行われず、テーブルマージ時にのみ実行されます。アクティブにマージされていないテーブルがある場合、TTLイベントをトリガーする2つの設定があります
- `merge_with_ttl_timeout`: 削除TTLで再度マージするまでの最小遅延時間。デフォルトは14400秒4時間です。
- `merge_with_recompression_ttl_timeout`: 再圧縮TTL削除前にデータをロールアップするルールで再度マージするまでの最小遅延時間。デフォルト値は14400秒4時間です。
したがって、デフォルトでは、TTLルールは少なくとも4時間ごとにテーブルに適用されます。より頻繁にTTLルールを適用する必要がある場合は、上記の設定を変更してください。
:::note
推奨する頻繁な使用法ではありませんが、`OPTIMIZE`を使用してマージを強制することもできます:
```sql
OPTIMIZE TABLE example1 FINAL
```
`OPTIMIZE`はテーブルの部分の予定外のマージを初期化し、`FINAL`はテーブルがすでに単一部分になっている場合に再最適化を強制します。
:::
## 行の削除
一定時間経過後にテーブル全体の行を削除するには、テーブルレベルでTTLルールを定義します
```sql
CREATE TABLE customers (
timestamp DateTime,
name String,
balance Int32,
address String
)
ENGINE = MergeTree
ORDER BY timestamp
TTL timestamp + INTERVAL 12 HOUR
```
さらに、レコードの値に基づくTTLルールを定義することも可能です。
これは、条件を指定することで簡単に実装できます。
複数の条件を許可しています:
```sql
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を追加します
```sql
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`句を追加する必要があります:
```sql
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_hits`と`sum_hits`を追加しました
- `max_hits`と`sum_hits`のデフォルト値を`hits`に設定することは、`SET`句に基づいて、ロジックが機能するために必要です
## ホット/ウォーム/コールドアーキテクチャの実装
:::note
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/`に配置して、システムに構成を適用します:
```xml
<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>
```
2. 上記の設定は、ClickHouseが読み書きできるフォルダを指す三つのディスクを指しています。ボリュームは一つ以上のディスクを含むことができ、私たちは三つのディスクのためにそれぞれのボリュームを定義しました。ディスクを確認してみましょう
```sql
SELECT name, path, free_space, total_space
FROM system.disks
```
```response
┌─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 │
└─────────────┴────────────────┴──────────────┴──────────────┘
```
3. そして…ボリュームを確認しましょう:
```sql
SELECT
volume_name,
disks
FROM system.storage_policies
```
```response
┌─volume_name─┬─disks─────────┐
│ default │ ['default'] │
│ hot_volume │ ['hot_disk'] │
│ warm_volume │ ['warm_disk'] │
│ cold_volume │ ['cold_disk'] │
└─────────────┴───────────────┘
```
4. では、データをホット、ウォーム、そしてコールドボリューム間で移動する`TTL`ルールを追加します:
```sql
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';
```
5. 新しい`TTL`ルールは材料化されるはずですが、確認のために強制することもできます:
```sql
ALTER TABLE my_table
MATERIALIZE TTL
```
6. `system.parts`テーブルを使って、データが期待通りのディスクに移動したかを確認してください:
```sql
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)
```
レスポンスは以下のようになります:
```response
┌─name────────┬─disk_name─┐
│ all_1_3_1_5 │ warm_disk │
│ all_2_2_0 │ hot_disk │
└─────────────┴───────────┘
```
## 関連コンテンツ
- ブログ&ウェビナー: [Using TTL to Manage Data Lifecycles in ClickHouse](https://clickhouse.com/blog/using-ttl-to-manage-data-lifecycles-in-clickhouse)