RDBMS in the Cloud: PostgreSQL on AWSを読んでみた

102件のシェア(ちょっぴり話題の記事)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

pos-005

はじめに

AWSにはRDSというマネージドなデータベースサービスがあることは皆さんご存知だと思います。そこで提供されているデータベースは、MySQL、Oracle、SQLServerの3種類です。そうです、PostgreSQLが無いのです!ナイナイ詐欺のAWSなので、そのうち出てくると思いますが、今のところはありませんので、自前で構築する必要があります。せっかく構築するなら、オンプレのコピー感覚で使うのではなく、クラウドネイティブに使いたいものです。今回は、そんなPostgreSQLをEC2上で構築するために考えるポイントをまとめたホワイトペーパーをベースに理解を深めたいと思います。

PostgreSQL on Amazon EC2

PostgreSQLは、ACID(Atomicity:原子性, Consistency:一貫性, Isolation:独立性, Durability:永続性)に対応したデータベースです。また、以下のようなキーワードを抑えておくと、より深い理解に繋がると思います。

WAL

WAL(write ahead logging)というログを先行書き込みすることで、 データベースの原子性と永続性を実現しています。そして、マスターは1つだけです。 セカンダリーのホストは、WALレコードをマスターから取得します。これにより、 レプリケーションは、ストリーミングレプリケーションによってリアルタイムに処理されるか、 遅延WALアーカイブによって処理されます。

ウォームスタンバイ

ホットスタンバイとは、セカンダリーのホストが読込みクエリーを受け取れる場合を指します。 PostgreSQLは、ウォームスタンバイと言って、WALアーカイブを受け取ることはできますが、 読込みクエリーを受け取ることはできません。

ストリーミングレプリケーション

ストリーミングレプリケーションは、PostgreSQLネイティブな方法でリアルタイムなレプリケーションを実現しています。MySQLの行レベルレプリケーションと似ている方法です。

同期と非同期のレプリケーション

PostgreSQLのレプリケーションは2つのタイプの永続性をサポートしています。同期と非同期です。 ひとつだけのレプリカは同期モードになれます。プライマリがダウンするときに備えて、同期レプリカの順序リストを 設定することができます。同期レプリカは、マスターとレプリカのネットワーク速度が遅いとパフォーマンスに影響を与えてしまいます。

カスケーディングレプリケーション

PostgreSQLのバージョン9.2では、カスケーディングレプリケーション機能が備わりました。これは、 マスターから送られてきたWALレコードを、他のレプリカであるホストに送り、レプリケーションのトポロジー(次にどこに行けば良いのか表したもの)を作成します。そして、レプリカのバックアップを作成して新しいレプリカとして繋げることができます。

再起動やリビルドを気にせずにレプリカを高速に行いたい場合はSSDストレージを使います。 オンラインで高速にレプリカのコピーを作成するのであれば、pg_basebackupを使うのは良い方法です。

PostgreSQLのセットアップ準備

PostgreSQLをインストールする先となるEBSを新規作成し、EC2にアタッチして、フォーマットして、マウントします。

  1. Amazon Linux 64-bit AMIを起動します。
  2. EBSボリュームを新規にアタッチします。(/dev/xvdfとします。)
  3. SSHで接続します。
  4. EBSボリューム用にファイルシステムをインストールします。
  5. $ sudo yum update -y
    $ sudo yum install xfsprogs -y
    $ sudo mkfs -t xfs /dev/xvdf
    
  6. マウント用にディレクトリを作成します。
  7. $ sudo mkdir -p /data
    $ sudo chown `id -u` /data
    
  8. 起動時にマウントするようにfstabを編集します。
  9. $ sudo –i
    $ echo ‘/dev/xvdf /data auto noatime,noexec,nodiratime 0 0’ >> /etc/fstab
    
  10. ボリュームをマウントします。
  11. $ sudo mount -a /dev/xvdf /data
    

PostgreSQLのインストールと起動

PostgreSQLをインストールして、マウントしたドライブをDATAディレクトリとして自動 起動できるようにします。

  1. 必要なパッケージをインストールします。
  2. $ sudo yum install postgresql postgresql-contrib postgresql-devel postgresql-server -y
    $ sudo yum install postgresql-jdbc postgresql-odbc postgresql-libs postgresql-plperl postgresql-plpython postgresql-pltcl -y
    
  3. DATAディレクトリをpostgres権限にして起動時に参照するようにします。
  4. $ sudo chown postgres:postgres /data
    $ sudo vi /etc/init.d/postgresql 
    PGDATA=/data/
    
  5. セキュリティグループで、5432ポートのInBoundを許可します。
  6. 起動設定で外部からの接続を許可します。
  7. $ sudo vi /data/postgresql.conf
    listen_addresses = '*' 
    
  8. 初期化と起動をします。
  9. $ sudo service postgresql initdb
    Initializing database:                                     [  OK  ]
    $ sudo service postgresql start
    Starting postgresql service:                               [  OK  ]
    

高速化と負荷分散のアーキテクチャー

データをSSDインスタンスストレージに格納することで高速化を図るテクニックがあります。 注意点としてインスタンスストレージはサーバ再起動時にデータが消えますのでテンポラリーデータにしてください。 具体的な手順は割愛します。

アーキテクチャーの選択

PostgreSQLをより大きな負荷環境化でスケールするために選択するアーキテクチャーについてご紹介します。

  • 機能的な分割:リソースの競合を最小限に抑えるために、マスターとレプリカに掛かる負荷を分離します。
  • 垂直スケーリング:必要なインスタンスサイズやストレージサイズに変更することで負荷を軽減します。
  • チューニング:コネクションプーリング、不必要なデータの削除、適切なパーティショニングなどを慎重に行って負荷を軽減します。
  • レプリケーション:読込みによってCPUやI/Oへの負荷が大きいのであれば、リードレプリカによって負荷を分散します。
  • シャーディング:書き込みによる負荷が大きいのであれば、複数のクラスタ間でデータを書き分けることで負荷を分散します。

アンチパターン

これらを行うにあたってアンチパターンがありますのでご紹介します。

  • 垂直スケーリング:インタンスサイズを上げることによって様々なパフォーマンスが上がるため、多くの問題を解決することができますが、 耐障害性に関する問題は解決しませんので注意が必要です。
  • スケーリング:大きなシステムが必要になったことを知ったときにステップバイステップでスケーリングすることは効率的ではありません。 これは良いエクササイズです。AWSにおいてシステムの成長に合わせたスケーリングの計画は簡単です。 システムの成長トリガーを識別するために計画が必要なのです。
  • ACID特性:ACIDはコストが掛かります。ログやセッションデータをデータベースに入れているのであれば、DynamoDBやCassandraやRiakなどのNoSQLを検討してください。
  • データベース利用:なんでもかんでもデータベースに任せないでください。キャッシュ層を使ったり、特化した検索エンジンを使ったり、 アプリケーションサーバからの利用を控えたり、いろいろ打つ手がありますので検討してください。

パフォーマンスに関するオススメ

ストレージ

いろいろな意味で、I/O性能を向上させる方法について、ある特定のケースに関係付けて、詳細な情報を提供することは困難です。 例えば、EBSボリュームでソフトウェアRAIDを組んで、パフォーマンスを向上させるとします。 あるケースでは8個でI/Oが良く向上しました。他のケースでは22個で良い結果がでました。 注意点としては、一般的なガイダンスを参考にすることと、実際にすべてをテストすることをお勧めします。

pos-000

スケーリング

小規模なスケーリング

常にAmazon EBSを使います。Amazon EBSは、書き込みキャッシュ、ランダムI/Oのパフォーマンスが良く、エフェメラルディスクと比較してデータ永続性の機能を持っています。もし、1つ以上のエフェメラルディスクを使っているならば、データをミラーするなどオペレーションで担保してください。もし、インスタンスが終了した場合、エフェメラルディスク内の全てのデータが消えてしまいます。SSDではないインスタンスストレージは、EBSよりも性能が悪いです。WALファイルをこの場所に置かないでください。

pos-001

中規模なスケーリング

ネットワークバンド幅の大きいインスタンス(m1.xlarge, c1.xlarge, m2.4xlarge)を用いてください。また、RAIDのボリューム数を増やしてください。

pos-002

大規模なスケーリング

もし、US East (Northern Virginia), US West (Oregon), Asia Pacific (Tokyo), EU (Ireland)リージョンで利用する予定であれば、クラスタコンピュートインスタンスを検討してください。これは、より大きなネットワークバンド幅でEBSとやり取りします。CC2 や CR1インスタンスは、8個以上のEBSボリュームをアタッチした際に性能を発揮します。I/Oの要求が高いアプリケーションであれば、Provisioned IOPSのEBSを用いてください。

pos-003

他にも、hi1.4xlargeインスタンスと2つのエフェメラルSSDボリュームを用いることもできます。これらは、pg_basebackupコマンドを用いたオンラインのバックアップやバックアップからリビルドを用いてレプリカを作成するのに向いています。

pos-004

PostgreSQLでRAIDを組むのであれば、effective_io_concurrencyをRAIDの数に設定することでパフォーマンスが上がります。

もし、SSDを用いてレプリカを動かしているのであれば、fsyncとfull_page_writesを全てのホストで無効にすることでパフォーマンスが上がります。

オペレーション

メンテナンスとバキューム

PostgreSQLのインスタンスに対する主なメンテナンス作業はバキュームです。バキュームをすることで古いバージョンや削除されたレコードなどの不要なブロックが解放され、フリーな領域が増えます。デフォルトで自動バキュームは有効になっていますが、無効にすることをお勧めします。なぜならば、アクセスがあまりないOFFの時間を狙ってスケジューリングすべきだからです。自動パキュームの手順は並行でワーカーが起動します。デフォルトでは3ですが、5や8に設定することもできます。システムに対する負荷に応じて、日中のしきい値を変更することは問題ありません。バキュームは高コストであることを憶えておいてください。アクセスの多いときに使いたくはないはずです。ANALYZEコマンドは、安価なだけでなく、重要なリソースについて使うことができます。

たとえば、指定されたテーブルの統計情報について頻繁に更新したい場合、以下のようなSQLを用いることができます。

ALTER TABLE stat SET (autovacuum_analyze_threshold=20);
ALTER TABLE stat SET (autovacuum_analyze_scale_factor=0.10);

ANALYZEコマンドは、以下の式によって導きだされます。

