Nedia What's up!

ネディアのエンジニアによるIT技術やサービスの紹介・検証などをお届け!

PostgreSQLストリーミングレプリケーション 第1回 ストリーミングレプリケーションの4つの構成

PostgreSQLを使ってシステムを構築していると、レスポンス速度の改善が課題になってくることがあります。

そのような場合、まずはシステム自体のクエリの見直しを行ったり、PostgreSQL自体をチューニングし改善を行いますが、それでもまだ速度が物足りない場合にはハードウェア増強を検討することになります。

ハードウェア的には「ディスクのI/O性能の不足」か、「CPUの処理能力不足」のどちらかが原因となっていることが多く、きちんとボトルネックを見極めてハードウェア交換を行うことで速度改善ができたりします。

ところが著しくアクセスが多い場合や、重い処理を複数走らせたりする場合には、それでも速度に不満を感じる場面が出てきます。

そんなときの改善策の1つとして、PostgreSQLサーバを参照更新可能なマスターと参照のみのスレーブに分けたレプリケーション構成で運用し負荷分散を行う方法があります。

PostgreSQL 9系になってからストリーミングレプリケーション機能の強化が行われ、レプリケーション導入の敷居が下がりました。

本記事ではPostgreSQL 9.3でのストリーミングレプリケーションについて解説するとともに、実際に負荷分散としてどの程度の効果があるかを検証していきたいと思います。

全4回を予定しています。

  • 第1回 ストリーミングレプリケーションの4つの構成
  • 第2回 インストールと基本設定
  • 第3回 レプリケーション構成によるパフォーマンス比較
  • 第4回 チューニングでパフォーマンスは向上する?

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

PostgreSQLは「WAL」を「ストリーミング」してレプリケーションを実現しているため文字通りストリーミングレプリケーションと呼ばれます。

WAL(Write Ahead Logging)とは更新などの変更があった場合に、データファイルへの書き込みを行う前に、変更点(WALレコード)をログとしてファイルへ書き出す仕組みです。ちなみにトランザクションログと言われることもあります。

WALレコードを再適用すれば同じデータを復元できるため、このWALレコードを別のサーバへ渡すことで、レプリケーションを実現しています。

PostgreSQL 9
postgresql9

ちなみにPostgreSQLでレプリケーションを行う場合、pgpool-IIというミドルウェアも有名です。

PostgreSQLのストリーミングレプリケーションはWALを転送し復元するため、厳密にマスターとスレーブの内容に差分が生じる場合がありますが、pgpool-II自身が持つレプリケーション機能ではpgpool-II自体がミドルウェアとして動作し、配下のサーバに同時に更新クエリを投げるため更新遅延が発生しない同期レプリケーションが可能です。

また、PostgreSQLにない機能を補完するため、多機能だったりしますが、一旦pgpool-IIを経由して動作するため、発生したオーバーヘッドによりクエリの性能が低下するというデメリットもあります。

pgpool-II
pgpool

4つのレプリケーション構成

PostgreSQLのストリーミングレプリケーションでは、前述のWALレコードの書き込みと応答のタイミングによって4つのレプリケーション構成が実現可能です。

実際には設定ファイル中のsynchronous_commitパラメータによって動作が変わります。

synchronous_commit値 マスターの処理 スレーブの処理 概要
on 処理完了 処理完了

マスター・スレーブ完全同期

remote_write 処理完了 メモリ書き込み処理完了 スレーブメモリ同期
local 処理完了 待たない 非同期(マスター処理のみ)
off メモリ書き込み処理完了 待たない 非同期(マスターメモリ処理のみ)

この表だけだとさすがに分り辛いので、一つずつ解説していきたいと思います。

「on」 マスター・スレーブ完全同期後応答

PostgreSQL01

スレーブのWAL同期処理が完全に終わってから応答するため、処理に一番時間がかかりますが、マスター障害時にはスレーブが最新の状態を保持できることがメリットです。

ただしマスターへ応答することが前提なため、スレーブの障害時には応答ができなくなるデメリットがあります。

「remote_write」 スレーブメモリ同期後応答

PostgreSQL02

スレーブのWAL同期がメモリ書き込み処理完了後に応答します。

「on」よりもディスクI/Oの書き込み待ちが発生しないため高速になります。

また、マスターの障害が発生した場合にでも、最新の更新を保持できます。

「on」と同様にマスターへ応答することが前提なため、スレーブの障害時には応答ができなくなるデメリットがあります。

「local」 非同期 マスター処理後応答

PostgreSQL03

マスターのWAL処理は待ちますが、スレーブの処理は待ちません。

スレーブの更新を待たないため高速ですが、マスターに障害が発生した場合には、スレーブからデータを取り出そうとしてもWAL転送が完了していない部分の更新内容を失う可能性があります。

「off」 非同期 マスターメモリ処理後応答

PostgreSQL04

マスターのWAL処理がメモリ上に書き込まれた段階で応答を返します。

マスターとスレーブが非同期のまま応答することになります。

処理を待つ時間が減るため応答速度が最も高速ですが、マスターの障害発生時にスレーブからデータを取り出そうとしても、WAL転送が完了していない部分の更新内容を失う可能性があるだけでなく、マスターからデータ復旧を行える場合でもディスク書き込みが完了していない更新内容まで失う可能性があります。

まとめ

メリット・デメリットをまとめると以下のような感じです。

synchronous_commit値 メリット デメリット
on 耐障害性がある 最も遅い
スレーブ故障時にマスターの応答ができない
remote_write Onよりも高速で、耐障害性がある スレーブ故障時にマスターの応答ができない
local 高速 更新内容を失う可能性がある
off 最も高速 更新内容を失う可能性がある

デメリットをきちんと理解したうえでリスクのあるレプリケーション構成にしてみるというものアリかもしれませんが、サーバを運用していく以上障害はつきものですので、特にマスターのディスク書き込み前に応答してしまう「off」はあまりお勧めできないように思います。

ストリーミングレプリケーションの4つの構成を理解したところで、次回は「インストールと基本設定」の予定です。お楽しみに!