2010年12月6日月曜日

pgpool2による負荷分散

0 コメント
PostgreSQL 9.0.1でストリーミングレプリケーションしたサーバー群を、pgpool2を使って負荷分散させてみました。
イメージはこんな感じで。


pgpool2は3.0.1を使用します。
またこの時、pgpool2のモードは、マスタースレーブモードに設定します。

前回のAをマスターとして、BとCにレプリケーションした状態に、Dというpgpool2サーバーを入れます。
また、Dのpgpool2のポートは5432とし、クライアントはDのサーバーをPostgreSQLデータベースサーバーとしてアクセスするようにします。

pgpool2をマスタースレーブモードで動作させる場合、システムDBは不要ですが、pgpool2をソースからビルドするために、PostgreSQLのライブラリなどが必要になるので、PostgreSQL 9.0.1をソースからビルドしておきます。

pgpool2をインストールします。
$ sudo mkdir /usr/local/pgpool2
$ sudo chown postgres:postgres /usr/local/pgpool2
$ cd /usr/local/src
$ sudo wget http://pgfoundry.org/frs/download.php/2841/pgpool-II-3.0.1.tar.gz
$ sudo tar zxvf pgpool-II-3.0.1.tar.gz
$ chown -R postgres:postgres pgpool-II-3.0.1
$ sudo chown -R postgres:postgres pgpool-II-3.0.1
$ su - postgres
$ cd /usr/local/src/pgpool-II-3.0.1/
$ ./configure --prefix=/usr/local/pgpool2 -with-pgsql=/usr/local/pgsql
$ make
$ make install

pgpool2を設定します。
$ cd /usr/local/pgpool2/etc/
まずpcp.confにpcp.conf.sampleをコピーして編集します。
$ cp pcp.conf.sample pcp.conf
pcp.confに、
postgres:postgresのパスワードのMD5
という記述を追加します。
postgreslのパスワードのMD5で暗号化されたものは、
../bin/pg_md5 ユーザーpostgresのパスワード
で表示されます。

pgpool.confにpgpool.conf.sample-streamをコピーして編集します。
$ cp pgpool.conf.sample-stream pgpool.conf
内容の次の箇所を変更します。
listen_addresses = '*'
port = 5432
pid_file_name = '/var/run/pgpool.pid'
# 次の3行は確認用
log_statement = true             # 実行されるSQL文を出力
log_per_node_statement = true    # どのノードでSQL文が実行されたかを出力
log_connections = true           # ノードに接続されたことを出力

# システムDBは不要だけの一応設定
system_db_hostname = 'localhost'
system_db_port = 5433  # pgpool2を5432ポートで動かすので、PostgreSQLを動かすときは5433ポートにする
system_db_dbname = 'pgpool'
system_db_schema = 'pgpool_catalog'
system_db_user = 'pgpool'
system_db_password = ''

backend_hostname0 = 'マスター(A)のホスト'
backend_port0 = 5432
backend_weight0 = 1
backend_data_directory0 = '/usr/local/pgsql/data'
backend_hostname1 = 'スレーブ(B)のホスト'
backend_port1 = 5432
backend_weight1 = 1
backend_data_directory1 = '/usr/local/pgsql/data'
backend_hostname2 = 'スレーブ(C)のホスト'
backend_port2 = 5432
backend_weight2 = 1
backend_data_directory2 = '/usr/local/pgsql/data'

実際に動かして動作確認してみます。
$ sudo /usr/local/pgpool2/bin/pgpool -n

クライアントから、Dのサーバーにポートを5432でアクセスして、更新クエリと参照クエリを適当に投げてみます。
すると、更新クエリは必ずサーバーAに送られ、参照クエリはA,B,Cのいずれかのサーバーに送られます。