質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.03%

pub-subモデルの冗長化について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,727

score 212

Redis等のpub-subモデルで連携しているアプリケーションで、
  1.  あるメッセージをSubscriberが受け取る
  2.  そこそこ負荷のかかる処理を実行する
  3.  処理結果をPublishする
というプロセスがあるとします。

このプロセスを冗長化(+負荷分散)したい場合、どういった方法が考えられるでしょうか?
イメージとしては、単なるHTTPで動いているWebサーバの前にロードバランサを置くような構成を、Pub/Subモデル動いているアプリケーション(群)で実現したいといった感じです。

パッと思いつくのは、
  1.  LoadBarance用のプロセスを作り、それをSubscriberにする
  2.  当該の負荷のかかるプロセスはRest等でKickできるようにしておく
  3.  LoadBarance用プロセス内部で自分でラウンドロビン等の処理を書き、割り振るサーバを決定する
  4.  割り振られたサーバはRestでメッセージを受け取り、処理結果をPublishする
といったところですが、何かデファクトスタンダード的な手法があるようであれば、ご教示いただけると幸いです。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

Pub/Subというと、通常は購読者(Subscriber)に対してメッセージを
発行(Publish)することをいうと思いますが、ここではSubscribeをメッセージの受信、
Publishをメッセージの送信としている様に読めましたが、その認識であっているでしょうか?

一般的には、Pub/Subで冗長化というと、
ブローカーやメッセージバスを冗長化するのだと思います。
Publishしたら、Subscriberに確実にメッセージが届くことを
保証するイメージです。

TatsuyaZamaさんが気にされているのは、
Subscriberが確実に処理を完了する事を保証するための冗長化と思いますが、
それはPub/Subはあまり関係しないので、質問に記述されている方法を含め、
ある意味どんな方法でもよい気がします。

ある程度Pub/Subの特徴を活かすなら、
  1. その負荷のかかる処理を実行するSubscriberを複数登録しておく。
  2. Publishされた時にそれらのSubscriberが同じ処理をする。
  3. 終わったら結果をまたPublishする。
  4. (同じ処理を複数のSubscriberで実行するので、複数のSubscriberが処理に成功すると、無駄にはなるが、それは許容する。)
という方法もあると思います。
ある種の投機的実行ですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/15 07:20

    ご回答ありがとうございます。

    >ここではSubscribeをメッセージの受信、
    Publishをメッセージの送信としている様に読めましたが、その認識であっているでしょうか?

    はい、すみません、そう解釈して頂ければと思います。


    >TatsuyaZamaさんが気にされているのは、
    >Subscriberが確実に処理を完了する事を保証するための冗長化と思いますが、

    確かにおっしゃる通り、いわゆる可用性の確保という点も大事なのですが、
    ここではそれに加えて、(このSubscriberはそこそこ負荷のかかる処理をしなければいけないので)負荷分散の要素も考えなくてはならないイメージでした。すみません、こちらの質問が分かりにくいですね。。。

    さらに、処理が終わったらその結果をもとにPublishしなければならないため、単にSubscriberを増やすとその処理完了後のメッセージが複数Publishされてしまう点も気になっています。

    よって、

    >(同じ処理を複数のSubscriberで実行するので、複数のSubscriberが処理に成功すると、無駄にはなるが、それは許容する。)

    これが許容できるケースであれば、ご提示頂いた「投機的実行」が有効かと思うのですが、許容できない場合はみなさんどうされているのかなという点が疑問でした。

    キャンセル

  • 2015/08/15 10:20 編集

    負荷分散のイメージですか。
    そうすると、Redisではないですが、
    Kafka+Stormのように、
    Pub/Subと分散実行の基盤を組み合わせるケースなどでしょうか。

    参考URL:
    http://acro-engineer.hatenablog.com/entry/2013/12/13/100129

    キャンセル

  • 2015/08/15 22:32

    ありがとうございます!
    不勉強ながらStormについては名前は聞いたことがある程度でしたが、ご提示頂いたことをキッカケに調べてみて「コレだ!」と思いました。

    なお、ご提示頂いたのはRedisではないですが、
    Redisでも同じような構成がいけそうですね。

    https://github.com/stormprocessor/storm-redis-pubsub/blob/master/src/jvm/yieldbot/storm/spout/RedisPubSubSpout.java

    キャンセル

  • 2015/08/15 23:48

    参考になって良かったです。
    spoutがあるなら、Redisでもできますね。
    Hadoop/YARN、Sparkなども選択肢に入るかも知れません。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る