WEBベースシステムのスケーラビリティ(OpenSource を利用した場合)

サーバを適宜追加するだけで、負荷分散できるように考慮する。

WEB側

同じ処理を行うサーバ郡を並列に配置して分散処理を行う

DNS によるラウンドロビンでも、ロードバランサーでも良い。
mod_proxy_balancerPound 等が便利。
ただし、永続化するデータは、NAS や DB、Memcached*1 等を適宜使い分ける必要がある。

静的コンテンツ(イメージファイル等)は、リバースプロキシをフロント側に複数台配置する。
squid が便利。

静的コンテンツと動的コンテンツを分離する

Java の場合、説明するまでもない。
Perl の場合は、id:cooldaemon:20060213 こんな感じ。
静的な処理にさほど負荷が掛からないのであれば、フロント側でmod_proxy_balancer を利用して複数のアプリサーバに分散しても良いかもしれない。

DB側

参照の負荷分散

MySQL であればデフォルトのレプリケーション機能を利用して Slave を複数台配置する。
PostgreSQL であれば Slony-IPGCluster を利用する。

一見、テーブル結合を行って検索した方が効率が良さそうな場合であっても、テーブルを他のDBに分散する場合を考慮して、複数回検索クエリを発行した方が良い場合もある。そもそもテーブル結合が遅い場合*2O/Rマッピングとの相性等も考慮する必要があるので、テーブル結合を用いた検索を行うのは、よく考えた方が良い。

更新の負荷分散

サーバを適宜追加するだけという事に拘るのであれば…更新が頻繁に発生するテーブルを、複数のDB(仮にスレイブとする)に保持し、各スレイブの dsn *3 をマスタとなる DB に保存する。
更新前にマスタとなる DB から dsn を取り出し、その dsn を利用してスレイブに接続し、更新クエリを発行する。

コネクションをプーリングする

mod_perl 環境であれば Apache::DBI が利用可能。
PostgreSQL であれば、pgpoolPGCluster も利用可能。

その他

メールサーバの負荷分散等を検討中。

*1:Memcached は、デフォルトでクラスタリング可能…あぁ便利すぎ

*2:正規化や索引の問題を疑うのが先か?

*3:DatabeseSourceNameの略。Perl + MySQL だと 'DBI:mysql:mydb:www:3306' みたいな感じ