Kafkaのコンシューマラグが伸び続けているのに気づかず、ディスクI/Oがボトルネックになっていたと後から知った苦い経験があります。KafkaとRabbitMQでは詰まる場所がまったく違うと知ってから、確認すべき指標を整理し直しました。
メッセージキューの役割と特性
図1: Producer〜Broker〜Consumer の非同期処理フロー
Kafka / RabbitMQ はサービス間の非同期通信・バッファリングを担う。Kafka はログベースの高スループット設計、RabbitMQ は低レイテンシの柔軟なルーティングが得意だ。I/O スループット・OS ページキャッシュ(メモリ)・ネットワーク帯域がスケールアップの主対象となる。
ボトルネックになるリソース
| MQ 種 | ボトルネック | 確認方法 |
|---|---|---|
| Kafka | ディスク I/O(書き込みスループット)・OS ページキャッシュ・ネットワーク帯域 | iostat -x / Consumer Lag |
| RabbitMQ | メモリ(キュー蓄積)・CPU(高頻度 ACK)・ディスク(スワップ時) | Management UI / rabbitmqctl list_queues |
スケールアップの内容と効果
① Kafka:I/O スループットとページキャッシュ増強
■ Kafka 必要ディスクスループット試算
必要 MB/s = Producer throughput(MB/s) × レプリカ数 × (1 + コンシューマー数)
例:200 MB/s・レプリカ 3・コンシューマー 2 → 200 × 3 × 3 = 1,800 MB/s → NVMe SSD が必要
# JVM ヒープは最小限(ページキャッシュ優先)
# KAFKA_HEAP_OPTS="-Xmx6g -Xms6g"(残りは OS ページキャッシュへ)
iostat -x 1 10
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group my-group --describe | awk '{print $6}' | sort -n
② RabbitMQ:メモリ増強と flow control 防止
# rabbitmq.conf
vm_memory_high_watermark.relative = 0.6 # 物理メモリの 60% で flow control 開始
rabbitmqctl list_queues name messages consumers
rabbitmqctl status | grep -A5 "memory"
スケールダウンの考え方
| 状況 | スケールダウン条件 |
|---|---|
| Kafka | Consumer lag がゼロ・ディスク I/O %util < 30%・ページキャッシュに余裕あり |
| RabbitMQ | キュー蓄積ほぼゼロ・flow control 未発動・メモリ使用率 < 30% |
スケールアップ vs スケールアウト
✅ Kafka スケール判断
① Consumer lag 増加 → コンシューマー並列度(パーティション数)を増やす。② ブローカー I/O 飽和 → ブローカー追加・パーティション再分散(スケールアウト)。③ メモリ不足 → スケールアップでページキャッシュを増やす。
判断指標(監視メトリクス)
| MQ 種 | メトリクス | スケールアップの目安 |
|---|---|---|
| Kafka | ディスク %util | ≥ 70% が継続 |
| Kafka | Consumer Lag | 増加傾向が 30 分以上継続 |
| RabbitMQ | queue messages(蓄積数) | SLA 閾値を超えて増加 |
| RabbitMQ | flow control 発動回数 | > 0 が継続 |
MQ設計でよくある誤りと対処
KafkaとRabbitMQのスケールアップで繰り返される誤りと、正しい判断軸を整理する。
| 誤りのパターン | なぜ問題か | 正しいアプローチ |
|---|---|---|
| KafkaのJVMヒープを大きく設定する | KafkaはOSのページキャッシュを使ってパフォーマンスを出す。JVMヒープを大きくするとページキャッシュに使えるメモリが減り、逆に遅くなる | JVMヒープは6GB程度に抑え、残りの物理メモリをOSページキャッシュに割り当てる |
| Consumer Lagが増えているのでBrokerを増やす | Consumer側の並列度が不足している場合、Brokerを増やしてもLagは解消しない | まずパーティション数を増やしConsumerの並列数を上げる。Brokerは I/O %utilが70%超のときに追加 |
| RabbitMQのflow controlが出たのでCPUを増やす | flow controlはメモリ閾値超過が原因であることが多くCPU増加では解消しない | vm_memory_high_watermarkを確認してメモリを増強する。キュー設計も見直してメッセージの蓄積を抑制する |
まとめ
| 項目 | 要点 |
|---|---|
| Kafka の最優先 | ディスク I/O スループット(NVMe SSD 化)とページキャッシュ(メモリ増強) |
| RabbitMQ の最優先 | メモリ増強(flow control 防止) |
| JVM ヒープ | Kafka は最小限(6GB 程度)に抑えてページキャッシュを優先する |
| スケールアウト | Kafka はパーティション追加+ブローカー追加が基本 |