autovacuum_analyze_threshold + (autovacuum_analyze_scale_factor * # rows in table)

巨大でアクセスの多いテーブルは、一般的には、より頻繁に統計情報を更新する要因を減らす必要があります。 もし、アクセスの少ないメンテナンスに向いた時間帯があるのであれば、バキュームを実行して、 autovacuum_analyze_threshold値を増やしてください。おそらく、自動バキュームだけでは十分ではありません。 これは、サーバに対して最小のインパクトで稼働しつづけるために設計されたものです。自動バキュームのタスクは、 影響を最小限に抑えながら、負荷の増加した期間中にキャンセルすることができます。ただし、非ピーク時に通常のバキュームをスケジュールする必要があります。以下は、crontabを用いて、6時間毎に指定されたテーブルのバキュームとANALYZEを行う例です。

0 */6 * * * /opt/pg/bin/vacuumdb -z -d <database> -t <table> -Uuser_for_maintenance</p>

読込み専用サーバ

いくつかのプロジェクトでは、読込み専用のデータベースにしたいことがあります。こういった場合には、サーバのメンテナンスは不要になります。これを実現するためには、postgresql.confを以下のように編集してpg_ctlの再読み込みを含むリスタートをしてください。

transaction_read_only=on
default_transaction_read_only=on

再度書き込みを許可したければ、先ほど設定した項目をコメントにするか削除して再読み込みすることで戻せます。

スナップショットによるバックアップ

もし、ボリュームのスナップショットを実施するのであれば、以下のコマンドを事前に実行してください。

SELECT pg_start_backup(‘label’,true);

この操作はノンブロッキングで行われます。

この第2引数をtrueにすることで、できるだけ早くバックアップが出来るようにします。しかし、I/Oパフォーマンスに影響を与えます。デフォルトではfalseに設定されています。詳しくは公式ドキュメントを参照してください。

24.3. 継続的アーカイブとポイントインタイムリカバリ(PITR)

"デフォルトで、pg_start_backupは終了までに長い時間がかかる場合があります。その理由はあるチェックポイントを実行し、そして、デフォルトでは設定したチェックポイント間隔の半分である、そのチェックポイントに必要なI/Oがかなりの時間にわたって広がるためです(設定パラメータについてはcheckpoint_completion_targetを参照してください)。通常これは、問い合わせ処理における影響を極小化するので望ましいことです。"

以下はスナップショットのコマンドです。

ec2-create-snapshot -d "postgres clon" vol-24592c0e
SNAPSHOT snap-219c1308 vol-24592c0e pending 2012-12-03T01:34:12+0000 052088341151 10 postgres clon
SELECT pg_stop_backup();

これは、スナップショットを作成中にEBSのパフォーマンスに影響を与えます。もし、I/Oキャパシティが空いていなければレプリカに対して行ってください。詳しくは、以下のドキュメントを参考にしてください。

Creating Consistent EBS Snapshots with MySQL and XFS on EC2

スナップショットからのリストア

バックアップからリストアする際には、以下の手順に従ってください。

  1. スナップショットの確認をします。
  2. $ ec2-describe-snapshots
    SNAPSHOT snap-219c1308 vol-24592c0e completed 2012-12-03T01:34:12+0000 100% 052088341151 10 postgres clon
    
  3. バックアップデータの入ったスナップショット毎にAmazon EBSボリュームを作成します(1つ以上)。AWS Management Consoleやec2-describe-snapshotsコマンドを使ってスナップショットIDを確認します。
  4. $ ec2-create-volume --snapshot snap-219c1308 --availability-zone eu-west-1c
    VOLUME vol-eb1561c1 10 snap-219c1308 eu-west-1c creating 2012-12-03T10:13:44+0000
    
  5. インスタンスにボリュームをアタッチします。もし、RAIDセットをリストアするのでしたら、OS内で同じ順番で再作成さっるようにしてください。
  6. $ ec2-attach-volume -i i-96ec5edd -d /dev/sdc vol-eb1561c1
    ATTACHMENT vol-eb1561c1 i-96ec5edd /dev/sdc attaching 2012-12-03T10:23:37+0000
    
  7. ボリュームをマウントしてパーミッションの対応付けを行ってください。
  8. $ dmesg | tail
    [3889500.959401] blkfront: xvdc: barrier or flush: disabled
    [3889500.961193] xvdd: unknown partition table
    
    # mkdir -p /data
    # chown -R postgres: /data
    # echo “/dev/xvdf /data auto noatime,noexec,nodiratime 0 0” >> /etc/fstab
    # mount -a
    

リストアをするときは、マスターをどのように設定したかに寄りますが、ポイントインタイムリカバリをすることができ、レプリカを設定することができ、リストアされたデータを使ったテスト用に単独のインスタンスを立ち上げることもできます。

WALのバックアップをS3へ

以下は、WALファイルをS3にバックアップするプロジェクトです。

https://github.com/wal-e/wal-e

依存するライブラリをインストールして、setup.py installを実行してください。その際に、AWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYの値を環境変数にセットする必要があると思います。

以下のコマンドが使えます。

  • backup-push : Amazon S3バケット上でフルバックアップを行う。
  • backup-fetch : Amazon S3からフルバックアップをリストアする。
  • wal-push : アーカイブコマンドを使ってWALファイルを格納する。
  • wal-fetch : リストアコマンドを使ってWALファイルを格納する。
  • backup-list : バックアップリストの取得する。
  • delete : 指定された日付のものを削除する。

このツールは、暗号化、GPGベース、負荷計測、圧縮をサポートしています。

これらのタイプのバックアップは、Amazon EBSのスナップショットではありませんので、完了するまでに時間がかかる場合があります。利点は、彼らは非AWSマシン上で復旧を可能にするということです。

レプリケーション手法

このセクションでは、マスター、レプリカ、およびカスケーディングレプリケーションを設定する方法を確認できます。カスケードされたサーバはMulti-AZ配備として実行するように設定されています。また、バックアップターゲットとしてレプリカを使用して進めます。

基本ストリーミング設定

レプリケーションを設定する前に、別のインスタンスへのバックアップを復元することにより、ストリーミング·レプリケーション·ベースのスレーブを設定します。

スナップショットボリュームをアタッチしてマウントしたら、ホスト間でストリーミングレプリケーションを設定することができます。これは、5つのステップに分けることができます。

  1. ユーザーを作成
  2. レプリケーション·プロセスを実行するアカウントに権限を与える
  3. サーバーへのアクセスを許可する
  4. プライマリサーバを指すようにスレーブを設定
  5. レプリケーションを開始する

新しいデータベースサーバーでは、設定ファイルの最小セットを作成します。

/data/pg/recovery.conf
standby_mode = on
primary_conninfo = 'host=10.250.227.15 port=5432 user=repl password=repl'
postgresql.conf
host_standby = on

ホットスタンバイのノードとして、すべてのノードを持つことを計画している場合、データのスナップショットを実行したときに変数の値を維持するように、マスター上でこの変数を有効にすることができます。

max_connectionsやwal_levelのように、クラスタ全体で同じにしなければならない変数があります。

バックアップのためにレプリカを使うことができます。以下のバックアップツールを利用可能です。

  • snapshot : このテクニックは高速ですが、他の手順が必要です。
  • pg_basebackup : 直接バックアップするか、PITR(ポイントインタイムリカバリ)を使うことができます。
  • wal-e : Amazon S3バケットにバックアップすることができます。
  • pg_dump / pg_dumpall : これらのツールはレプリケーションセットアップのためにツールではありません。

pg_basebackupをオンラインで実行する例です。

pg_basebackup -D new_data -U replication_user -h source_host -p source_port

最小マスター構成

マスター上では、ストリーミングレプリケーションを十分に高く設定し、レプリケーションユーザを作成して、WALを冗長化する必要があります。デフォルトでは、レプリケーションユーザは作成されません。

最小限のWAL構成セットアップ:

wal_level=hot_standby
wal_keep_segments=<recommended to start >800 >
max_wal_senders=<number of servers you are planning to set up is the minimal>

ユーザの作成と認証の構成:

$ psql -Upostgres
postgres=# CREATE USER repl WITH PASSWORD 'repl';
CREATE ROLE
postgres=# ALTER USER repl REPLICATION;
ALTER ROLE
# echo "host replication repl 10.208.8.123/32 md5" >> pg_hba.conf
# service postgresql reload

チューニングできるパラメータ

内部の構成値やチューニング可能なパラメータによって、かなりのインパクトを与えることが出来ます。

いくつかの重要な値は次のとおりです。

Swappiness、vm、カーネルチューニング

  • デフォルトでは、shmmaxとshmallはとても小さな値です。これらの値は、postgresql.conf内のshared_buffersに関連していて、もし、この値をカーネルよりも大きな値にするとPostgreSQLは起動しません。
  • vm.swappinessを5未満にすることをお勧めします。必要でない限りスワップ領域を用いて回避します。

ファイルシステムのチューニング

  • XFS (nobarrier,noatime,noexec,nodiratime)
  • ext3 / ext4 : ログ用にext3や非ジャーナルファイルシステムを利用することができます。

メモリーチューニング

  • shared_buffers は、チューニングするのに最も重要で難しい変数です。とりあえず取っ掛かりとして4分の1のメモリを指定してみてください。

WAL

  • pg_xlog (WAL)フォルダーのデータを分けることを強くオススメします。WALファイルには、fsyncが大量に生成されるXFSファイルシステムに置いてください。
  • checkpoint_segments 変数の値は、インスタンス上のデータ変更に依存します。取っ掛かりとして、中ぐらいの値からはじめて以下のようなログからヒントを得てください。
  • pg_log/postgresql-2012-12-02_134148.log:LOG: checkpoints are occurring too frequently (5 seconds apart)
    pg_log/postgresql-2012-12-02_134148.log:HINT: Consider increasing the configuration parameter "checkpoint_segments".
    
  • ファイルセグメントはそれぞれ16MBで、バッチ処理でデータを追加か変更することができるならば、埋めるのは簡単になります。忙しいサーバー上で、30ファイルセグメント以上を簡単に追加することができます。
  • WALをデータと同じディレクトリーに置くなら、ext3 を使わないことをお勧めします。このファイルシステムは、fsyncを非効率に呼び出します。

pgtune

  • pgtuneは現在のサーバー構成から設定すべき値をオススメしてくれるpythonスクリプトです。以下は基本的なインストールと実行方法です。
  • wget https://github.com/gregs1104/pgtune/archive/master.zip
    unzip master.zip
    ./pgtune -i /opt/pg/data/postgresql.conf -o test.conf -TOLTP
    
  • pgtuneは面白いオプションがあります。
    • -M TOTALMEMORY, --memory=TOTALMEMORY : 合計システムメモリーが未検出の場合
    • -T DBTYPE, --type=DBTYPE : データベースタイプ、デフォルトはMixed、オプション値は、DW, OLTP, Web, Mixed, Desktop
    • -c CONNECTIONS, --connections=CONNECTIONS : 予想される接続数、デフォルトはデータベースタイプに依存します。
  • “CUSTOMIZED OPTIONS” ラベル以下の部分が新しい行です。
  • # egrep 'CUSTOMIZED' -A 40 test.conf
    # CUSTOMIZED OPTIONS
    #------------------------------------------------------------------------------
    # Add settings for extensions here
    #------------------------------------------------------------------------------
    # pgtune wizard run on 2013-02-21
    # Based on 1696956 KB RAM in the server
    #------------------------------------------------------------------------------
    default_statistics_target = 100
    maintenance_work_mem = 96MB
    checkpoint_completion_target = 0.9
    effective_cache_size = 1152MB
    work_mem = 5632kB
    wal_buffers = 8MB
    checkpoint_segments = 16
    shared_buffers = 384MB
    max_connections = 300
    
  • pgtuneは、postgresql.confの中で最も一般的な変数についてのアドバイスしますが、おそらく直接の使用量に依存するいくつかの要因と変数があります。 max_connectionsの値は、この典型的な例であり、300という値はいくつかの環境には高い値であると考えることができます。

  • pgtuneは、現在PostgreSQLのバージョン9.1をサポートしています。新しいバージョンで使用する場合は、注意する必要があります。

CloudWatchによるモニタリング

AWSは、CloudWatchにより、Amazon EC2インスタンス、EBSボリューム、その他サービスを堅牢に監視することができます。CloudWatchは、ユーザ指定によるサービス毎のしきい値をトリガーして、SMSかEメールによるアラーム通知に対応しています。例えば、ストレージのスループット値です。他の例では、インスタンスのフリーメモリ値をカスタムメトリクスとして登録してトリガーによるアラームが通知される等です。

PostgreSQLクラスターで、主に監視すべきものを以下に示します。

  • checkpoint_segmentsの警告:インスタンスのチェックポイントセグメントが不足した場合、ログに警告を書き込みます。そのエラーのログファイルを監視することによって、checkpoint_segmentsの値を大きくする必要があるかどうか、検出することができます。
  • コネクション数
  • メモリー使用量とロードアベレージ
  • スロークエリ:以下を実行
  • SELECT pid, QUERY FROM pg_stat_activity WHERE (query_start - now()) > '30 seconds'::interval;
    
  • レプリケーションラグ:レプリカ上で以下を実行
  • SELECT ( extract('epoch' from now()) - extract('epoch' from pg_last_xact_replay_timestamp())) AS result;
    

CloudWatchのカスタムメトリクスの作成方法

以下を参考にCLIをダウンロードしてください。

Amazon CloudWatch Developer Guide - Choosing A CloudWatch Interface

カスタムメトリクスの使い方は以下を参考にしてください。

Amazon CloudWatch Developer Guide - Publishing Custom Metrics

以下は、使用例です。

$ ec2-monitor-instances i-08fe4e43
i-08fe4e43 monitoring-pending
# while true ; do CloudWatch-1.0.13.4/bin/mon-put-data --metric-name backends --namespace Postgres --dimensions "InstanceId=i-08fe4e43" --value `psql -Upostgres -Atc 'SELECT sum(numbackends) FROM
pg_stat_database'` --timestamp `date +%Y-%m-%dT%H:%M:%S.000Z` ; sleep 60 ; done
# CloudWatch-1.0.13.4/bin/mon-list-metrics | grep -i backends
backends Postgres {InstanceId=i-08fe4e43}
# CloudWatch-1.0.13.4/bin/mon-get-stats backends --namespace Postgres --statistics "Average,Maximum" --dimensions "InstanceId=i-08fe4e43" --start-time 2013-03-04T23:00:00.000Z
2013-03-05 13:15:00 1.0 1.0 None
2013-03-05 13:16:00 1.0 1.0 None
2013-03-05 13:17:00 1.0 1.0 None
2013-03-05 13:22:00 1.0 1.0 None
2013-03-05 13:23:00 1.0 1.0 None
2013-03-05 13:24:00 1.0 1.0 None
…

セキュリティ

大きなトピックですので、サーバー間のSSLによる暗号化のみ詳細にご紹介します。

ディスクの暗号化

PostgreSQLは、データフォルダの暗号化についてネイティブで対応していませんが、OSやディスクの仕組みで暗号化することで実現できます。

行レベル暗号化

Pgcryptoは、/contribディレクトリーに含まれているソースディストリビューションです。詳しくはPostgreSQLのドキュメントを見てください。

付録 F. 追加で提供されるモジュール - pgcrypto

SSL

PostgreSQLをパッケージからインストールして、標準的なオプション指定をした場合、SSLは有効になっているはずです。以下のコマンド確認してみてください。

postgres=# show ssl;
ssl
-----
on

もし、ソースからインストールする場合は、configure時に--with-opensslオプションを付けてください。

以下のコンフィグオプションが使えるはずです。

#ssl_ciphers = 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH' # allowed SSL ciphers
#ssl_renegotiation_limit = 512MB # amount of data between renegotiations

データディレクトリーで、証明書へのリンクを張ってください。

lrwxrwxrwx 1 root root 36 Jan 28 16:56 server.crt -> /etc/ssl/certs/ssl-cert.pem
lrwxrwxrwx 1 root root 38 Jan 28 16:56 server.key -> etc/ssl/private/ssl-cert.key

認証とネットワーク

メインの認証に関する設定ファイルはpg_hba.confですが、postgresql.confにもlisten_addresses変数があります。設定を反映させるには再起動が必要です。一般的な方法は、ワイルドカード指定(*)で、pg_hba.confの中でホストを指定する方法です。

PostgreSQLはデフォルトで5432ポートを使用します。同じサーバーで複数起動するのであればポートとデータディレクトリーを変更する必要があります。ただし、リソース使用の点から、この方法をプロダクション環境で行うことはオススメしません。

多層アーキテクチャーのベストプラクティスは、PostgreSQLへのアクセスはセキュリティグループ内のサーバーからのみで、かつ、既知の管理化にあるIPアドレスからのみを許可することです。

サポートされている認証方法は、"trust", "reject", "md5", "password", "gss", "sspi", "krb5", "ident", "peer", "pam", "ldap", "radius" , "cert" です。

パスワードを送信する際は、"md5"を使いことをお勧めします。PostgreSQLのログイン情報を保存するためには、~/.pgpass ファイルを設定することができます。詳細については、 PostgreSQL 9.2.4文書 第 31章libpq - C ライブラリ - パスワードファイル を参照してください。

まとめ

AWSクラウドは、PostgreSQLを含め、様々なRDBMSのためのプラットフォームを提供します。 CloudWatchのような他のAWSプロダクトと簡単に統合することで、ハードウェアを自分で管理することなく、様々なアプリケーションを実行することができます。

今回は、このホワイトペーパーを読みながら、最新版のPostgreSQLが提供している機能について理解することができ、かつ、EC2上に構築しときのチェックすべきポイントを押さえることができました。実際のプロダクション環境を意識し、レプリケーション方法やチューニング項目など、なかなか知ることができない項目も多く、多くを学ぶことが出来ました。次は実務で使い続けることで、ホワイトペーパー内には載っていないノウハウも身に付くのではと思っています。でもでもでもでもーーーー、RDS(PostgreSQL)にも期待していますよっ!!

参考資料

RDBMS in the Cloud: PostgreSQL on AWS

wikipedia - ACID

wikipedia - ログ先行書き込み