Kafkaのcleanup.policyは、ログ(各パーティションのセグメント)を「時間・サイズで削除」するか、「キー単位で圧縮(コンパクション)」するか、または両方を併用するかを決めます。
本稿では、delete / compact / compact,delete をどのように使い分けるか、フィールドで起きがちな落とし穴、主要パラメータの相性、試験(CCAAK)で問われやすい観点をまとめます。
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を選ぶと、コンパクションで最新化しつつ、さらに時間・サイズ上限でセグメント自体も消える点が重要です。
| 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パーティションの概念図)
deleteは最も直感的な保持戦略で、セグメントを一定期間またはサイズを超えたときに丸ごと削除します。アクティブセグメントは削除されないため、segment.msやsegment.bytesでロールを促すと保持境界が明確になります。
時間基準はメッセージタイムスタンプの種別に依存します。CreateTimeならプロデューサが付与した時刻、LogAppendTimeならブローカ到達時刻です。遅延到着や時計ずれがあるワークロードではLogAppendTimeを選ぶと保持が安定します。
compactでは、同一キーの古いレコードを間引き、最新版のみを残します。削除はtombstone(値null)で表現し、delete.retention.msの間はtombstoneを保持して、下流のコンシューマが削除を観測できるようにします。
コンパクションは非同期で、min.cleanable.dirty.ratio(前回クリーン時からの汚れ比率)が閾値を超えると対象になります。min.compaction.lag.msで「書き込まれてからすぐには圧縮しない」猶予を設けられます。高スループット環境ではlog.cleaner.threadsの並列度やI/O帯域を監視してください。
compact,deleteは「最新像を維持しつつ、ログ全体の体積も制限」したいときに有効です。コンパクションで各キーの最新版だけを残し、さらに古いセグメント自体をretention.ms/bytesで削除してディスクを抑えます。
注意点は、コンパクションが永続保持を保証しないことです。retention.msを過ぎれば、まだ必要だと思っていた過去のスナップショットを含むセグメントが削除され得ます。新規コンシューマのブートストラップや、下流の再処理窓よりも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を小さくすると保持境界の反映は早まるが、ファイル数が増えメタデータ負荷が上がります。
代表的な設定コマンド例(バージョンによりスクリプト名・オプションは差異あり)
# 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:
監視では、ディスク使用率、パーティションごとのログサイズ、セグメント数、Log Cleanerの稼働状況(スレッドのバックログ、処理レート)を追います。保持ポリシー変更後は、想定どおりにセグメントがロール・削除されているかをブローカログとメトリクスで確認します。
トラブル時は、対象トピックの有効設定(brokerデフォルトとトピック上書き)を再確認し、retention.ms / retention.bytes / segment.ms / delete.retention.ms / min.cleanable.dirty.ratioの相互作用を洗い出します。特にcompact,deleteで初期同期に失敗する場合、retention.msが短すぎる可能性が高いです。
CCAAK
問題 1
あるトピックは cleanup.policy=compact,delete、retention.ms=48h、delete.retention.ms=24h。新規コンシューマがこのトピックから最新状態をブートストラップできない事象が発生した。最も妥当な原因はどれか?
正解: 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の進捗とディスク挙動を監視してください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Kafka Topic と Partition の基礎: 分散とスケーラビリティの要
CCDAK 対策と実務の両立を意識し、Topic/Partition/Replica/Consumer Group の役...
CCDAK 試験ガイド:出題範囲・配点・申込み・対策
Confluent Certified Developer for Apache Kafka (CCDAK) の出題範囲...
Confluent Certified Administrator (CCAAK) 対策: 出題範囲・配点の考え方・運用観点の要点
CCAAKに向けて、試験領域の押さえどころを運用目線で整理。プロダクションで通用する設定・監視・セキュリティの実践知を、...
Kafka の Replica と In-Sync Replicas を正しく設計する: 耐障害性と一貫性
レプリカとISRの仕組みを起点に、acks と min.insync.replicas、クリーン/アンクリーンリーダー選...
Kafka の Offset とコミット: ポジション管理と at-least-once の基礎
CCDAK 対策と実務の両立を意識して、Kafka コンシューマのオフセット管理とコミット戦略を整理。at-least-...