JJUGナイトセミナー「メッセージングミドルウェア特集」に行ってきた #jjug

先日、JJUGナイトセミナー「メッセージングミドルウェア特集」に行ってきました。簡単に所感をまとめます。

jjug.doorkeeper.jp

メモから抜粋。(資料が公開されたら貼っておきます)

実運用して分かった Rabbit MQ の良いところ・気をつけること

  • オープンソースのメッセージブローカー
  • 複数のメッセージプロトコルに対応している
  • スタンドアローンでもクラスタ構成でも構築が可能
  • 多言語サポート
  • プラグインが豊富
    • AMQP以外のプロトコルを追加できる
    • 認証機能, 管理画面
  • Web API でリソースやトラフィックの監視が可能

  • RabbitMQ 導入前はブローカーのないキュー管理の仕組みを利用していた

    • 接続設定の変更などが面倒
    • 設定ファイルをすべてのファイルに持たせる必要がある
    • Producer, Consumer が簡単に追加できない
  • キュー管理から RabbitMQ へ

    • AMQPプロトコルをサポート
    • クライアントライブラリがある (Java, PHP)
    • クラスタ構築が簡単
    • Producer, Consumer の追加が簡単
    • トピックとキーでルーティングが可能
  • バックエンドサーバの前段に RabbitMQ のクラスタを配置
  • Java から PHP へのメッセージの受け渡しができる
  • クラスタ構成で耐障害性が高い
  • クライアントは RabbitMQ クラスタを向けるだけでよい
    • Producer, Consumer の追加が簡単
  • 現在は1クラスタで 1000万msg/day を Consumer が処理している

  • RabbitMQ の前にロードバランサーを配置してみた

    • メッセージがなくなる現象が発生
    • LBの設定でセッションが維持されずコネクションが途中で切れることが原因
    • RabbitMQ の Java クライアントにロードバランスする機能が実装されている
  • RabbitMQ はデフォルトでメッセージをディスクに書き込む設定になっている

    • 大量のメッセージが処理しきれずクラスタが応答しない現象が発生
    • メッセージをメモリで扱うように設定を変更
    • マスタ1台はディスク, スレーブ2台はメモリ
    • RabbitMQ はディスクを使うことを推奨している (メモリは特殊ケース)
  • 管理プラグインの Message Rates の設定がデフォルトで Basic モード (メッセージの流量をモニタする)

    • このオプションを無効にしたらパフォーマンスが向上した
    • メトリック監視とパフォーマンスはトレードオフ
    • スループットが要求される場合はプロビジョニングに注意
  • 無停止バージョンアップ

    1. Producer を新しい RabbitMQ クラスタに向ける
    2. クラスタに残っているメッセージを捌き切ったら旧クラスタを停止
  • ネットワーク障害時
    • クラスタを落として再起動 (ドキュメントにも書いてあるので問題なし)

40分弱でわかる Apache Kafka

  • スケーラブルな分散pub/sub型のメッセージングシステムを実現するためのミドルウェア
  • ストリーミングプラットフォーム
  • pub -> 仲介者 (ブローカー) -> sub

    • pubとsubを非同期に分離して疎結合
  • 小規模なシステムでも使える (大規模なシステムに限らない)

  • オートスケールではない
  • プロトコルは独自バイナリ
  • パーティション単位で順序を保証する

  • 複雑なデータパイプラインをシンプルにする

  • ストリーミングデータを処理する (リアルタイム処理)

  • Kafka はディスクにメッセージを書き込む

  • オフセット (Consumerが次にどこを読むか) を柔軟にコントロールできる
  • 指定時間内はデータが損失なく読み直すことができる安心感

  • ZooKeeper (分散コーディネーションシステム)

    • 高い可用性と信頼性
    • クラスタマネジメント
    • 死活監視
    • ACL情報のストア
  • Kafka で扱うメッセージは独自フォーマットのバイナリ

  • トピックはメッセージストリームのラベル
    • ラベルの名前は任意
    • Producer は1〜複数のトピックにメッセージを投げる
    • トピックは負荷分散のためパーティションに分割される
  • パーティション
  • Consumer Group
    • 複数の Consumer を論理的にグルーピングできる
    • オフセットによって Consumer Group ごとにどこまで読み込んだかを Consumer が覚えている
  • Extract -> Transform -> Load (ETL)
    • Kafka からデータを取得して加工して Kafka に戻す

メッセージキュー「Pulsar」の紹介

  • Yahoo!で開発されたpub/sub型メッセージングシステム
  • マルチテナント
    • 1つのMQに複数のサービスが同居できる
    • 他のサービスのトピックへのアクセスは認証/認可機構でブロックできる
  • トピックが階層化されている (ネームスペース単位で設定変更が可能)
  • 地理的に離れたデータセンターのクラスタ間でレプリケーション

    • すべてのデータセンターにメッセージを Publish するのは非効率
    • MQ内部でデータセンターをまたいでレプリケーションしてくれることが望ましい
    • Producer は自分のデータセンターの Pulsar にメッセージを送るだけでよい
    • あとは Pulsar がレプリケーションしてくれる
  • クライアントライブラリは Java, C++, Python

    • 多言語からは WebSocket API で利用可能
  • pub/sub はトピックURIで Pulsar に接続する

  • Subscription Type

    • Exclusive : 1つの Subscription に対して、1つの Consumer
    • Shared : 1つの Subscription に対して、複数の Consumer (Consumer Group)
    • Failover : Exclusive + Consumer が落ちたら別の Consumer に failover する
  • Consumer から Broker に ACK を返すとキューからメッセージが削除される

  • BookKeeper

    • 先行書き込みログ (SSD) と 永続化ストレージ (HDD)
    • 速度と永続性の両立を実現する

素人目ですが、後発の Pulsar はやはりいい感じに見えました。ただ、他のミドルウェアにも特徴がいろいろあって適材適所だと思うので、システムの特性に応じて選定できるようになるとよいのかなと思います。これを書いてる時点では資料は公開されてないのですが、最後にミドルウェアの比較があったので、それはぜひ読み返してみたいです。

今回はミドルウェアの話がメインでしたが、そのうちメッセージングシステムの設計の話とか聞いてみたいです。