ブラックフライデーのセール開始からわずか10分、注文処理マイクロサービスのアラートが鳴り止まなくなりました。RabbitMQのキュー深度(Queue Depth)が限界を突破し、コンシューマーがメッセージを捌ききれずにタイムアウトが多発していたのです。MSA環境において非同期通信は生命線ですが、「使い慣れているから」という理由だけでメッセージブローカーを選ぶと、こうしたスケーラビリティの壁に激突します。本稿では、私たちが直面したRabbitMQの限界と、Kafkaへ移行すべき境界線について、実戦経験に基づき解説します。
Deep Dive: アーキテクチャの決定的違い
「どちらもメッセージを運ぶ」という点では同じですが、内部構造は水と油ほど異なります。ここを誤解していると、運用フェーズで必ず痛い目を見ます。
RabbitMQは「スマートブローカー、ダムコンシューマー(Smart Broker, Dumb Consumer)」です。ブローカーがルーティングや状態管理の責任を持ちます。
対してKafkaは「ダムブローカー、スマートコンシューマー(Dumb Broker, Smart Consumer)」です。単なるログストレージとして振る舞い、消費状態(オフセット)はクライアントが管理します。
RabbitMQは、複雑なルーティング(Topic Exchange, Header Exchange)が必要な場合や、メッセージごとのACK管理、優先順位付けが必要なタスクキューとして極めて優秀です。しかし、メッセージが消費されると消える設計のため、過去のイベントを再生(Replay)することはできません。
一方、Kafkaは分散コミットログです。ディスクへのシーケンシャル書き込みに特化しており、永続性が高く、コンシューマーが増えてもブローカーの負荷はほとんど変わりません。これが、大量のイベントストリーミング処理でKafkaが選ばれる理由です。また、Kafkaの設定ファイルやスキーマレジストリの定義は、多くの場合gitリポジトリで管理され(GitOps)、変更履歴の追跡やロールバックが容易になるよう運用されます。
RabbitMQはメモリ上で動作することを前提としています。キューが溢れてディスクへのスワップが発生し始めると、スループットは劇的に低下します。
The Solution: ユースケース別実装パターン
「どちらが優れているか」ではなく、「どのトラフィック特性に合致するか」で判断します。以下に、それぞれの強みを活かした設定例を示します。
1. RabbitMQ: 確実な配送を重視する注文処理
RabbitMQはメッセージの到達保証(At-least-once)と複雑なルーティングが得意です。以下は、Spring BootでのPublisher Confirm設定例です。ここでは信頼性を最優先しています。
2. Kafka: 超高スループットのログ収集・分析
Kafkaはバッチ処理と圧縮を駆使して、ネットワークI/Oを極限まで減らします。以下のProducer設定は、レイテンシを数ミリ秒犠牲にして、スループットを最大化する「高負荷対策」の設定です。
// Kafka Producer Configuration (Java)
// High Throughput Optimization
Properties props = new Properties();
props.put("bootstrap.servers", "broker1:9092,broker2:9092");
// 1. バッチサイズを増やす
// デフォルト16KB -> 64KB。一度に送信するバイト数を増やし、ネットワーク往復回数を減らす
props.put("batch.size", 65536);
// 2. 待機時間 (Linger)
// 即時送信せず、5ms待ってバッチを埋める。CPU負荷低減と圧縮効率向上に寄与
props.put("linger.ms", 5);
// 3. 圧縮の有効化
// snappyはCPU負荷と圧縮率のバランスが良い。帯域幅の節約に必須
props.put("compression.type", "snappy");
// 4. ACK設定
// "all"は堅牢だが遅い。ログ収集なら"1" (Leaderのみ) で十分な場合が多い
props.put("acks", "1");
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
linger.ms を大きくしすぎるとレイテンシが悪化します。また、acks=1 はリーダー障害時にデータロストのリスクがあるため、決済データなどには絶対に使用しないでください。
性能と特性の比較マトリクス
意思決定のための最終チェックリストです。
| 特性 | RabbitMQ | Apache Kafka |
|---|---|---|
| 主な用途 | 複雑なルーティング、タスクキュー | イベントストリーミング、ログ集約 |
| スループット | 4k - 10k msg/sec (構成による) | 100k - 1M+ msg/sec |
| メッセージ永続性 | 消費されると削除 (基本) | 設定期間保持 (リプレイ可能) |
| スケーリング | 垂直方向 (Vertical) 推奨 | 水平方向 (Horizontal) が容易 |
| プロトコル | AMQP, MQTT, STOMP | TCP (Binary Protocol) |
Conclusion
「RabbitMQは遅い」というのは誤りです。適切なユースケース(複雑なルーティングが必要な少〜中規模トラフィック)では、Kafkaよりも運用コストが低く、柔軟性に富んでいます。しかし、秒間数万件を超えるイベントデータや、コンシューマーが過去のデータに遡って処理を行う必要がある場合、Kafka以外の選択肢はほぼありません。
私たちのプロジェクトでは、決済トランザクション管理にはRabbitMQを残し、クリックストリームや在庫更新イベントにはKafkaを採用するハイブリッド構成に落ち着きました。単一のツールですべてを解決しようとせず、データの性質(フローか、ストックか)を見極めてアーキテクチャを決定してください。
Post a Comment