mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-17 03:42:48 +00:00
260 lines
11 KiB
Markdown
260 lines
11 KiB
Markdown
|
---
|
|||
|
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)
|