2012/01/18

DebianでPython + RabbitMQ( 2 )

前回、基本的な構築を終えたので、可用性と冗長性を加える。
RabbitMQ( 2.7.1 )には、Active/Activeクラスタリング機能が搭載されている。
これを利用すると、RabbitMQ間でキュー内容をミラーリングすることができる。
但し、キュー保存形式にDisk指定したクラスタを複数構成しても、
複製クラスタでの永続化は保証されていない。
プライマリークラスタにエンキューした内容は、複製クラスタ上のRAMへ即座に反映されるが、
Disk出力完了を待たずに同期完了として扱われる。
尚、この他に多重化モードとして、WAN間向けの「Federation」や「Shovel」がある。

クラスタリングの設定は、rabbitmqctlコマンドで行う。
複製クラスタを構築する(1Primary1Cluster構成時)
#cookie同期を全クラスタリングサーバーで実施
echo 'hogehoge' > /var/lib/rabbitmq/.erlang.cookie

#**以降、全てCluster**
#サービス初期化
rabbitmqctl stop_app
rabbitmqctl reset

#Clusterノード連携登録
#パターン1,2の何れかを実施
#
#パターン1: Primary(Disk)<->Cluster(RAM)構成時
rabbitmqctl cluster rabbit@primarymq

#パターン2: Primary(Disk)<->Cluster(Disk)構成時
rabbitmqctl cluster rabbit@primarymq rabbit@clustermq

#Cluster側RabbitMQサービス開始
rabbitmqctl start_app
以上を実行した後、
前回作成したConsumer/Producerをそれぞれプライマリとクラスタ上で実行して、
相互にキュー取得をできればクラスタリング設定は完了。

次に、縮退運転を検証する。
縮退運転の生じる状況では、
  1. Cluster上でRabbitMQが落ちたものの、他クラスタへアクセス出来る
    RabbitMQ自体の障害などで生じるケース。
    アプリ側で真っ当なコネクション管理を実装していれば、継続運転できる可能性が高い

  2. 他クラスタへアクセス出来ないが、キューが残っている
    他クラスタ側での項目1状態やネットワーク障害、ファイヤーウォールなどの設定誤り等で生じるケース。
    とりあえず残留キューを処理する。
    後は、順次他クラスタを復旧させる。
などがスプリットブレインと共に生じていると思われる。
スプリットブレインを発生させて、復元してみる。
#非同期、RabbitMQダウン前にエンキュー
python producer.py

#NICをダウンさせる
ifdown eth0

#nodedownを確認
rabbitmqctl cluster_status

#NICを復帰させる
#ダウンタイムが短い場合は、クラスタ復元処理をせずともNIC復帰後に再同期が一瞬に行われた
ifup eth0

#node_runningsを確認
rabbitmqctl cluster_status

#クラスタ再設定
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl cluster rabbit@primarymq
rabbitmqctl start_app

#RabbiMQダウン前に自身でエンキューした内容の受信
python consumer.py
などを試した結果、RabbitMQでスプリットブレインが生じると...
  • 非同期中にエンキューされた内容は、同期クラスタ間ないしエンキューしたクラスタから復旧したクラスタへ伝播しない
  • ネットワーク瞬断時は動作が安定せず、一瞬同期が行われるものの、
    継続した正常な同期は見込めない
となる。
要するに、スプリットブレインが生じたら一刻も早く復旧すべしということかと。
次回は、RabbitMQコネクション管理とprocmail周りを実装する。

0 件のコメント: