TTL(time-to-live)でデータを管理する
TTLの概要
TTL(有効期限, time-to-live)は、一定の時間が経過した後に行またはカラムを移動、削除、またはロールアップする機能を指します。「time-to-live」という表現は古いデータの削除にのみ適用されるように聞こえますが、TTLにはいくつかのユースケースがあります:
- 古いデータの削除:驚くことではありませんが、指定された時間間隔の後に行またはカラムを削除できます
- ディスク間でのデータ移動:一定の時間が経過した後、ストレージボリューム間でデータを移動できます - ホット/ウォーム/コールドアーキテクチャのデプロイに便利です
- データのロールアップ:削除する前に、古いデータをさまざまな有用な集計と計算にロールアップします
TTLはテーブル全体または特定のカラムに適用できます。
TTL構文
TTL句はカラム定義の後、またはテーブル定義の最後に指定できます。INTERVAL句を使用して期間を定義します(DateまたはDateTimeデータ型である必要があります)。たとえば、次のテーブルには TTL 句を持つ 2 つのカラムがあります:
- x列にはtimestamp列から1か月のtime to liveがあります
- y列にはtimestamp列から1日のtime to liveがあります
- 間隔が経過すると、列は期限切れになります。ClickHouseは列の値をそのデータ型のデフォルト値で置き換えます。データパート内のすべての列値が期限切れになると、ClickHouseはファイルシステム内のデータパートからこの列を削除します。
TTLルールは変更または削除できます。詳細については、テーブルTTLの操作ページを参照してください。
テーブルレベルのTTLを使用して古い行を削除する場合、TTL式で使用しているのと同じ時間フィールドの日付または月でテーブルをパーティション分割することを推奨します。
ClickHouseは個々の行を削除するよりも、パーティション全体を削除する方がはるかに効率的です。 パーティションキーがTTL式と整合していると、ClickHouseは期限切れの行を削除するためにデータパーツを書き換えるのではなく、期限切れになったときにパーティション全体を一度に削除できます。
TTLの期間に基づいてパーティションの粒度を選択します:
- 日/週単位のTTLの場合:
toYYYYMMDD(date_field)を使用して日ごとにパーティション分割する - 月/年単位のTTLの場合:
toYYYYMM(date_field)またはtoStartOfMonth(date_field)を使用して月ごとにパーティション分割する
TTLイベントのトリガー
期限切れの行の削除または集計は即座には行われません - テーブルのマージ中にのみ発生します。何らかの理由で積極的にマージされていないテーブルがある場合、TTLイベントをトリガーする2つの設定があります:
merge_with_ttl_timeout:削除TTLを使用したマージを繰り返す前の最小遅延(秒単位)。デフォルトは14400秒(4時間)です。merge_with_recompression_ttl_timeout:再圧縮TTL(削除前にデータをロールアップするルール)を使用したマージを繰り返す前の最小遅延(秒単位)。デフォルト値:14400秒(4時間)。
したがって、デフォルトでは、TTLルールは少なくとも4時間ごとにテーブルに適用されます。TTLルールをより頻繁に適用する必要がある場合は、上記の設定を変更するだけです。
素晴らしいソリューションではありません(頻繁に使用することをお勧めしません)が、OPTIMIZEを使用してマージを強制することもできます:
OPTIMIZEはテーブル内のパーツのスケジュールされていないマージを開始し、FINALはテーブルがすでに単一のパーツである場合に再最適化を強制します。
行の削除
一定時間後にテーブルから行全体を削除するには、テーブルレベルでTTLルールを定義します:
さらに、レコードの値に基づいてTTLルールを定義することも可能です。 これは、where条件を指定することで簡単に実装できます。 複数の条件が許可されています:
カラムの削除
行全体を削除する代わりに、balanceとaddressカラムだけを期限切れにしたいとします。customersテーブルを変更して、両方のカラムに2時間のTTLを追加しましょう:
ロールアップの実装
一定時間後に行を削除したいが、レポート目的でデータの一部を保持したいとします。すべての詳細は必要ありません - 履歴データのいくつかの集計結果だけです。これは、TTL式にGROUP BY句を追加し、集計結果を格納するためにテーブルにいくつかの列を追加することで実装できます。
次のhitsテーブルでは、古い行を削除したいが、行を削除する前にhits列の合計と最大値を保持したいとします。これらの値を格納するフィールドが必要で、合計と最大値をロールアップするGROUP BY句をTTL句に追加する必要があります:
hitsテーブルに関するいくつかの注意点:
TTL句のGROUP BY列はPRIMARY KEYのプレフィックスである必要があり、結果を日の開始時刻でグループ化したいので、toStartOfDay(timestamp)がプライマリキーに追加されました- 集計結果を格納するために2つのフィールドを追加しました:
max_hitsとsum_hits max_hitsとsum_hitsのデフォルト値をhitsに設定することは、SET句の定義方法に基づいて、ロジックが機能するために必要です
ホット/ウォーム/コールドアーキテクチャの実装
ClickHouse Cloudを使用している場合、このレッスンの手順は適用されません。ClickHouse Cloudで古いデータを移動することを心配する必要はありません。
大量のデータを扱う際の一般的な慣行は、データが古くなるにつれてそのデータを移動することです。TTLコマンドのTO DISKおよびTO VOLUME句を使用してClickHouseでホット/ウォーム/コールドアーキテクチャを実装する手順は次のとおりです。(ちなみに、ホットとコールドのことである必要はありません - どのような使用例でもTTLを使用してデータを移動できます。)
TO DISKおよびTO VOLUMEオプションは、ClickHouse構成ファイルで定義されたディスクまたはボリュームの名前を参照します。ディスクを定義するmy_system.xmlという名前の新しいファイル(または任意のファイル名)を作成し、次にディスクを使用するボリュームを定義します。XMLファイルを/etc/clickhouse-server/config.d/に配置して、構成がシステムに適用されるようにします:
- 上記の構成では、ClickHouseが読み書きできるフォルダに対応する3つのディスクを定義しています。ボリュームには1つ以上のディスクを含めることができるため、3つのディスクそれぞれにボリュームを定義しました。ディスクを表示してみましょう:
- では、ボリュームも確認してみましょう:
- 次に、ホット、ウォーム、コールドの各ボリューム間でデータを移動させる
TTLルールを追加します:
- 新しい
TTLルールはマテリアライズされるはずですが、確実を期すために強制的に実行することもできます:
system.partsテーブルを使用して、データが想定どおりのディスクに移動したことを確認します:
レスポンスは次のようになります: