Kafka

Kafkaのcleanup.policy=delete / compact / compact,delete 使い分けと運用上の注意

2026-04-19
NicheeLab編集部

Kafkaのcleanup.policyは、ログ(各パーティションのセグメント)を「時間・サイズで削除」するか、「キー単位で圧縮(コンパクション)」するか、または両方を併用するかを決めます。

本稿では、delete / compact / compact,delete をどのように使い分けるか、フィールドで起きがちな落とし穴、主要パラメータの相性、試験(CCAAK)で問われやすい観点をまとめます。

cleanup.policyの基本と内部動作

cleanup.policyはトピック単位の設定です。deleteはセグメントを時間(retention.ms)やサイズ(retention.bytes)の条件で丸ごと削除します。compactはキーごとに最新値のみを残し、重複更新を間引きます。compact,deleteは両方を適用し、キー単位の最新のみ維持しつつ、古いセグメントを一定期間・サイズで消してディスク上限を抑えます。

deleteはアクティブセグメント(現在書き込み中)には適用されません。compactはブローカのLog Cleanerがバックグラウンドで動作し(log.cleaner.enable、log.cleaner.threads)、min.cleanable.dirty.ratioなどの条件を満たしたセグメントを対象にキー重複を除去します。tombstone(値がnullのレコード)は削除指示として扱われ、delete.retention.msの間は保持されます。

retention.msとretention.bytesは独立に評価され、どちらかの条件を満たせば古いセグメントから削除されます。compact,deleteを選ぶと、コンパクションで最新化しつつ、さらに時間・サイズ上限でセグメント自体も消える点が重要です。

  • deleteは履歴をそのまま保持してから丸ごと削除。compactはキーの最新版のみを残す(nullキーは対象外)。
  • compactの前提: キー付きメッセージ、log.cleaner.enable=true、適切なdelete.retention.ms。
  • timestamp基準の保持はlog.message.timestamp.type(CreateTime or LogAppendTime)に依存。
  • 無期限保持はretention.ms=-1 または retention.bytes=-1。
cleanup.policy保持の粒度主な利用例主な関連設定
deleteセグメント単位(時間/サイズ)イベントログ、監査ログ、時系列データretention.ms / retention.bytes / segment.ms / segment.bytes
compactキー単位(最新値+tombstone保持)KTable/状態変更ログ、CDCの最新像delete.retention.ms / min.cleanable.dirty.ratio / min.compaction.lag.ms
compact,deleteキー単位+古いセグメント削除最新像を維持しつつディスク上限を管理上記すべて(特にretention.msとdelete.retention.msの関係に注意)

セグメント削除とコンパクションの関係(1パーティションの概念図)

S0 (古い)time/size超過で削除対象compact 対象S1compact 対象キー重複を間引き最新のみS2 (アクティブ)書き込み中で削除不可S0→S2 の順に古い→新しい。アクティブ(S2)は削除されず、S0/S1 がコンパクション/削除の対象

deleteの運用ポイント(時間・サイズでの削除)

deleteは最も直感的な保持戦略で、セグメントを一定期間またはサイズを超えたときに丸ごと削除します。アクティブセグメントは削除されないため、segment.msやsegment.bytesでロールを促すと保持境界が明確になります。

時間基準はメッセージタイムスタンプの種別に依存します。CreateTimeならプロデューサが付与した時刻、LogAppendTimeならブローカ到達時刻です。遅延到着や時計ずれがあるワークロードではLogAppendTimeを選ぶと保持が安定します。

  • 保持の実効性を高めるにはsegment.msを短め(数分〜数十分)にし、セグメントをロールさせる。
  • サイズ上限(retention.bytes)は時間と独立に適用されるため、ピーク書き込み時もディスクを守れる。
  • retention.ms=0は即時削除に近いが、アクティブセグメントは残る点に注意(完全即時ではない)。
  • ディスク見積りはパーティション数×レプリカ係数×想定保持サイズ+インデックスを考慮する。

compactの運用ポイント(キー単位の最新化)

compactでは、同一キーの古いレコードを間引き、最新版のみを残します。削除はtombstone(値null)で表現し、delete.retention.msの間はtombstoneを保持して、下流のコンシューマが削除を観測できるようにします。

コンパクションは非同期で、min.cleanable.dirty.ratio(前回クリーン時からの汚れ比率)が閾値を超えると対象になります。min.compaction.lag.msで「書き込まれてからすぐには圧縮しない」猶予を設けられます。高スループット環境ではlog.cleaner.threadsの並列度やI/O帯域を監視してください。

  • キー必須。nullキーのレコードはコンパクション対象外。
  • delete.retention.msは十分長く。短すぎると新規コンシューマが削除を見逃して不整合になる恐れ。
  • レコード順序は保持されるが、古い重複が消えるため「欠番のあるオフセット」を読む前提でコンシューマを実装。
  • 大きなメッセージや巨大キーはコンパクション効率を下げる。適切なsegment.bytesと圧縮(compression.type)も検討。

compact,deleteの併用パターンと落とし穴

compact,deleteは「最新像を維持しつつ、ログ全体の体積も制限」したいときに有効です。コンパクションで各キーの最新版だけを残し、さらに古いセグメント自体をretention.ms/bytesで削除してディスクを抑えます。

注意点は、コンパクションが永続保持を保証しないことです。retention.msを過ぎれば、まだ必要だと思っていた過去のスナップショットを含むセグメントが削除され得ます。新規コンシューマのブートストラップや、下流の再処理窓よりもretention.msが短いと、完全な初期化ができないことがあります。

  • 推奨の関係: retention.ms は少なくとも delete.retention.ms より長くする(tombstoneが十分に伝搬できる)。
  • 最新像が重要だが過去全履歴は不要、かつディスク上限を守りたいケースに適合。
  • Kafka Streamsの一部トピック(例: 一部の状態やウィンドウ用)で採用されることがあるが、用途ごとに要確認。
  • レプリケーションやスナップショット復元の要件がある場合、retention.msを広めに確保するか、外部にスナップショットを逃がす。

設定チューニングの指針と実例

代表的な組み合わせは以下です。イベントログ: cleanup.policy=delete、retention.msとretention.bytesを業務SLAとディスク容量に合わせる。状態変更ログ(最新像が重要): cleanup.policy=compact、delete.retention.msは少なくとも下流の取り込み遅延をカバー。最新像+ディスク制限: cleanup.policy=compact,delete、retention.msは初期同期や再処理窓より長く設定。

容量見積りは、1パーティションあたりの平均スループット×保持時間でおおよそのセグメント総量を見積もり、これにパーティション数とレプリカ係数を乗算、さらに10〜20%のインデックス・オーバーヘッドを見ておくのが無難です。segment.bytesを小さくすると保持境界の反映は早まるが、ファイル数が増えメタデータ負荷が上がります。

  • 概算ディスク式: 必要容量 ≈ 書込レート(B/s) × 保持秒 × パーティション数 × レプリカ係数 × 1.2
  • 時間保持優先ならsegment.msを短め、サイズ保持優先ならsegment.bytesを小さめにしてロール頻度を上げる。
  • コンパクション負荷が高いと感じたらmin.cleanable.dirty.ratioをやや上げ、log.cleaner.threadsやI/Oを増強。

代表的な設定コマンド例(バージョンによりスクリプト名・オプションは差異あり)

# 1) イベントログ(delete): 7日 or 200 GiB のどちらかに達したら削除
kafka-topics.sh --create \
  --topic app-events \
  --partitions 12 --replication-factor 3 \
  --config cleanup.policy=delete \
  --config retention.ms=$((7*24*60*60*1000)) \
  --config retention.bytes=$((200*1024*1024*1024)) \
  --config segment.ms=$((15*60*1000))

# 2) 状態変更ログ(compact): tombstoneは72時間保持
kafka-topics.sh --create \
  --topic user-profile-changelog \
  --partitions 12 --replication-factor 3 \
  --config cleanup.policy=compact \
  --config delete.retention.ms=$((72*60*60*1000)) \
  --config min.cleanable.dirty.ratio=0.5 \
  --config min.compaction.lag.ms=$((10*60*1000))

# 3) 最新像+サイズ制限(compact,delete): 最新像維持、14日超で古いセグメント削除
kafka-topics.sh --create \
  --topic account-state \
  --partitions 24 --replication-factor 3 \
  --config cleanup.policy=compact,delete \
  --config retention.ms=$((14*24*60*60*1000)) \
  --config delete.retention.ms=$((72*60*60*1000)) \
  --config segment.bytes=$((256*1024*1024))

# 4) 既存トピックの変更
kafka-configs.sh --alter --entity-type topics --entity-name app-events \
  --add-config retention.ms=$((10*24*60*60*1000))

# 5) tombstoneの送信例(キー:値形式、値省略でnull=削除指示)
# 注意: ツールやクライアントにより指定方法は異なる
kafka-console-producer.sh --broker-list localhost:9092 \
  --topic user-profile-changelog \
  --property parse.key=true --property key.separator=:
user-123:

監視・トラブルシュートとCCAAK対策ポイント

監視では、ディスク使用率、パーティションごとのログサイズ、セグメント数、Log Cleanerの稼働状況(スレッドのバックログ、処理レート)を追います。保持ポリシー変更後は、想定どおりにセグメントがロール・削除されているかをブローカログとメトリクスで確認します。

トラブル時は、対象トピックの有効設定(brokerデフォルトとトピック上書き)を再確認し、retention.ms / retention.bytes / segment.ms / delete.retention.ms / min.cleanable.dirty.ratioの相互作用を洗い出します。特にcompact,deleteで初期同期に失敗する場合、retention.msが短すぎる可能性が高いです。

  • 試験対策: deleteはセグメント単位、compactはキー単位。compactにはキーが必須でnullキーは対象外。
  • 試験対策: tombstoneはdelete.retention.msの間保持。compact,deleteではretention.ms経過でセグメントが消えるため「最新版でも永続保証ではない」。
  • 試験対策: timestamp基準はCreateTime/LogAppendTimeのどちらを採用しているかで挙動が変わる。

問題で確認

CCAAK

問題 1

あるトピックは cleanup.policy=compact,delete、retention.ms=48h、delete.retention.ms=24h。新規コンシューマがこのトピックから最新状態をブートストラップできない事象が発生した。最も妥当な原因はどれか?

  1. A. retention.ms が短く、コンパクションが終わる前に古いセグメントが削除され、完全な初期化に必要なデータが失われた
  2. B. delete.retention.ms が短く、tombstoneが永遠に残り続けている
  3. C. retention.bytes が未設定のため、サイズ上限に到達しない
  4. D. segment.ms が長すぎて、アクティブセグメントが即時に削除されてしまった

正解: A

compact,deleteでは、キー単位で最新版を残しつつ、retention.msを超えたセグメントは削除される。retention.msが短いと、コンパクション完了前に必要な履歴がセグメントごと消え、新規コンシューマが完全な最新状態を再構築できない。Bは逆で、短いとtombstoneが早く消える。Cは直接の原因になりにくい。Dはアクティブセグメントは削除されないため誤り。

よくある質問

retention.ms と retention.bytes はどちらが優先されますか?

独立に評価され、いずれかの条件を満たすと古いセグメントから削除されます。時間・サイズの両輪で上限を設ける設計が一般的です。

compactを使うとデータは永久に残りますか?

いいえ。compactは同一キーの古い更新を間引いて最新版を残す仕組みで、compact,deleteの場合はretention.ms/bytesでセグメント自体が削除されます。compactのみでもtombstoneはdelete.retention.ms経過後にクリーンアップされます。

deleteからcompact(またはcompact,delete)へ切り替える際の注意は?

全メッセージにキーが付いているかを確認し、log.cleaner.enableを有効化、delete.retention.msを十分に確保します。必要に応じてsegment.ms/bytesを見直し、切替後はLog Cleanerの進捗とディスク挙動を監視してください。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Kafka

Kafka Topic と Partition の基礎: 分散とスケーラビリティの要

CCDAK 対策と実務の両立を意識し、Topic/Partition/Replica/Consumer Group の役...

Kafka

CCDAK 試験ガイド:出題範囲・配点・申込み・対策

Confluent Certified Developer for Apache Kafka (CCDAK) の出題範囲...

Kafka

Confluent Certified Administrator (CCAAK) 対策: 出題範囲・配点の考え方・運用観点の要点

CCAAKに向けて、試験領域の押さえどころを運用目線で整理。プロダクションで通用する設定・監視・セキュリティの実践知を、...

Kafka

Kafka の Replica と In-Sync Replicas を正しく設計する: 耐障害性と一貫性

レプリカとISRの仕組みを起点に、acks と min.insync.replicas、クリーン/アンクリーンリーダー選...

Kafka

Kafka の Offset とコミット: ポジション管理と at-least-once の基礎

CCDAK 対策と実務の両立を意識して、Kafka コンシューマのオフセット管理とコミット戦略を整理。at-least-...

Kafkaの記事一覧 (100件)
© 2026 NicheeLab All rights reserved.