ThemBid.comにて、Web 2.0的サイトをスケーリングするためのテクニックが紹介されています。Ubuntu、Lighttpd、PHP、Symfonyフレームワークの組み合わせを使うもので、高アクセスに耐えるPHPシステムの設計手法を学べるのではないでしょうか。
ThemBid.comにて、Web 2.0的サイトをスケーリングするためのテクニックが紹介されています。Ubuntu、Lighttpd、PHP、Symfonyフレームワークの組み合わせを使うもので、高アクセスに耐えるPHPシステムの設計手法を学べるのではないでしょうか。
1.ハードウェア
初期状態で、充分なスペックを持ったサーバーを用意しておき、数千のユーザーアクセスに耐える余裕を持たせておきます。我々は、2GBのメモリと2台の1万回転の36GB SCSIディスク(RAID1)を用意しました。
低い遅延時間を持つDNS
サービスを短期間で拡大させる予定でしたので、低い遅延時間を持つDNSサーバーを使用しました。今回は、コストがあまりかからないDNS Made Easyを使用しています。DNS Stuffを使うと、この確認を行えます。
OS
多くのホスティング環境でLinuxが採用されています。開発環境としては、デュアルモニタ構成のUbuntu Linuxを使用しており、1.5画面でEclipseを、ターミナルをバックグラウンドで、0.5画面でブラウザを表示させています。また、我々の場合はサーバーのOSにもUbuntuを使用しています。デスクトップ画面が気になる人は、こちらのスクリーンショットをご覧下さい。
Webサーバー
ThemBid.comでは多くの静的な画像やページがあり、多くのサーバーで検証する必要がありました。最初はApache+mod_phpの構成でPHPスクリプトを、別のWebサーバーで静的なコンテンツを提供していました。次に、Lighttpdを検証しました。Lighttpdと FastCGIを使うと、静的な画像やWebページはLighttpdで、PHPページはFastCGIで処理します。Lighttpdは高速なWeb サーバーで、素晴らしい処理能力を備えています。インストールを行うには、
apt-get install lighttpd
と記述し、FastCGIを有効にします:
lighty-enable-mod fastcgi
次に/etc/lighttpd/conf-enabled/10-fastcgi.confを以下のように編集します:
fastcgi.server = ( ".php" => ( ( "host" => "127.0.0.1", "bin-path" => "/usr/bin/php-cgi", "port" => 9000 ) ) )
データベース
MySQLでの開発経験が多いことに加え、MySQLはスケール性能も高いです。MySQLのインストールは以下の通りです:
apt-get install mysql-client-5.0 mysql-common mysql-server mysql-server-5.0
開発フレームワーク
まず最初に検証を行ったのはRailsでした。しかし、
- これまでにPHPでの開発経験が多くあったこと
- DiggやYahooといったスケーラブルなWebサイトがあること
- 経験豊富なRubyプログラマよりも経験豊富なPHPプログラマの方が人材の面でも有利であること
から、PHPでの開発を行いました。SymfonyとCakePHPフレームワークを検証しましたが、ドキュメントの量と開発の積極性からSymfonyを選択しました。また、同時期にYahooがSymfonyフレームワークを使ったサービスをリリースしたことも一因でした。
PHPをインストールするには、以下のように記述します。
apt-get install php5-cgi php5-cli php5-common php5-gd php5-mysql php5-mysqli php5-sqlite php5-dev make
また、Lighttpdの設定をするために、/etc/lighttpd/lighttpd.confに以下の記述を行います(今回、Symfonyが/var/www/www.thembid.comに有ることを前提としています):
$HTTP["host"] == "www.thembid.com" { server.document-root = "/var/www/www.thembid.com/web" url.rewrite-once = ( "^/(.*..+(?!html))$" => "$0", "^/(.*).(.*)" => "$0", "^/([^.]+)$" => "/index.php/$1", "^/$" => "/index.php" )
AJAX
AJAXを使うと、ユーザーインターフェースを改良することができます。また、効果的に使うことで、転送量も軽減させることが可能です。Symfonyを使うと、PrototypeというJavaScriptライブラリを使って、AJAXの開発を非常に簡単に行えます。
キャッシュ技術
アプリケーションをスケーラブルなものにするためには、キャッシュを賢く活用し、繰り返しの多い作業を軽減させることが大切です。我々は、以下のようなキャッシュ技術を使っています。
PHPキャッシュ
デフォルトでは、PHPスクリプトがアクセスされると、Webサーバーは毎回そのコードをコンパイルします。PHPアクセラレータを使うと、これらのスクリプトの最適化を行い、コンパイルし、キャッシュに保存します。最初に、XCacheを使いましたが、Symfonyを使う上ではこちらの現象と同様の問題に遭遇しました。そのため、eAcceleratorを使用して高速化しています。
eAcceleratorは以下のようにインストールを行います:
# wget http://bart.eaccelerator.net/source/0.9.5/eaccelerator-0.9.5.tar.bz2 # tar xvjf eaccelerator-0.9.5.tar.bz2 # cd eaccelerator-0.9.5/ # phpize # ./configure # make install # mkdir /var/tmp/eaccelerator/; chmod 777 /var/tmp/eaccelerator/
そして、/etc/php5/cgi/php.iniには以下の記述を追記します:
zend_extension="/usr/lib/php5/20051025/eaccelerator.so" eaccelerator.shm_size="0" eaccelerator.cache_dir="/var/tmp/eaccelerator" eaccelerator.enable="1" eaccelerator.optimizer="1" eaccelerator.check_mtime="1" eaccelerator.debug="0" eaccelerator.filter="" eaccelerator.shm_max="0" eaccelerator.shm_ttl="0" eaccelerator.shm_prune_period="0" eaccelerator.shm_only="0" eaccelerator.compress="1" eaccelerator.compress_level="9"
その後、Lighttpdを再起動させます。
オブジェクトとコンテンツのキャッシュ
オブジェクトとコンテンツをキャッシュするとデータベースのクエリや、同じデータの再計算といった作業負担を減らすことが出来ます。幸いなことに、 Symfonyを使うと既にキャッシュ機構を備えています。キャッシュの種類には複数方法あり、ファイルベースのキャッシュ、共有メモリキャッシュ、 SQLiteキャッシュがあります(もうすぐMemcacheベースのキャッシュプラグインもリリースできると思います)。色々な場面でキャッシュを活用すると、キャッシュの容量が問題となってきます。我々はメモリー内に保持することで、速度を最大化したいと考えていました。SQLiteは非常に高速なのですが、通常の使用ではディスクに情報が保存されてしまいます。また、Memcacheプラグインもまだ存在しませんでした。そのため、SQLiteを使用して、メモリー内に構築したファイルシステムにデータを格納することにしました。そうすることで、メモリー内に構築されたSQLiteの、非常に高速な検索を達成できます。この実現には、以下の記述を行います。
# mount -osize=100m -t tmpfs tmpfs /var/www/www.thembid.com/cache/
また、/etc/fstabに以下の記述を行うこともできます。
tmpfs /var/www/www.thembid.com/cache/ tmpfs defaults,size=100m 0 0
クライアントサイドのキャッシュ
JavaScriptやスタイルシート、画像などのデータはあまり改変されません。そのため、これらはブラウザーが毎回ダウンロードしないように指示する必要があります。そのために、/etc/lighttpd/lighttpd.confを修正し、以下のような記述を行います。
$HTTP["host"] == "www.thembid.com" { server.document-root = "/var/www/www.thembid.com/web" url.rewrite-once = ( "^/(.*..+(?!html))$" => "$0", "^/(.*).(.*)" => "$0", "^/([^.]+)$" => "/index.php/$1", "^/$" => "/index.php" ) expire.url = ( "/sf/" => "access 1 days", "/js/" => "access 1 days", "/css/" => "access 1 days", "/images/" => "access 3 days" ) }
モニタリング
サーバーのアップグレードの時期を見極めるためには、サーバーのモニタリングを行う必要があります。最も簡単な方法は、Muninを使用することです。インストールは以下の通りです。
# apt-get install munin munin-node
次に、/etc/munin/munin.confを変更します。
htmldir /var/www/www.thembid.com/web/status [thembid.com] address 127.0.0.1 use_node_name yes
これで、http://サーバー名/statusというURLにアクセスすると、サーバーのモニタリングが可能になっていると思います。このMuninのサンプル画面をこちらに掲載します。
また、AwstatsといったWebのアクセス解析ソフトも便利です。
スケーラビリティのプランニング
Muninのグラフの状況に応じて、サイトのアップグレードをいつ行うか、判断を行います。最初の増強では、MySQLサーバーを別のサーバーに移行することになります。これにより、メモリやディスク、CPUといったリソースの多くが解放されるでしょう。次に、Memcachedを使ったメモリキャッシュを実装する方法があります。また、もしMySQLのレプリケーションにボトルネックがある場合は、MySQLクラスターといった手法を採ることもできます。また、Lighttpdサーバーの負荷分散を行いたい場合は、LVSといった仕組みを検証したほうが良いかもしれません。
この記事の通り、スケーラブルなWebシステムを実装するためにも、いろいろな技術があります。これらの手法は、サーバーの耐久性を向上させるものではありません。その話題については、別の機会に紹介したいと思います。(PHPプロ!)
関連リンク
関連ニュース
- オブジェクト関係の処理を高速化するための方法
- =JASLABS= Alternative PHP CacheでPHPを高速化する方法
- =Fiftyfoureleven.com= PHPを使ってCSSを圧縮転送し、読み込みを高速化させる手法
転載元
PHPプロ!:最新のPHPニュース
この記事は参考になりましたか?
- この記事の著者
-
PHPプロ!(PHPプロ!)
「PHPプロ!」は、アシアル株式会社が運営するPHP開発者のためのポータル&コミュニティサイトです。同サイトでは、PHP最新ニュースや、困ったときのQ&A掲示板、初心者向けのPHP講座、PHP中級者のためのTIPSメーリングリスト、中・上級者向けの技術ノウハウ満載のPHPプロ!マガジンの提供など、PHP開発...
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です