PREPARATION
受験対策

オススメ!OSS-DB情報

第10回 レプリケーションについて(その1)

レプリケーション(replication)を日本語にすると「複製」という意味になります。
PostgreSQLを含め、多くのRDBMSにはレプリケーション、つまりデータベースを複製する機能があります。
レプリケーションは、どのような目的で使われるのでしょうか。また、使うときにはどのような注意が必要なのでしょうか。そんなことを考えてみたいと思います。

レプリケーション機能を使う主要な理由の一つが負荷分散です。
大量の同時アクセス、あるいは負荷の大きな複数のアクセスがあって、コンピュータの処理能力を上回っているとき、取れる対応策として簡単に思いつくのは
(1) より処理能力の高いマシンを導入する(スケールアップ)
(2) 複数のマシンを導入して処理を分散させる(スケールアウト)
の2つがあります。

スケールアップでは、新しい、より高性能なマシンに従来と同じプログラムをインストールするだけ、つまりプログラムの変更が不要なので簡単です。しかし、マシンの性能を倍にしたとき、その価格は倍以上になることが多く、高価です。
しかも、望む性能のマシンが世の中に存在するとは限りません。2倍の性能のマシンなら手に入るかも知れませんが、10倍の性能のマシンが必要なら、ムーアの法則に期待して、数年、待つことになるでしょう。
スケールアウトはシステム構成が複雑になるので実現がやや難しいですが、安価であり、うまくすればシステムを無限に大きくすることができます。
データベースでは、レプリケーション機能を使えばスケールアウトを実現できます。
例えばデータベースの複製を10個作っておき、処理をその10台のマシンに分散させれば、理論上、1台の時の最大10倍の量の処理を行うことができます。

レプリケーションを使うもう一つの理由は可用性の向上です。
データベースの複製を作っておけば、何らかの理由で通常利用しているサーバがダウンした時でも、アクセス先を複製したデータベースに変更すれば、引き続きデータベースを利用することができます。
このとき、通常利用している方をプライマリ、待機している複製の方をスタンバイ、と呼び、複製側マシンの稼働状態などによって、コールドスタンバイ、ウォームスタンバイ、ホットスタンバイ、といった区別がされます。

レプリケーション機能を利用しているとき、データの更新に注意する必要があります。
負荷分散のためにレプリケーション機能を使ってデータベースを複製しているとき、同じデータを異なるデータベース上で同時に更新したらどうなるでしょうか。またこの場合、どのように動作するべきでしょうか。これは実は解決困難な問題です。

レプリケーション機能をデータ更新の観点から分類すると、シングルマスタレプリケーションとマルチマスタレプリケーションの2つがあります。
シングルマスタレプリケーションでは、更新可能なデータベース(マスタと呼びます)は1つだけ、それ以外の複製されたデータベース(スレーブと呼びます)は読み取り専用です。
これに対し、マルチマスタレプリケーションでは、複数、あるいはすべてのデータベースが更新可能です。
制限のないマルチマスターの方が良さそうに思えます。そもそも、どうしてデータ更新について制限のあるシングルマスタなんていう方式があるのだろう、と思われるかもしれません。これには、マルチマスタではデータの同時更新の問題の解決が難しい、また、十分な性能を出すのが難しい(負荷分散の効果が小さくなる)、という2つの理由があります。

シングルマスタでは、マスタのデータベースでしかデータを更新できませんから、同時更新に関する面倒な心配をする必要はありません。
その代わり、データベースにアクセスするアプリケーション側で多少の配慮が必要になります。レプリケーションにより複数のデータベースが稼働していますが、データを更新できるのはそのうちの1つ(マスタ)だけですから、データを更新したいアプリケーションは必ずマスタにアクセスしなければなりません。一方で、データを参照するだけのアプリケーションは、負荷分散のためにも、データを更新できないスレーブにアクセスすべきです。アクセス先のデータベースの振り分けをミドルウェアで実行し、アプリケーションにそれを意識させない(アプリケーションを変更しなくて良い)ようなことも可能ですが、いずれにせよ、データベースよりも上の層で何らかの工夫が必要になります。

マルチマスタでは、どのデータベースでも更新可能なので、アプリケーションはどのデータベースにアクセスしても構いません。従って、アプリケーション側の変更は不要です。その代わり、データの同時更新に対処するために、データベース側で何らかの工夫が必要です。
例えば、データの更新に先立ち、全データベースについて対象データのロックを取得する、という方法が考えられますが、こうすると更新の性能が大きく落ちることになります。またレプリケーションの遅延やオフライン更新などにより、同時更新を防げない場合もあります。この場合は、何らかのルールを策定し、どちらか一方の更新を無効にする、などの例外処理を行うことになります。
このようにマルチマスタレプリケーションは、性能的に問題があり、かつ安定的に動作させるのが難しい技術です。

PostgreSQLのストリーミングレプリケーション機能は、シングルマスタレプリケーションのみをサポートしています。
マルチマスタをサポートするPostgres-XCという機能も開発が進められていて、バージョン1が公開されています。これはシェアードナッシング方式によるクラスタリングなので、厳密に言うとレプリケーションとは少し違うのですが、書き込み性能についてもサーバの台数に合わせて伸びるという結果が出ており、将来が楽しみな機能です。

解説:松田神一

応募者全員プレゼント!
オープンソース データベース標準教科書 -PostgreSQL-