【postgreSQL】Iaas+slony-Iな運用

半年ほど前から、Amazon EC2のような従量課金制のIaas(EC2ではありませんが)の上で、postgreSQL運用を行っとります。

運用中の構成を簡単に図にすると

ええ。一般的なDMZ-LAN構成ですね。
従量課金なので、必要ない時はサーバは稼動していないのです。

で、広告掲載時や繁忙期の高負荷時はIaasの得意技を利用して…

となり、参照ノードを追加しています。
稼動postgreSQLが8系ということもあり、レプリケーションslony-Iを利用しています。

では、早速、運用手順のご紹介を致します。

スレーブ追加時の手順

前提として、すでにすべてのノードにpostgres、slony-Iがインストール済み。としています。

マスタサーバで作業 レプリケーション定義ファイルを編集します。

master$ vi slon_tools.conf
 #先に定義しておくと、とても楽です。
 add_node(node     => 3,
         host     => 'x.x.x.x',
         dbname   => 'hoge',
         port     => 5432,
         user     => 'superuser ',
         password => '****');
 #稼働中セットはset1とします
 $SLONY_SETS = {
    "set1" => {
        "set_id" => 1,
        "table_id"    => 1,
        "sequence_id" => 1,
     …(省略)

新ノードをレプリケーションクラスタに追加します。

master$ slonik_store_node 3 | slonik

コマンドの中を確認しましょう。

master$ slonik_store_node 3

cluster name = CLUSTER_NAME;
 node 1 admin conninfo='host=y.y.y.y dbname=hoge user=superuser port=5432 password=password';
 node 2 admin conninfo='host=z.z.z.z dbname=hoge user=superuser port=5432 password=password';
 node 3 admin conninfo='host=x.x.x.x dbname=hoge user=superuser port=5432 password=password';

# STORE NODE
  store node (id = 3, event node = 1, comment = 'Node 3 - hoge@x.x.x.x');
  echo 'Set up replication nodes';

# STORE PATH
  echo 'Next: configure paths for each node/origin';
  store path (server = 1, client = 3, conninfo = 'host=y.y.y.y dbname=hoge user=superuser port=5432 password=password');
  store path (server = 2, client = 3, conninfo = 'host=z.z.z.z dbname=hoge  user=superuser port=5432 password=password');
  store path (server = 3, client = 1, conninfo = 'host=x.x.x.x dbname=hoge  user=superuser port=5432 password=password');
  store path (server = 3, client = 2, conninfo = 'host=x.x.x.x dbname=hoge  user=superuser port=5432 password=password');
  echo 'Replication nodes prepared';
  echo 'Please start a slon replication daemon for each node';
  • admin conninfo :ノード1(ここではマスタ)が各ノードに接続する為の情報ですね。
  • store node : ノード3を作成しました。
  • store path : 各ノードに追加されたノードのアドレスを伝播します。追加ノードには、稼動中ノードのアドレスを伝えています。

追加したノードにレプリケーションセットを定義します。

master$ slonik_subscribe_set set1 3 | slonik

こちらのコマンドは、追加ノードにset(レプリケーション対象のテーブル、シーケンス)を伝えているだけですね。

-bash-3.2$ slonik_subscribe_set set1 3
try {
  subscribe set (id = 1, provider = 1, receiver = 3, forward = yes);
}
on error {
  exit 1;
}

追加スレーブDBで作業。レプリケーションの開始。

slave2$ slon_start 3

行中の3という数字はslon_tools.confのnode=>3ということですね。
この時点で、set1に定義されているテーブルにtruncateが走り、テーブル、シーケンスの再構築が始まり、マスタの複製が出来ました。

待機中にマスタスキーマに変更があった場合

コールドスタンバイ中に、マスタスキーマに変更があった場合。
面倒ですが、マスタダンプから一度、スキーマを最構成します。(データは必要ありません)

master$ pg_dump -c -s 'hoge' > hoge.dump

スレーブにてインポート

slave2$ psql < hoge.dump
slave2$ psql 'hoge'

DBスキーマの再構築が終われば、上記、追加手順を実施します。

退縮時の操作

そして、負荷から開放されて退縮を行う時は、マスタから、

master$ slonik_drop_node 3 | slonik

この操作だけ!簡単ですね。

仮想インスタンスもOFFに

おまけ

絶賛稼働中のレプリケーションにcreate tableを走らせる

レプリケーションクラスタ全体にDDLを実行(create tableはスーパユーザ権限で作成されるので注意)

master$ slonik_execute_script 1 full_path_sqlfile | slonik

新セットとなるtable_idとseq_idの取得

master$ psql hoge
 select max(tab_id)+1 from _'CLUSTER_NAME'.sl_table; (1)
 select max(seq_id)+1 from _'CLUSTER_NAME'.sl_sequence; (1)

新セットをslon_tools.confに記述

"set2" => {
	"set_id" => 2,
	"table_id" => (1)の値,
	"sequence_id" => (2)の値,
	"pkeyedtables" => ["new_table"],
	"sequences" => ["new_table_id_seq"],
},

クラスタに新セットを追加

master$ slonik_create_set set2 | slonik

スレーブに新セット通知。スレーブのノード数分行ってください。

master$ slonik_subscribe_set set2 [node] | slonik

新セットをオリジナルセットへマージ

master$ slonik_merge_sets [マスタnode番号] [orgin set] set2 | slonik

slon_tools.confのオリジナルセットに追加セットの内容を記述。
セットのマージは実施しなくても問題ないですが、常にオリジナルセットで続けると運用が断然楽です。

まとめ

半年くらい運用してみた感じたこと
良いところ

  • 急な要件でのサーバ増設が格段に楽になった。実際はcold沢山あります。
  • WALの消失を気にすることなく、心置きなく長期間インスタンスを停止できる!お財布に優しい!
  • postgreSQLのバージョン?何それ?うまいの?
  • 操作に失敗しても DROP SCHEMA _'CLUSTER_NAME' CASCADE; slonik_uninstall_nodes | slonik できっと大丈夫!自信を持ってコマンド打とう!!

悪いところ

  • コマンド覚えるのめんどくさいお。

今後の課題

  1. postgreSQLのアップグレード
  2. マスタ分割、それに対応したslave構成。
  3. 現在、アプリケーションから参照振り分けを行っているので、バランサを導入する
  4. postgreSQLのアップグレード
  5. postgreSQLのア(ry

といったところです。。。

以上、まだまだ8系でがんばってる、お財布に優しいPostgresQLサーバ運用でした。。。