Kafka

Kafka のコスト最適化: パーティション数・圧縮・保持設計の実務基準

2026-04-19
NicheeLab編集部

Kafka のコスト最適化は、パーティション数・圧縮・保持(retention/compaction)の三点を揃えることから始まります。過剰なパーティションはメモリ/FD/レプリケーション流量を押し上げ、圧縮のミスマッチはCPU過負荷やスループット劣化を招き、保持ポリシーの誤りはストレージ爆発を起こします。

本稿では、公式ドキュメントの動作を前提に、試験(CCAAK)で問われやすい要点と、運用での現実解を整理します。注意点はバージョン依存の挙動を避け、安定機能(topic 設定・producer/consumer 基本設定・log compaction の原理)に絞って解説します。

パーティション数設計の原則とコスト影響

パーティション数は並列性の上限を決める一方で、1パーティションあたりのメタデータ・ページキャッシュ・ログセグメント・レプリケーションスレッド等の固定コストを持ちます。過剰に増やすと、ブローカーのメモリ消費、オープンファイル数、コントローラやメタデータ伝播の負荷が跳ね上がります。

おおまかな見積りとして、総セグメント数 ≈ パーティション数 × (アクティブ + ローテート済みセグメント)。retention.bytes/segment.bytes が大きいとセグメント数が増え、ファイルディスクリプタとディスクシークのコストが増加します。レプリケーションのネットワーク出力はおおむね 書き込みスループット × (replication.factor - 1) に比例します。

  • スループット優先の初期値: 1〜3 MB/s/パーティション程度を目安に算出し、将来成長分を乗せて決める
  • コンシューマ並列度の上限はパーティション数。グループ当たりのターゲット並列度から逆算する
  • パーティション増は縮小不可(再パーティショニングが必要)。先行しすぎない
  • ブローカー1台あたりのパーティション総数が数千規模に近づくとGCやレプリケーション遅延が増えやすい。監視して段階的に増やす

段階的なパーティション増加(縮小不可のため計画的に)

# パーティション増加。割当はクラスタのバランスを見て進める
kafka-topics.sh --bootstrap-server <broker:9092> \
  --alter --topic orders --partitions 24

# 増やしすぎ注意。割り当て後は再バランスのネットワーク/ディスクI/Oも計画に入れる

圧縮アルゴリズムの選択とチューニング

Kafka の圧縮は基本的にプロデューサ側で行い、トピック設定 compression.type=producer(デフォルト)だとプロデューサ設定が適用されます。圧縮はディスク/ネットワーク使用量を下げる一方で、CPUコストとレイテンシに影響します。アルゴリズムによる性質差を把握し、メッセージサイズ・バッチングとの相性を見て選定します。

一般に zstd は高圧縮・高CPU、lz4 は低レイテンシ・中圧縮、snappy は軽量で安定、gzip は互換性が広いがCPUが重め、無圧縮はCPU最小だが帯域・ディスクを消費します。小さすぎるバッチでは圧縮効果が出にくいため、linger.ms と batch.size を併用して有効な単位で固めるのが定石です。

  • 小〜中サイズのJSON/Avro: lz4 か zstd を検討
  • 超低レイテンシ重視: lz4/snappy + 小さめの batch
  • 帯域/ストレージが逼迫: zstd + 適度な linger.ms と大きめ batch.size
  • 圧縮はエンドツーエンド。ブローカーでの再圧縮は避け、プロデューサで決める
アルゴリズム概ねの圧縮率CPUコスト傾向スループット/遅延への影響
zstd高い(2〜5倍圧縮が出やすい)バッチ大で高効率・CPUは重め
lz4中(1.5〜3倍程度)中〜低低遅延で安定、スループット良好
snappy中(1.5〜2倍程度)安定・CPU軽め
gzip中〜高中〜高CPU負荷が効くと遅延増
noneなし最小帯域・ディスクを消費

プロデューサの圧縮とバッチング設定例

props.put("compression.type", "zstd");
props.put("linger.ms", "15");         // レイテンシ許容範囲で調整
props.put("batch.size", "131072");    // 128KB 目安(ワークロードでABテスト)
props.put("acks", "all");             // 耐障害性と再送の無駄を抑える

