Postgres-XC ver 0.9.1 クイックスタート & レビュー

すでにver0.9.2版を書きました。 また、 多重化gtmが動くVagrant boxを作成して公開: [Vagrant box| GitHub] したので、興味があればどうぞ。

Postgres-XCは同期マルチマスタ型のPostgreSQLクラスタシステムである。

PGClusterと競合するが、 Postgres-XCの目標は"Write-scalable"の1点で、 現時点でもデータノードが10台程度までは性能がリニアに向上しているとのベンチマークが出されている。
アーキテクチャも PGClusterと異なり、より大規模構成を意識したものに見える。

Potgres-XCのダウンロード & インストール

ダウンロード

Postgres-XCのサイトからダウンロードする。
本体の最新版は2010.6.6時点でpgxc_v0_9_1.tar.gz、各種ドキュメントもいっしょにダウンロードしておく。

pgxc_v0_9_1.tar.gz
PG-XC_Architecture.pdf
PG-XC_pgbench_Tutorial_v0_9_1.pdf
PG-XC_DBT1_Tutorial_v0_9_1.pdf
PG-XC_InstallManual_v0_9_1.pdf
PG-XC_ReferenceManual_v0_9_1.pdf  

インストール

今回は/usr/local/pgxc以下にインストールする。pgbenchもインストールする。

$ tar xvfz pgxc_v0_9_1.tar.gz
$ cd pgxc
$ export CFLAGS='-O2'
$ ./configure --prefix=/usr/local/pgxc
$ make && make install
$ cd contrib/pgbench
$ make && make install

最小構成でのシステム構築

ドキュメント"PG-XC_pgbench_Tutorial_v0_9_1.pdf"では、サーバ4台でpgbenchを実行するシステム構成が解説されている。 しかし、仮想マシンを4台準備するのも面倒なので、実験しやすいように1台のサーバ上で構成する方法を示す。

ここで説明する方法はPostgres-XC本来の目的から完全に逸脱している。 あくまで「試してみたい」という人向けである。

以下に、今回のシステム構成とポート番号を示す。

1台のサーバでPostgres-XCを構築:システム構成とポート番号

一般ユーザはcoordinatorにアクセスする。図ではcoord1とcoord2と表記している。

データは全てのdatanodeに書き込まれる。

システム全体を統合するため、Postgres-XCは"Global Transaction ID"を用いる。 Global TransactionIDを統括するのがgtm(Global Transaction Manager)である。 詳細はドキュメント"PG-XC_Architecture.pdf"を参照。

Postgres-XCは、gtmがボトルネックになるのを防ぐため、gtm-proxyを使ってgtmへのアクセス集中に因る負荷を軽減する仕組みがある。
gtmとgtm-proxyがPostgres-XCの技術的な肝だが、今回は1台のサーバ上で動作させるだけなので、 gtm-proxyは使わない。
本格的に試用するならドキュメント"PG-XC_pgbench_Tutorial_v0_9_1.pdf"や "PG-XC_DBT1_Tutorial_v0_9_1.pdf"を参照して構築すること。

gtm, coordinator, datanodeの作成

全ての要素(coordinator, datanode, gtm)は"/home/postgres/pgxc"以下にインストールする。

$ mkdir /home/postgres/pgxc
$ cd /home/postgres/pgxc
$ mkdir node1
$ mkdir node2
$ mkdir gtm
$ mkdir gtm/log
node1の準備

node1には、coordinatorとdatanodeをインストールする。
coordinatorはcoord1、datanodeはdatanode1と命名する。

$ /usr/local/pgxc/bin/initdb -D /home/postgres/pgxc/node1/coord1
$ /usr/local/pgxc/bin/initdb -D /home/postgres/pgxc/node1/datanode1

はじめにcoord1の設定を行う。"~/node1/coord1/postgresql.conf"を以下のように編集する。

~/node1/coord1/postgresql.confの編集箇所
port = 1111
num_data_nodes = 2
data_node_hosts = 'localhost,localhost'
data_node_ports = '15432,25432'
gtm_host = 'localhost'
gtm_port = 6666
gtm_coordinator = 1

クライアントがcoord1にアクセスするにはport:1111を使うことになる。
coord1には2つのdatanode: ~/node1/datanode1(localhost:15432)と~/node2/datanode2(localhost:25432)が接続される。

次にdatanode1の設定を行う。"~/node1/datanode1/postgresql.conf"を以下のように編集する。

~/node1/datanode1/postgresql.confの編集箇所
port = 15432
gtm_host = 'localhost'
gtm_port = 6666
gtm_coordinator = 11
max_prepared_transactions = 100
node2の準備

node2には、最初はdatanodeだけインストールする。
datanodeはdatanode2と命名する。

$ /usr/local/pgxc/bin/initdb -D /home/postgres/pgxc/node2/datanode2

次にdatanode2の設定を行う。"~/node2/datanode2/postgresql.conf"を以下のように編集する。

~/node2/datanode2/postgresql.confの編集箇所
port = 25432
gtm_host = 'localhost'
gtm_port = 6666
gtm_coordinator = 12
max_prepared_transactions = 100

システムの初期化

ver0.9.1では、 coordinatorが1台のときにデータベースやテーブルを作成して、 そのcoordinatorのデータを"手動"で複数のcoordinatorで共有できるようにする。
まだ、マルチマスタ状態で自由にDDLを実行できるわけではない。

なのでPostgres-XCの利用の際は下図のように、 coord1だけを起動して利用するデータベースやテーブル(今回はpgbench)をインストールし、 coord1に各種データを記録する。
その後、一旦coord1を停止して残りのcoord2を作成、改めて2つのcoordinatorを起動するという 手順が必要になる。

システム初期化時の構成

gtmの起動

はじめにgtmを起動する。gtmへのアクセスポート番号は"-p"オプションで指定する。ここではデフォルトの6666を使う。

$ /usr/local/pgxc/bin/gtm -x 1000 -D /home/postgres/pgxc/gtm -l /home/postgres/pgxc/gtm/log/gtmlog -p 6666 &
datanodeの起動

次に2つのdatanodeを起動する。

$ /usr/local/pgxc/bin/postgres -X -i -p 15432 -D /home/postgres/pgxc/node1/datanode1 &
$ /usr/local/pgxc/bin/postgres -X -i -p 25432 -D /home/postgres/pgxc/node2/datanode2 &
coordinatorの起動

最後にcoordinatorを起動する。

$ /usr/local/pgxc/bin/postgres -C -i -p 1111 -D /home/postgres/pgxc/node1/coord1 &

pgbenchのインストール

ここで、実験用にpgbenchをインストールする。

これからクライアントがアクセスするのはcoordinatorである(datanodeではない)。 coord1にアクセスするので、ポート番号1111を指定する。

まず、データベースpgbenchを作成する。coord1にアクセスして"CREATE DATABASE"を実行すると、 datanode1とdatanode2にデータベースが作成される。

$ /usr/local/pgxc/bin/psql template1 -p 1111
The session started: 10169
psql (8.4.3)
Type "help" for help.

template1=# CREATE DATABASE pgbench;
CREATE DATABASE
template1=# \q

次に、pgbenchの各種テーブルをインストールするため、"pgbench -i"を実行する。 ここでもアクセスするポート番号はcoord1の11111である。

$ pgbench -i pgbench -p 1111

実は、すでにPotgres-XCは稼働している。ここでpgbenchを実行すれば結果を返してくる。

$ pgbench pgbench -p 1111

しかし、クライアント側からみるとcoordinatorが1台しかなく、マルチマスタではない。

マルチマスタ化

いよいよPostgres-XCをマルチマスタ化する。具体的にはcoord2の設定を行い、2台のcoordinator体制にする。

coord1の停止

coord1を停止する。これによってPostgres-XCはクライアント側からみると停止している状態になる。

$ /usr/local/pgxc/bin/pg_ctl -D /home/postgres/pgxc/node1/coord1 stop
coord2の作成

coord2は、coord1をコピーして作成する。 つまり保存しているデータはcoord1とcoord2で完全に一致している状態にするということである。

$ pwd
/home/postgres/pgxc
$ cp -r node1/coord1/ node2/coord2

pg_dumpallなど使ってもよいかもしれないが、ここでは簡便かつ確実な方法を使う。

coord2の設定

coord2の設定を行う。"~/node2/coord2/postgresql.conf"を以下のように編集する。

~/node2/coord2/postgresql.confの編集箇所
port = 2222
num_data_nodes = 2
gtm_host = 'localhost'
gtm_port = 6666
gtm_coordinator = 2

pooler_port = 6668
  • ポート番号は1111から2222に変更する。
  • gtm_coordinatorの値を1から2に変更する
  • pooler_portを6668に変更する(これは同一サーバ上で稼働させる場合のみ必要)。
coordinatorの再起動

2つのcoordinator: coord1とcoord2を起動する。

$ /usr/local/pgxc/bin/postgres -C -i -p 1111 -D /home/postgres/pgxc/node1/coord1 &
$ /usr/local/pgxc/bin/postgres -C -i -p 2222 -D /home/postgres/pgxc/node2/coord2 &
クライアントからのアクセス

これでcoordinatorが2台体制になったので、coord1とcoord2のいずれにもアクセスできる。

$ pgbench -p 1111 pgbench
The session started: 15371
starting vacuum...end.
The session started: 15373
transaction type: TPC-B (sort of)
scaling factor: 1
query mode: simple
number of clients: 1
number of transactions per client: 10
number of transactions actually processed: 10/10
tps = 43.922258 (including connections establishing)
tps = 52.134382 (excluding connections establishing)


$ pgbench -p 2222 pgbench
The session started: 15380
starting vacuum...end.
The session started: 15382
transaction type: TPC-B (sort of)
scaling factor: 1
query mode: simple
number of clients: 1
number of transactions per client: 10
number of transactions actually processed: 10/10
tps = 75.704239 (including connections establishing)
tps = 79.888795 (excluding connections establishing)

停止

システムを停止するには、以下の手順で行う。

$ /usr/local/pgxc/bin/pg_ctl -D /home/postgres/pgxc/node1/coord1 stop
$ /usr/local/pgxc/bin/pg_ctl -D /home/postgres/pgxc/node2/coord2 stop
$ /usr/local/pgxc/bin/pg_ctl -D /home/postgres/pgxc/node1/datanode1 stop
$ /usr/local/pgxc/bin/pg_ctl -D /home/postgres/pgxc/node2/datanode2 stop
$ /usr/local/pgxc/bin/gtm_ctl stop -S gtm -D /home/postgres/pgxc/gtm

レビュー

更新性能

複数台のサーバを準備する余裕がないので、ベンチマークは行っていない。 よって、性能に関するコメントは控える。

公表されているベンチマークによれば、10台程度のサーバで稼働でき、性能もリニアに向上している。 コア機能の実装は成功したと判断してよいのだろう。

バージョン

"ver 0.9.1"は「更新性能のスケーラビリティ向上」という開発主目的に対する バージョン番号であると思う。開発者側の視点でのバージョン。
一般のユーザの視点からすると、RDBとして利用できない機能が多すぎるので"ver 0.3"くらいに考えておくのが無難と判断した。今後に期待である。

制限など

まだver0.9.1、個人的体感ではver0.3なので、さまざまな制約(実行できないSQLなど)がある。 ここで列挙してしまうと、それだけが切り取られて独り歩きしてしまうので、敢えて書かない。
Postgres-XCの目的と現在のバージョンを考えた上で、 ドキュメント"PG-XC_Architecture.pdf"の32p-35p「ロードマップ」を参照。 ここに、現時点でできないことが列挙してある。

耐障害性

「書き込みパフォーマンス向上」が主目的の開発者と違い、 同期マルチマスタのクラスタシステムへの 個人的な興味は冗長なマスタによる耐障害性向上」 だったりする。

現時点ではgtm(Global Transaction Manager)が単一障害点になるが、 性能が出ているのだから、ここでgtmの多重化は現実的ではないか。

gtmの多重化は分散システムの理想的な応用で、 すでにさまざまなアプローチやアルゴリズムが出尽くしていると思うので(Ex:gtm障害におけるリーダー選出アルゴリズムなど)、 実装してみるのもおもしろいかもしれない。

その他

因みにヨーロッパではPostgreSQLを使ったレプリケーションの研究事例が多い。 例えばGanymed
Postgres-Rもまだ生きている。


Last-modified: 2012-10-28