Kafka のプロデューサ設定 acks は、書き込みの耐久性とレイテンシのトレードオフを直接左右します。単に速い/遅いではなく、ISR と min.insync.replicas(MinISR)の関係を踏まえて選ぶ必要があります。
本稿は CCDAK(Confluent Certified Developer for Apache Kafka)で問われやすい公式挙動に寄せ、実務の判断軸として使える具体策に落とし込みます。バージョン差異に敏感な部分は注意書きで保守的に扱います。
acks はプロデューサが送信後にどの段階の確認応答(ACK)を待つかを指定します。acks=0 は待たない、acks=1 はリーダーのみ、acks=all(= -1)は ISR(In-Sync Replicas)全員の ACK を待ちます。ISR はリーダーと最新のフォロワー集合で、割り当てレプリカ全員ではありません。
min.insync.replicas(MinISR)は acks=all のときに意味を持ち、成功とみなすために必要な ISR の最小人数をサーバ側で定義します。たとえばレプリケーション係数 3、MinISR=2 のトピックに acks=all で書くと、ISR が 2 以上なら成功、1 しかいなければ NotEnoughReplicas 系のエラーで失敗します。これは耐久性の下限を担保する代わりに、一部障害時は書き込み不可となる可能性があります。
| 設定 | 耐久性 | レイテンシ | 可用性(RF=3, MinISR=2 前提) |
|---|---|---|---|
| acks=0 | 最弱(未達でも成功扱い) | 最短 | 高い(待たないため影響小) |
| acks=1 | 中(リーダー故障直後にロス可能) | 低〜中 | 高い(リーダーのみ依存) |
| acks=all | 強(ISR 人数に依存) | 中〜高(遅い ISR に引きずられる) | ISR>=2 で可、ISR<2 でエラー |
acks と複製の応答フロー(概念図)
Producer --> Leader P
|
v
followers: F1, F2
acks=0: P -send-> L (即返答) [F1/F2待ちなし]
acks=1: P -send-> L -ACK-> P [F1/F2の複製は非同期]
acks=all: P -send-> L -> F1/F2
^ ^
| |
ACK(F1,F2 in ISR)
\ /
--> L -ACK-> P主要設定の関連(概念メモ)
プロデューサ側: acks, retries, delivery.timeout.ms, request.timeout.ms, enable.idempotence
ブローカー/トピック側: replication.factor, min.insync.replicas, unclean.leader.election.enable
注意: acks=all は ISR 全員の ACK。MinISR を満たせないとプロデューサはエラー(NotEnoughReplicas など)。acks=0 は送信直後に成功とみなすため、ネットワーク往復遅延がほぼ乗りません。ブローカー未到達やバッチ破棄が起きても検知できない点が本質的なリスクです。retries を増やしてもエラーが返らないので効果は限定的です。
用途としては、ロス許容のテレメトリや一時的なクリックストリームなどに絞るのが無難です。後段の集計が冪等・推定可能で、喪失に耐える設計であることを確認しましょう。
| 観点 | acks=0 の挙動 | 実務メモ | 代替 |
|---|---|---|---|
| エラー検知 | 不可 | 監視は送信側キュー枯渇など間接指標のみ | acks=1 以上 |
| 再送(retries) | 限定的効果 | 送信前例外にのみ効く | acks=1/all で有効化 |
| 順序 | 送信順で投げるのみ | サーバ側未到達も成功扱い | 冪等設計へ寄せる |
acks=0 の最短経路
Producer -> Leader (即成功返却)
(フォロワー複製は結果に影響しない)
失敗: ネットワーク断/リーダーダウンでも Producer は未検知プロデューサ設定例 (acks=0)
props.put("acks", "0");
props.put("linger.ms", 0);
props.put("batch.size", 131072);
props.put("retries", 0); // 効果は限定的
// ロス許容の用途に限定して使用acks=1 はリーダーが受領しログに追記した時点で ACK を返します。フォロワーへの複製は非同期のため、リーダー故障直後の狭い時間窓で未複製データが失われる可能性があります。多くの業務では十分なバランスですが、厳格な耐久性要件には届きません。
レイテンシは acks=all より低く出やすく、可用性も高い一方で、失敗窓を縮めるにはフォロワーの複製を速くする(ネットワーク/ストレージ健全性、適切な負荷)ことが前提です。
| タイミング | リーダー状態 | フォロワー複製 | 結果 |
|---|---|---|---|
| ACK 直後〜フォロワー未追従 | 稼働 | 未完了 | 後の故障でロス可能 |
| フォロワー追従完了後 | 稼働 | 完了 | 故障でもリーダー切替で保全 |
| 送信前障害 | ダウン | なし | クライアントがリトライで回復可能 |
acks=1 の失敗窓(概念タイムライン)
t0: send -> Leader append -> ACK to Producer
|<--- 未複製ウィンドウ --->|
フォロワー追従完了 t1
故障が [t0, t1) に発生: 未複製データは失われ得る安全側の併用設定例
props.put("acks", "1");
props.put("retries", Integer.MAX_VALUE);
props.put("delivery.timeout.ms", 120000);
props.put("request.timeout.ms", 30000);
// 再送中の順序性はクライアント/バージョンに依存。必要なら max.in.flight を下げるなどで制御acks=all は ISR 全員の ACK を待ちます。これにより最も遅い ISR にレイテンシが引っ張られますが、MinISR と組み合わせることで「少なくとも N 台に複製されなければ失敗」という耐久性下限を強制できます。
ISR が MinISR を下回る場合、プロデューサは書き込みに失敗し、例えば NotEnoughReplicas または NotEnoughReplicasAfterAppend といったエラーが返り得ます。これは可用性低下を許容してデータロスを避ける設計です。
| RF | MinISR | 現在の ISR | acks=all の結果 |
|---|---|---|---|
| 3 | 2 | 3 | 成功(レイテンシは最遅 ISR 依存) |
| 3 | 2 | 2 | 成功(ぎりぎり許容) |
| 3 | 2 | 1 | 失敗(MinISR 未満でエラー) |
acks=all と ISR/MinISR
RF=3, MinISR=2
ISR={Leader, F1, F2}
ケースA: ISR=3 -> L<=F1, F2 両方ACK -> L ACK -> P (成功)
ケースB: ISR=2 -> L<=F1のみACK -> L ACK -> P (成功)
ケースC: ISR=1 -> フォロワーACK不足 -> エラー返却トピックとクライアントの両面設定
# トピックで MinISR を設定
kafka-topics --alter --topic critical-events \
--config min.insync.replicas=2 --bootstrap-server <broker>
# プロデューサ(例)
props.put("acks", "all");
props.put("retries", Integer.MAX_VALUE);
props.put("delivery.timeout.ms", 120000);
props.put("enable.idempotence", true); // 厳密な重複排除が必要な場合
# 注意: 具体的なデフォルト値はクライアント/バージョンで異なるため、利用バージョンの公式ドキュメントを確認acks に加えて、linger.ms と batch.size は送信側の待ち時間とバッチ化を制御します。小さなメッセージ多数では linger を適度に上げてバッチ化し、ネットワーク/システムコールのオーバーヘッドを amortize するのが実務上有効です。
delivery.timeout.ms は全体のリトライ予算、request.timeout.ms は 1 リクエストの待ち時間です。圧縮(compression.type)や適切なパーティション数もレイテンシ/スループットに効きます。メトリクスではプロデューサ側の request-latency、ブローカー側の replica.lag を必ず可視化して、acks 選定の妥当性を継続検証します。
| 設定 | 主な効果 | 副作用/注意 | 適用目安 |
|---|---|---|---|
| linger.ms | 送信待ちを増やしバッチ効率化 | 待機分レイテンシ増 | 5–20ms から調整 |
| batch.size | 1 リクエスト当たりのデータ量増 | 大きすぎると待機増 | 64–256KB 程度から |
| compression.type | 帯域節約・CPU使用増 | CPU ボトルネックに注意 | snappy/zstd を比較 |
| delivery.timeout.ms | 全体の再送予算 | 短すぎると早期失敗 | >= 2 × request.timeout.ms |
レイテンシ分解のイメージ
送信待ち(linger) |-> 送信/待機(RTT×往復) |-> ブローカー処理 |-> フォロワー複製(acks依存)
|----------------- クライアント側 ------------------| |------ サーバ側 ------|遅延の予算化(ラフな見積もり)
# 例: RTT=5ms, linger=10ms, ブローカー処理=2ms, フォロワー複製=8ms
# acks=0: ~ linger(10) + 送信(OS/キュー) ≈ 10–12ms
# acks=1: linger(10) + RTT(5) + 処理(2) ≈ 17ms
# acks=all: linger(10) + RTT(5) + 処理(2) + 複製(8) ≈ 25ms
# 実際はバッチ化・負荷・GC・I/O で変動。メトリクスで補正することCCDAK では acks と MinISR、ISR の関係、障害時の結果、そして idempotent producer やトランザクションとの組み合わせを問う出題が定番です。特に「acks=all は ISR 全員であり、割り当て全レプリカではない」「MinISR 未満だと書き込みが失敗する」点の理解が重要です。
実務では、unclean.leader.election.enable を無効にしてデータロスを避ける方針が一般的です。設定のデフォルトや厳密な振る舞いはバージョン依存のため、運用環境の公式ドキュメントで最終確認してください。
| シナリオ | 推奨 acks | 追加条件 | 観察すべきメトリクス |
|---|---|---|---|
| 重要イベント(ロス不可) | all | RF≥3, MinISR≥2, idempotence 有効 | replica.lag, request-latency |
| 一般業務(バランス) | 1 | retries 大, 配信遅延監視 | failed-requests-rate |
| ロス許容・最短遅延 | 0 | 監査設計で補完 | 送信キュー滞留, ドロップ率(下流) |
acks 選定の簡易ディシジョン
ロス許容? --yes--> acks=0
|
no
v
停止中も可用性優先? --yes--> acks=1
|
no
v
acks=all (+ MinISR 設定)設定テンプレート(プロファイル別)
# Durable(ロス不可)
acks=all
retries=Integer.MAX_VALUE
delivery.timeout.ms=120000
enable.idempotence=true # 必要に応じて transactions も
# Balanced(一般業務)
acks=1
retries=Integer.MAX_VALUE
delivery.timeout.ms=120000
# Ultra-low-latency(ロス許容)
acks=0
linger.ms=0
batch.size=131072CCDAK
問題 1
レプリケーション係数 3、min.insync.replicas=2 のトピックに対し、重要な決済イベントをできる限り失わずに書き込みたい。1 台のブローカーが計画停止しても書き込みは継続したい。この要件に最も適した構成はどれか。
正解: A
RF=3, MinISR=2 なら 1 台停止でも ISR=2 を維持しやすく、acks=all で 2 台以上への複製を確認してから成功するため耐久性と可用性のバランスを満たす。B は耐久性を下げ、C はロス検知すらできない。D は ISR=2 になるだけで書けなくなる(可用性を失う)。idempotence は重複排除と順序性を補強する。
acks=all は「全レプリカ」への書き込み完了を意味しますか?
いいえ。acks=all は ISR(In-Sync Replicas)全員の ACK を意味し、割り当てられた全レプリカではありません。ISR から外れた遅延フォロワーは条件に含まれません。
acks を all にすればディスク障害でも絶対に失いませんか?
絶対ではありません。Kafka は各メッセージごとに同期フラッシュを強制しないため、単一ノード障害ではレプリケーションが主な防波堤です。acks=all と適切な MinISR(例: 2)により、少なくとも複数ノードに複製されてから成功するため耐久性は高まりますが、設計上の最悪ケースはゼロにはできません。
idempotent producer やトランザクションと acks の関係は?
冪等やトランザクションを有効にする場合、acks=all が前提(またはクライアントが自動的に同等の動作に設定)です。具体的な既定値や制約はクライアント/バージョンに依存するため、利用中の Kafka/Confluent クライアントの公式ドキュメントを確認してください。
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-...