保持期間と削除/コンパクション戦略

保持設計は delete(時間/サイズで丸ごと削除)と compact(キーごとに最新レコードを残す)の組み合わせで決めます。最新版を必ず保持したいキー付きデータ(例: エンティティ最新状態)は compact、イベント履歴は delete が基本です。両方を併用する compact,delete は、履歴を一定期間だけ保持しつつ最新版も残したい場合に有効ですが、retention を短くしすぎるとコンパクション前に削除が進み期待を外すことがあります。

retention.bytes と retention.ms はどちらか一方(または両方)で制限可能です。ストレージ予算を厳格に守りたい場合は bytes 優先、コンプライアンスで保存期間が決まる場合は ms を優先します。segment.bytes はコンパクタの効率やファイル数、ページキャッシュ効率に効くため、I/O とメモリのバランスで決めます。

  • 最新版保証が最優先: cleanup.policy=compact(delete を付けない)
  • 履歴も直近だけ欲しい: cleanup.policy=compact,delete + retention.ms を十分に長めに
  • ストレージ上限厳守: retention.bytes を設定(replication.factor を掛けた総量で見積もる)
  • コンパクション促進: min.cleanable.dirty.ratio を下げすぎるとI/O増。既定から小刻みに調整

delete と compact の違い(概念図)

Partition-0 Log時間 →seg#1seg#2seg#3seg#4seg#5古いセグメントcompact: 同一keyの古い値は削除、最新のみ保持retention 超過 → delete により丸ごと削除アクティブセグメントcompact: キーKの {v1, v2, v3} は最終的に v3 のみが残る / delete: retention 超過セグメント単位で履歴削除

トピック保持/コンパクションの安全な組み合わせ

# 最新版保証(履歴は不要)
kafka-configs.sh --bootstrap-server <broker> --alter \
  --topic entity-state \
  --add-config cleanup.policy=compact,segment.bytes=134217728,min.cleanable.dirty.ratio=0.5

# 履歴も直近は保持(compact + delete を慎重に)
kafka-configs.sh --bootstrap-server <broker> --alter \
  --topic entity-state-history \
  --add-config cleanup.policy=compact,delete,retention.ms=1209600000,segment.ms=604800000

# ストレージ上限を厳格化(bytes優先)
kafka-configs.sh --bootstrap-server <broker> --alter \
  --topic metrics \
  --add-config retention.bytes=10737418240

スループットとストレージの見積もり手順

概算ストレージ: 書き込みレートB(バイト/秒)、圧縮後比率r(0<r<=1)、保持期間T(秒)、パーティションP、レプリカR とすると、必要ディスク総量 ≈ B × r × T × R。bytes 制限を使う場合は、retention.bytes × P × R がクラスタ消費に近い上限目安になります(オーバーヘッドは別途)。

ネットワーク複製トラフィック(ブローカー内向き): B × r × (R-1)。クライアント外向きの送信はコンシューマ数やフィルタリングに依存します。見積もり段階ではピークと平常の両方を置いて上振れを吸収できるようにします。

  • r は実測で補正。サンプル10〜30分のプロデューサ AB テストで取得
  • segment.bytes を大きくすると圧縮のまとまりは良くなるが、削除粒度が荒くなる
  • retention.ms と retention.bytes が併用される場合、どちらか早いほうで削除が進む点に注意

簡易計算のメモ(シェル)

# B=20MB/s, 圧縮後 r=0.4, R=3, T=7日
B=$((20*1024*1024))
r=0.4
R=3
T=$((7*24*3600))
echo "Disk ~= $(awk -v b=$B -v r=$r -v t=$T -v R=$R 'BEGIN{printf "%.1f GiB\n", b*r*t*R/1024/1024/1024}')"

プロデューサ/コンシューマ設定でのコスト削減

プロデューサでは、linger.ms と batch.size によるバッチング、圧縮、適切な acks により、無駄な再送と小粒度送信を抑制します。レコードが小さいほどバッチ化の恩恵は大きく、ネットワーク/ディスクのオーバーヘッド削減に直結します。

