複製サーバーを保護する
前述のとおり、複製サーバーは壊れる可能性があるので大切に扱う必要があります。古いユーザーがこのリポジトリに変更をコミットすることも避けなければなりません。そのためには、ユーザーのアクセス権を厳しく管理することが必要です。具体的には、このリポジトリへの排他的アクセス権を持つ特別なユーザーを作成し、そのユーザーにsyncuserなどの名前を付けます(下記の例でもこの名前を使っています)。
この方法を使う場合は、pre-revprop-change
スクリプトにもう少し手を加える必要があります。次に示すスクリプトでは、syncuserというユーザーに対してのみリビジョンプロパティの更新処理を許可しています。
#!/bin/sh USER="$3" if [ "$USER" = "syncuser" ]; then exit 0; fi echo "Only the syncuser user may change revision properties" >&2 exit 1
start-commit
フックについても同様のスクリプトを記述し、このリポジトリに対してのみ変更をコミットするよう設定する必要があります。
最後に、この方法を使って複製プロセスを初期化するときは、次のようにしてsyncuserのユーザー名とパスワードを指定する必要があります。
$ svnsync init svn://svnmirror svn://svnrepos -sync-username syncuser -sync-password=secret
複製を自動化する
同期処理のセットアップができていれば、このプロセス全体を自動化するのは簡単です。post-commit
フックとpost-revprop-change
フックを追加して、変更がコミットされるたびに同期プロセスをバックグラウンドで開始するようにすればよいのです。post-commit
スクリプトは次のようになります。
#!/bin/sh # Post-commit script to replicate newly committed revision to mirrors svnsync sync svn://svnmirror > /dev/null 2>&1
post-revprop-change
フックは次のようになります。
#!/bin/sh # Post-revprop-change script to replicate revprop-changes to slaves REV=${2} svnsync copy-revprops svn://svnmirror ${REV} > /dev/null
これで、ターゲットリポジトリとメインリポジトリが常に同期するようになります。また、サーバー間のネットワーク接続に障害が起きた場合でも、次に接続が回復したときにターゲットリポジトリが更新されるので問題はありません。
ライトスループロキシで負荷分散を実現する
ここまでは、Subversionリポジトリをリモートのミラーサーバーにバックアップする方法を説明してきました。これは有用なテクニックですが、Subversion 1.5とApacheの組み合わせを使えば、もう一歩先に進むことができます。Subversion 1.5ではライトスループロキシという概念が導入されており、これを利用することで、地理的に分散したチームに適した分散リポジトリアーキテクチャをセットアップできます。
ライトスループロキシの概念は、Subversionリポジトリに対する操作のほとんどは読み取り専用であるという観察結果に基づいています。ライトスループロキシアーキテクチャは、中央にある1つのマスターリポジトリと、いくつかの読み取り専用の複製リポジトリから成ります(図1)。それぞれの複製リポジトリはローカル開発チームの近くに設置します。個々の複製リポジトリは、svnsyncに基づく自動プロセスによって中央リポジトリとの同期が保たれます。
開発者が読み取り専用の操作(更新など)を実行する場合、その要求はローカルの読み取り専用の複製リポジトリで直接処理されます。一方、読み書き両方を行う操作(コミットなど)は中央のリポジトリに透過的に送信されます。そこで更新が行われると、すべての分散ミラーも更新されます。
ライトスループロキシはApacheによって排他的に動作し、これを利用するためには若干のセットアップが必要です。この節の残りの部分ではこれについて説明します。
まず、読み取り専用の複製サーバーをセットアップする必要があります。ライトスループロキシの基盤になる複製メカニズムも、やはりsvnsyncを利用しています。そこで、svnsyncを使用できるように複製サーバーの準備をする必要があります(具体的な方法は前述)。
次に、複製サーバーがApache上で動作するように設定します。ここで重要なのはLocation
要素で、SVNMasterURI
という新しいエントリが含まれています。
<Location /svn-mirror> DAV svn SVNPath /var/svn/svnmirror SVNMasterURI http://svnrepos </Location>
このエントリは、すべての更新要求をhttp://svnrepos
上のマスターサーバーに送るようSubversionに指示するものです。
複製リポジトリは原則的に読み取り専用です。しかし、マスターサーバーと複製リポジトリを同期させるときには、マスターサーバーが複製リポジトリを更新しなければなりません。これを許可するには、マスターサーバーだけが更新できる特殊なアドレスを個々の複製サーバー上に用意します。
<Location /svn-proxy-sync> DAV svn SVNPath /var/svn/svnmirror Order deny,allow Deny from all # Only let the server's IP address access this Location: Allow from 192.168.1.101 </Location>
最後に、post-commit
フックとpost-revprop-change
フックをセットアップして、更新後に複製リポジトリを同期させるようにします。コミット処理の速度を低下させないために、svnsync
プロセスをバックグラウンドで実行することに注目してください(このやり方はSubversionのドキュメントから採用したものです)。
#!/bin/sh # Post-commit script to replicate newly committed revision to mirrors svnsync sync http://slave1/svn-proxy-sync > /dev/null 2>&1 #!/bin/sh # Post-commit script to replicate newly committed revision to mirrors svnsync copy-revprops http://slave1/svn-proxy-sync > /dev/null 2>&1
ここまでできれば、後は実行するだけです。
Subversionベースの複製リポジトリアーキテクチャ
Subversionの複製機能は強力なツールです。リポジトリを確実かつ効率的にバックアップするのに役立つだけでなく、強力で設定の簡単な複製リポジトリアーキテクチャの基盤としても利用できます。エンタープライズ環境でSubversionリポジトリアーキテクチャを構築している場合は、ぜひ複製機能の利用を検討してみてください。