Skip to content

Droongaノードの死活管理をSerfで行う手順

YUKI "Piro" Hiroshi edited this page May 7, 2014 · 33 revisions

実験環境(仮想環境)の構築に基づいて、以下の3ノードがセットアップ済みであると仮定する。

  • node0: 192.168.100.50
  • node1: 192.168.100.51
  • node2: 192.168.100.52

Serfのインストール

各ノード上で行う。

  1. ダウンロードページからバイナリを入手し、パスの通ったディレクトリに実行ファイルを設置する。

    % wget https://dl.bintray.com/mitchellh/serf/0.5.0_linux_amd64.zip
    % unzip 0.5.0_linux_amd64.zip
    % sudo mv serf /usr/local/bin/
    

Serfの挙動について

Serfの起動

  1. 各ノードでサービスを起動する。ノード名とバインド先IPアドレスは、自分自身を指す値とする。 ここではポート番号の指定を省略しており、Serf既定のポート7946が使われる。

    (node0)
    % serf agent -node=node0 -bind=192.168.100.50 \
                 -event-handler=/path/to/command \
                 -log-level=debug
    ----
    (node1)
    % serf agent -node=node1 -bind=192.168.100.51 \
                 -event-handler=/path/to/command \
                 -log-level=debug
    ----
    (node2)
    % serf agent -node=node2 -bind=192.168.100.52 \
                 -event-handler=/path/to/command \
                 -log-level=debug
    
    • この時、各ノードではイベントハンドラに以下の情報が渡される(以下はnode0の場合)。
      • $SERF_EVENT: member-join
      • stdin: node0 192.168.100.50

クラスタへの明示的な参加

  1. サービスを起動したコンソールとは別のコンソールで、他のノードのIPアドレスを指定してserf joinを実行する。

    (node0)
    % serf join 192.168.100.51
    % serf join 192.168.100.52
    ----
    (node1)
    % serf join 192.168.100.50
    % serf join 192.168.100.52
    ----
    (node2)
    % serf join 192.168.100.50
    % serf join 192.168.100.51
    
    • join先は、クラスタを構成する自分以外のノードであれば誰でも構わない。 (実際の運用時は、catalog.jsonからIPアドレスを収集してくることになる?)
    • 複数回joinしても問題ない。 (ただし、既にjoin済みの場合はエラーのイベントが発生するようなので、あるノードへのjoinに失敗したら次のノードにjoinを試みる、といった形でfallbackするのがよさそう。)
    • この時、各ノードではイベントハンドラに以下の情報が渡される(以下はnode0の場合)。
      • $SERF_EVENT: member-join
      • stdin: node1 192.168.100.51\nnode2 192.168.100.52
  2. クラスタへの参加に成功したかどうか、serf membersコマンドで確認する。

    % serf members
    node0  192.168.100.50:7946  alive
    node1  192.168.100.51:7946  alive
    node2  192.168.100.52:7946  alive
    

クラスタからの明示的な離脱と再参加

  1. どれか1つのノード(例えばnode1)でSerfのプロセスを終了してみる。 するとイベントが自動的にメンバーに通知されて、各メンバーが持つメンバーリストが更新される。

    • serf leaveを実行しても、自動的にプロセスが終了するので、結局はkillするのと変わりない。
    • この時、クラスタに残されたノードではイベントハンドラに以下の情報が渡される(以下はnode0の場合)。
      • $SERF_EVENT: member-leave
      • stdin: node1 192.168.100.51
  2. 他のノード(node0かnode2)でserf membersしてみる。

    (node0)
    % serf members
    node0  192.168.100.50:7946  alive
    node1  192.168.100.51:7946  left
    node2  192.168.100.52:7946  alive
    

    leftとなっているのが、離脱中のノードである。

  3. 離脱したノードで再度Serfを起動する。

    (node1)
    % serf agent -node=node1 -bind=192.168.100.51 \
                 -event-handler=/path/to/command \
                 -log-level=debug
    

    この時点ではまだ、このノードはクラスタに復帰していない。

    (node0)
    % serf members
    node0  192.168.100.50:7946  alive
    node1  192.168.100.51:7946  left
    node2  192.168.100.52:7946  alive
    ----
    (node1)
    % serf members
    node1  192.168.100.51:7946  alive
    
  4. 再度クラスタに参加する。node1から他のノードへserf joinする。

    (node1)
    % serf join 192.168.100.50
    
    • この時、クラスタに残っていたノードではイベントハンドラに以下の情報が渡される(以下はnode0の場合)。
      • $SERF_EVENT: member-join
      • stdin: node1 192.168.100.51
  5. クラスタへの参加に成功したかどうか、serf membersコマンドで確認する。

    % serf members
    node0  192.168.100.50:7946  alive
    node1  192.168.100.51:7946  alive
    node2  192.168.100.52:7946  alive
    

クラスタ全体への任意のメッセージの通知

  1. クラスタに参加中のノードからイベントを送る。

    (node0)
    % serf event "my-event" "my-data"
    
    • この時、クラスタに所属しているノードではイベントハンドラに以下の情報が渡される(以下はnode0の場合)。
      • $SERF_EVENT: user
      • $SERF_USER_EVENT: my-event
      • stdin: my-data
    • 他のノードだけでなく、自分自身にも同時に通知される。

特定ノードへの任意のメッセージの通知

  1. クラスタに参加中のノードからイベントを送る。

    (node0)
    % serf query -node=node1 "my-event" "my-data"
    
    • この時、-node オプションで指定されたノードではイベントハンドラに以下の情報が渡される(以下はnode1の場合)。
      • $SERF_EVENT: query
      • $SERF_USER_QUERY: my-event
      • stdin: my-data
    • 自分自身にも通知できる。
    • 関係ないノードには通知されない。

Droonga Engineとの連携プラン

  • Serfのインストールと起動はChefで自動化しておくのが望ましいか?
  • Serfのイベントハンドラとして機能するコマンドをDroonga Engineの`bin/handle-serf-event'として含める。 このコマンドの働きは以下の通りとする。
    • member-join, member-leaveイベントの受信時:Droonga Engineのプロセスに対して、liveなノードのリストの更新を促す。
    • user, queryイベントの受信時:ノードの死活状態の変更に関するものであった場合、Droonga Engineのプロセスに対して、liveなノードのリストの更新を促す。
  • Droonga Engineは、handle-serf-eventからの通知をトリガーとして、今持っているliveなノードのリストをメモリ上から破棄する。
    • メッセージを配送する必要が生じた時に、liveなノードのリストがメモリ上にない場合は、serf members コマンドを内部で実行して、結果をliveなノードのリストとしてメモリ上に保持する。
    • メッセージの配送先を決定するときは、メモリ上にあるliveなノードのリストに基づいて配送先を決定する。