|
Postgres-XC gtmの多重化(改訂3版:2011.02.25)
Postgres-XCの単一障害点であるgtmを多重化するmgtmを作ったので公表する。
これはAPPIA版の改良でJGroupsを使っている。
動機詳細にはいる前に、簡単に作成した動機を述べる。 開発の目的これを作った動機は2つある。
ディペンダブルなミドルウエアをつくるそもそもの発端は数年前に 「memcachedとPostgreSQLによるユーザ認証システムの検討」と称してあるシステムを構築したことにある。 これを現代的にリプレースするため、根本から見直して作りはじめたのがきっかけである。 基本的なアーキテクチャは下図。 gtmもmemcachedもメッセージを受け取って結果を返す状態遷移マシンとして扱うので、基本的にはどんなものにでも対応できる(はず)。 要するに図のサーバ部分はgtmでもmemcahedでも別のものでも簡単に組込みが可能なのである。 ついでに、今回の耐障害性の仕組み。これも汎用的な仕組みとしてプログラムしている。 gtmクラッシュ時の動作は以下。 フォーマルメソッド、モデル検証がどこまで適用できるか確認する
「3重化しました。しかしコンポーネントの信頼性が低いので、全体の信頼性は単体のときよりも下がりました」では意味がない。
ディペンダブルシステムについて考えていると、自然と「フォーマルメソッド」や「モデル検証」に目がいく。 批判も多いとは認識しているが、現時点での私のスタンスはここに書いてある。
とにもかくにも、やってみなければわからない。組込み分野やエンタープライズ分野では実際に使われているが、
信頼性を問われるミドルウエア分野での適用例は聞いたことがない。
準備と動作確認前置きはこれくらいにして、設定方法と動作確認方法を述べる。 Postgres-XC ver0.9.2の準備まず、こちらを参考に、Postgres-XC ver0.9.2をセットアップする。 各種jarファイルのダウンロード
起動方法mgtmはサーバgtm,coordinator1,coordinator2の3台で起動させる。 mgtm_proxyはサーバcoordinator1,coordinator2の2台で起動させる。 以下のファイル"demo.xml"を用意し、全サーバにコピーする。アイテム名がいまいちだが気にしないでほしい。 <?xml version="1.0" encoding="UTF-8"?> <conf> <gtms> <gtm> <gid>1</gid> <host>gtm</host> <port>5555</port> <port_ic>12345</port_ic> </gtm> <gtm> <gid>2</gid> <host>coordinator1</host> <port>5555</port> <port_ic>12345</port_ic> </gtm> <gtm> <gid>3</gid> <host>coordinator2</host> <port>5555</port> <port_ic>12345</port_ic> </gtm> </gtms> <proxies> <proxy> <pid>7</pid> <host>coordinator1</host> <port>6666</port> </proxy> <proxy> <pid>8</pid> <host>coordinator2</host> <port>6666</port> </proxy> </proxies> </conf> mgtm起動用スクリプトmgtm.shをサーバgtm,coordinator1,coordinator2に配置する。 #!/bin/bash export CLASSPATH=./commons-logging-1.1.1.jar:./jgroups-2.5.0-GA.jar:./mgtm-0.4.0a.jar java mgtm -f demo.xml -D . -g $1 -x $2 mgtm_proxy起動用スクリプトmgtm_proxy.shをサーバcoordinator1,coordinator2に配置する。 #!/bin/bash export CLASSPATH=./jgroups-2.5.0-GA.jar:./commons-logging-1.1.1.jar:./mgtm-0.4.0a.jar java mgtm_proxy -D . -f ./demo.xml -g $1 mgtmの起動サーバgtmで、以下のコマンドを実行する。 gtm> ./mgtm.sh 1 1000 ここで第一引数"1"はgtmのidで、demo.xmlファイルでgid=1のサーバ起動を意味する。 第二引数"1000"はグローバルトランザクションIDの初期値で適当に選んだ値である。 次いでサーバcoordinator1で、以下のコマンド: coordinator1> ./mgtm.sh 2 1000サーバcoordinator2で、以下のコマンド: coordinator2> ./mgtm.sh 3 1000を実行する。 第二引数のグローバルトランザクションIDはすべてのmgtmで同じ値を設定すること。 設定ファイルをつくろうとも考えたが面倒なので辞めた。 3台とも立ち上がると、gidが一番若いgtmサーバのコンソールに以下のメッセージが表示される。 This is a trial piece for feasibility stady. (1)This program works with Postgres-XC version 0.9.2 only. (2)You can execute pgbench, and simple queries. Ok. I'm running... Configuration File: [GTM] gid host port port_ic ----------------------------------------------- 1 gtm 5555 12345 2 coordinator1 5555 12345 3 coordinator2 5555 12345 [GTM_Proxy] pid host port ---------------------------- 7 coordinator1 6666 8 coordinator2 6666 GTM instance created. 2011/02/25 16:35:43 org.jgroups.JChannel init .... 略 ..... [Address]=/192.168.122.121[Port]=12345 [Address]=/192.168.122.121[Port]=12345 gid = 2 Leader = 1 I'm LEADER!!!! mgtm_proxyの起動"I'm LEADER!!!!"メッセージが出てリーダが選出されたら、mgtm_proxyを起動する。 サーバcoordinator1で以下のコマンド: coordinator1> mgtm_proxy 7サーバcoordinator2で以下のコマンド: coordinator2> mgtm_proxy 8をそれぞれ実行する。
以上で準備は終わりである。通常の手順でPostgres-XCのcoordinatorとdatanodeを起動し、適当にpgbenchなど実行する。
なお、mgtm_proxyの終了処理が汚いので、なかなか終了しない場合がある。これも直すのに時間がかかるので、そのまま公開することにした。 killでjavaVMごと落とせばよい。 まとめ前述したが、UIが悪い、終了処理がまずい、などなど欠点も多い。 しかしgtmの多重化が目標ではないので(ケリをつける意味で)、詰めが甘いのを承知で公開する。 動作速度であるがほどほど速いと思う。 mgtm間通信はJGroupsのUDPユニキャストを使っている。 UDPマルチキャストをつかえはもっと速くなるのは明らかだが、マルチキャストを使えない環境もありえるため、 今回はユニキャスト版を公開した。
mgtm_proxyは送信したメッセージを、mgtmは結果を、それぞれ保存しており、
各メッセージにはIDが割り振られているので、
mgtmのどれかが生きていれば処理を続けることができる。
このシステムはmgtmのクラッシュ障害に対しては完全な耐性があり、Omission障害にもほぼ耐性がある(JGroupsに依存)。 間欠障害については特に今回の場合はdatanode-mgtm_proxyやcoordinator-mgtm_proxyがランデブー通信なので、 timeout値の設定にも依存するが、それを修復不可能な障害と判断すれば縮退運転に移動するし、復活したならJGroupsの力でmgtm間のデータ一貫性は保てる。詳細な分析は後で公開できればと思っている。 ソースの公開については、かなり先になる。理由は「フォーマルメソッドやモデル検証の手法を部分的に試しつつあり、現状は公開できるレベルに到達していないため」 まだまだ試行錯誤の状態である。 「ケリをつける」については行間を読んでほしい。
Last-modified: 2012-10-28
|