コンシューマでは、fetch.min.bytes と fetch.max.wait.ms で取り込みのまとまりを作り、max.partition.fetch.bytes と session.timeout.ms をワークロードに合わせます。過小値はRPC増加とコンテキストスイッチを増やし、CPU/ネットワークコストが上がります。

  • プロデューサ: compression.type、linger.ms、batch.size をセットで最適化
  • acks=all + 適切な retries/delivery.timeout.ms で再送の無駄を抑制
  • コンシューマ: fetch.min.bytes を 64KB〜1MB 程度からABテスト開始
  • max.in.flight.requests.per.connection は順序要件と再送率を見て調整

コンシューマのフェッチ最適化例

props.put("fetch.min.bytes", "1048576");     // 1MB まとまり
props.put("fetch.max.wait.ms", "50");         // バッチ化の待ち
props.put("max.partition.fetch.bytes", "5242880");
props.put("enable.auto.commit", "false");     // 冪等に合わせて制御

運用監視と自動化(CCAAK で問われやすい論点)

監視では、ディスク使用率(topic/partition 単位の推移)、レプリケーションの遅延(ISR・UnderReplicatedPartitions、Follower ラグ)、ネットワーク出力、コンパクション指標(ログクリーナーの進捗/JMX)、リクエスト遅延を継続可視化します。保持やコンパクションの設定変更は即時反映されるものもあるため、動的変更後は必ず挙動を追跡します。

自動化では、クォータ(プロデューサ/コンシューマ/クライアントIDごとの帯域制限)でノイジーネイバーを抑制し、ストレージしきい値でアラートと書き込み制御を組み合わせます。CCAAK では、動的設定(kafka-configs.sh)、安全なローリング適用、設定の優先順位(ブローカー < トピック < クライアント)が理解できているかが狙われます。

  • 重要JMX例: kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec/BytesOutPerSec
  • クリーナースレッド: log.cleaner.threads はディスクI/Oと相談して増減
  • クォータ: client-id 単位で write/produce/consume をレート制御

クォータ/クリーナースレッドの動的設定例

# クライアントIDごとのプロデュース帯域を制限(過負荷回避)
kafka-configs.sh --bootstrap-server <broker> --alter \
  --add-config 'producer_byte_rate=1048576' --entity-type clients --entity-name appA

# ログクリーナースレッド(ブローカー再起動が必要な場合あり。環境により動的化可否を確認)
# server.properties: log.cleaner.threads=2

問題で確認

CCAAK

問題 1

監査対応のため、各キーの最新版は必ず保持しつつ、古い値は可能な限り削減してストレージコストを下げたい。どのトピック設定が最も適切か?

  1. cleanup.policy=compact のみを設定し、segment.bytes と min.cleanable.dirty.ratio を調整する
  2. cleanup.policy=delete と retention.ms=7d のみを設定する
  3. プロデューサで compression.type=gzip を設定する(トピック設定は既定のまま)
  4. cleanup.policy=compact,delete とし、retention.ms を数時間に設定する

正解: A

最新版保持を強制するには log compaction が必須。delete のみでは最新版が retention を超えると消える恐れがある。compact と delete の併用は保持期間が短いとコンパクションが追いつかず最新版が欠落するリスクがある。圧縮方式の変更だけでは保持要件を満たせない。

よくある質問

圧縮はブローカーでも設定できますか?どこで決めるのが正しいですか?

トピックの compression.type は "producer"(既定)を推奨。実際の圧縮はプロデューサが行い、エンドツーエンドで同一アルゴリズムを通すのが効率的です。ブローカーでの再圧縮はCPU/レイテンシのコストを生むため避けるのが無難です。

compact と delete を併用すると必ず最新版が残りますか?

最新版を確実に残したいなら compact 単独が安全です。compact,delete の併用は retention を短くするとコンパクションが完了する前に古いセグメントが delete で削除され、期待どおりの最新版保持にならない可能性があります。

パーティションを増やすときの最小限の安全策は?

段階的に増やし、ブローカーのディスク・FD・レプリケーション遅延・GC を監視します。リバランス中のネットワーク/ディスク負荷を見越してメンテナンス時間帯に実施し、必要に応じてスロットリング(クォータ)を一時的に強化します。縮小は不可なので過剰に先行しないことが重要です。

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

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.