Linux/Apache/PostgreSQL/PHPを利用した 高性能Webシステム構築 日本PostgreSQLユーザ会 四国支部 / 日本PHPユーザ会 / Momonga Project 大垣 靖男 yohgaki@ohgaki.net / yohgaki@postgres.jp / yohgaki@php.net / yohgaki@momonga-linux.org
目次 基本的なWebシステムを高性能化手法 高速化手法の利点・欠点 オープンソースシステムを利用したスケールアウト アクセスの分散 スケールアウトが行える条件 Webシステムの高性能化とキャッシュ リバースプロキシ(HTTPキャッシュ) ページキャッシュ クエリキャッシュ クエリ・ページキャッシュの効果 Squid/Apache/PHPとクエリキャッシュ HTTPキャッシュの効果 負荷分散の基礎知識 レイヤー7スイッチ機能の実装 レイヤー7スイッチ機能のシステム構成例 複数データセンタを利用するシステム構成例 その他のツール 2005/12/2
はじめに Linux/Apache/PostgreSQL/PHPを使用したWebシステムで高性能なWebシステムを構築する際のポイントを解説します。 どの高負荷システムでも同じですが、データベースがシステムのボトルネックになる場合が多くあります。 オープンソースシステムのみを利用したスケールアウト手法を中心Linux/Apache/PostgreSQL/PHP Webシステム構築、特にデータベースの負荷を分散する基本的な手法などを紹介します。 BigIP、ServerIronなどの商用の負荷分散システムは利用しない事が前提です。 高性能化以外の要件への対処は詳しく紹介しません。DBの負荷分散については他のセッションなどで解説されているので省略しました。 2005/12/2
基本的なWebシステムを高性能化手法 キャッシュ スケールアップ → ハードウェア チューニング → ソフトウェア データのキャッシュ バイトコードのキャッシュ スケールアップ → ハードウェア CPU/Disk/Networkを高速化 (負荷分散ハードウェア) チューニング → ソフトウェア アルゴリズムの高速化 適切な関数・システムの利用 スケールアウト → システムデザイン 負荷分散を可能にするシステムデザイン Webシステムではスケールアウトを可能にするシステムデザインが最も重要 スケールアウトを行いリニアにシステム性能を向上させるポイント DBMSへのアクセスを最小限 DBMSへのアクセスを分散 利用可能なキャッシュは全て活用 2005/12/2
高速化手法の利点・欠点 スケールアップ チューニング スケールアウト 利点 欠点 ハードウェアを交換するだけで高速化 CPU/Disk/Network高速化の限界 チューニング 適切なシステムの利用方法・アルゴリズムを使用する事により数倍、場合によっては数百倍以上の性能向上が可能 適切に構築されたシステムのチューニングは難しい 不適切に構築されたシステムのチューニングも難しい場合が多い スケールアウト ハードウェアを追加するだけでシステム全体の性能がスケーラブルに向上 (負荷分散システムを導入するだけで高速化) システム全体を設計する際にスケールアウトを前提としてシステム設計を行う必要がある (ハードウェアによる負荷分散システムの場合、システム設計がスケールアウトに対応していなくてもスケールアウトが可能な場合もある) (負荷分散システムは比較的高価 300万円~) 2005/12/2
オープンソースシステムを利用したスケールアウト Webシステムのスケールアウトに利用可能なシステム DNS – djbdns, bind Firewall - iptables Webcache – squid Traffic Control – iproute2 Replication - PGCluster, pgpool, Slony-I 簡単なシステム構成例 Traffic Control Webcache Webcache Webcache Web Server Web Server Web Server Replication Database Database Database 2005/12/2
アクセスの分散 DNS Webcache Traffic Control Replication 同じサーバ名(FQDN)に複数のIPアドレスを割り当てラウンドロビン方式でアクセスを分散(ラウンドロビンDNS) Webcache Squidにはキャッシュサーバの負荷分散機能を用いてキャッシュアクセスを分散可能。スケールアウトに用いるにはリバースプロキシとして使用 Traffic Control iptablesのDNAT(送信先IPアドレスを別のIPアドレスに変更する機能)もラウンドロビンDNSと同様に複数のIPアドレスを指定可能 iproute2のトラフィック制御には負荷分散機能がありサーバへのアクセスを分散可能。通常この負荷分散機能は複数のISPへ接続している場合に利用される。スケールアウトに利用するにはリバースプロキシと同様に反対方向に負荷分散を行う Replication 上記のアクセス分散は主にWebサーバへのアクセス分散方法。DBMSへのアクセス分散は基本的にPGCluster, pgpool等のReplicationを利用。 2005/12/2
スケールアウトが行える条件 スケールアウトを行うにはシステム・ページの特徴を分析・把握する事が重要 基本的な例1:Webページ全てが静的なページ、全てのユーザが同じページを参照する場合 最も簡単な方法は単純にWebサーバを増す Webサーバを増やすよりリバースプロキシを導入した方が高い効果を得られる ただしリバースプロキシを導入した場合はキャッシュコントロールを考慮することが必須 基本的な例2:WebページはDBMSに保存された情報から動的に生成、全てのユーザが同じページを参照する場合 単純にWebサーバは増やせない → DBMSへのアクセスがボトルネックとなりスケールしない 各Webサーバで生成されたページをキャッシュしDBMSへアクセスせずにキャッシュしたページデータを送信 実際のシステムはこの基本的な2例より複雑な構成となっているためシステム設計の際にシステム・ページの特徴を詳しく分析し特徴にあった設計が必須 より複雑な例:ユーザ別にカスタマイズしたページが表示され、ショッピングカートを使用して商品の購入が行える場合 単純にWebサーバ、キャッシュサーバを増やせない → ユーザ別にページを生成する必要がありキャッシュできない。HTTPセッション管理が必要となり永続性の管理が必要となる場合がある 2005/12/2
Webシステムの高性能化とキャッシュ Webシステムを高性能化するにはスケールアウトを可能な設計をすると共に利用可能なキャッシュをできる限り活用 主なキャッシュ HTTPキャッシュ - HTTP1.1ではキャッシュ機能が強化されより細かいキャッシュコントロールが可能 ページキャッシュ - 動的に生成したページをディスクなどに保存し、DBクエリ、ページ生成負荷を軽減 クエリキャッシュ - DBサーバへのクエリ結果をキャッシュしクエリ数を削減 バイトコードキャッシュ - PHPスクリプトは実行時にバイトコードにコンパイルされた後実行される。このバイトコードをキャッシュしてスクリプト実行を高速化 キャッシュを活用するとスケールアウトを行い高性能化できる可能性が増加 2005/12/2
リバースプロキシ(HTTPキャッシュ) 通常Webプロキシ(Webキャッシュ)はクライアント側のネットワークで使用しセキュリティーの確保やWebページのキャッシングに利用 リバースプロキシは通常の使用方法とは反対にWebサーバ側にプロキシを配置しWebシステムの性能を向上させるために使用 リバースプロキシの構成: Webブラウザ Webブラウザ Webブラウザ Squid Apache Webシステム 2005/12/2
ページキャッシュ ページの種類とキャッシュ 共通ページは本当にキャッシュが不可なのか? カスタマイズページは本当にキャッシュ不可なのか? アクセス統計情報を全て取得するためキャッシュ不可? ページにアクセスカウンタが付いているためキャッシュ不可? ページの情報がリアルタイムに更新される必要があるためキャッシュ不可? カスタマイズページは本当にキャッシュ不可なのか? ユーザの好みに合わせて表示を変えているためキャッシュ不可? セッション管理を行っているためキャッシュ不可? キャッシュヒット率は? 無用なキャッシングは無駄 キャッシュを全く行えないページは多くない。HTTPレベルでのキャッシュは不可能な場合もWebシステムレベルでキャッシュを行える場合は多い 共通ページ カスタマイズページ キャッシュ可能 ◎ ○ キャッシュ不可 本当にキャッシュが不可能なのか再検討 本当にキャッシュ不可なのか再検討 2005/12/2
クエリキャッシュ クエリの種類とキャッシュ 各クエリの実行結果はどの程度整合性が必要か? キャッシュヒット率は? 保存されているデータはどの程度のサイクルで更新? 表示されるデータはどの程度のサイクルで更新? 単一のリスト? アクセス統計情報を全て取得するためキャッシュ不可? キャッシュヒット率は? 無用なキャッシングは無駄 参照キャッシュを行えるページは多い トランザクション 作成 更新 削除 参照 キャッシュ × ○ 2005/12/2
クエリ・ページキャッシュの効果 HTTPレベルのキャッシュ、アプリケーションレベルのキャッシュどちらもスケールアウトを行うには重要 DBMSにアクセスが必要なページの場合、単独のDBサーバでは簡単なクエリでも数千クエリ/秒程度がMAX Webサーバをいくら増やしても全てのWebサーバは同じDBMSにアクセスしなければならない場合はスケールしない DBMSへのアクセスが分散可能な場合もスケールするためにはWebサーバとDBサーバの両方を増設しなければならない 単純な例: DBサーバは1台。200クエリ/秒の性能 DBサーバのクエリ結果を1分間Webサーバでページキャッシュを行うことが可能 キャッシュ無し: DBサーバの性能( 200クエリ/秒)がシステム全体の最高性能 200ページ/秒 キャッシュ有り: DBサーバへのアクセスは1/60の軽減。システム全体の最高性能 12,000ページ/秒以上 Webサーバはキャッシュした結果をWebサーバの最高性能まで処理できるため非常に多くのページを処理可能 2005/12/2
Squid/Apache/PHPとクエリキャッシュ 前のページの“簡単な例”ではDBサーバのクエリをWebサーバのアプリケーションでキャッシュしたがSquid/Apache/PHPを利用して簡単にDBサーバクエリ結果のキャッシュも可能 キャッシュがヒットする場合、キャッシュシステム性能と同じパフォーマンス システム構成例 Webシステム Apache Apache Apache クライアント側 Squid Apache サーバ側 PostgreSQL 2005/12/2
Squid/Apache/PHPとクエリキャッシュ キャッシュのヒット率にもよるが適切なシステム構成とコーディングで数百倍のシステム性能を達成する事も可能 <?php // query_result.php // cache 600 seconds header(‘Expires: public, max-age=600’); $db = pg_connect('dbname=foo'); // $_GET includes search condition $rec = pg_select($db, 'post_log', $_GET); echo ‘$rec = ‘; var_export($rec); ?> <?php include(‘http://some_db_cache_server/query_result.php?id=1234’); var_dump($rec); // Just dump query result ?> 2005/12/2
HTTPキャッシュの効果 スクリプト処理は基本的に遅い HTTPキャッシュは高効率 簡単な例: 単純なecho文でHTMLを出力した場合と静的なHTMLページを出力する場合とでは2倍以上の性能差が発生 HTTPキャッシュは高効率 HTTPレベルでキャッシュした場合、Webサーバでキャッシュした場合より数倍から数十倍のページを処理が可能 簡単な例: Webサーバは1台。200ページ/秒の性能 キャッシュサーバはページ出力を1分間キャッシュ可能 キャッシュ無し: Webサーバの性能( 200ページ/秒)がシステム全体の最高性能 200ページ/秒 キャッシュ有り: システム全体の最高性能はキャッシュサーバの台数応じてスケーラブルに性能が向上 2005/12/2
負荷分散の基礎知識 レイヤー3 & 4 レイヤー7 特定のサーバにアクセスが必要なシステムではレイヤー7負荷分散が必須 OSI参照モデルのネットワーク層(IP)、トランスポート層(TCP/UDP)での負荷分散 iptables, iproute2で実現できる負荷分散 レイヤー7 OSI参照モデルのアプリケーション層での負荷分散 特定のサーバへのアクセスに依存したアプリケーション(HTTPセッション管理など)の場合、IPレベルで負荷分散するとアプリケーションが正常に動作しなくなる 商用負荷分散システムはレイヤー7、つまりアプリケーションレベルのHTTPプロトコルを解析し負荷分散を行える (Cookie、URLスイッチングが可能) 特定のサーバにアクセスが必要なシステムではレイヤー7負荷分散が必須 PHPの場合、サーバを限定したアプリケーションスコープ変数を持たないためHTTPセッション管理のみ考慮すればレイヤー7での負荷分散をアプリケーションで実装することも比較的簡単 PHP+PostgreSQLの場合、session_pgsqlモジュールとiptables/iproute2のレイヤー3&4での負荷分散を組み合わせる 2005/12/2
レイヤー7スイッチ機能の実装 利点 レイヤー7スイッチ機能をアプリケーションに実装した場合はWebサーバ/DBサーバを追加するだけでスケールアウト可能 商用製品のレイヤー7スイッチ機能は便利だがシステム全体の性能を向上するにはWebサーバ/DBサーバのみではなくスイッチも購入しなければならない 欠点 システム構築時にアプリケーションでレイヤー7スイッチの代替機能を設計と実装を行わなければならない (障害が発生したサーバを切り離したりロードバランシングを行える商用スイッチのように可用性を確保する機能の設計と実装を行わなければならない) 2005/12/2
レイヤー7スイッチ機能のシステム構成例 iptablesなどを利用してWebアクセスを分散 HTTPセッションデータをWebサーバ以外のサーバ、PostgreSQL等に保存 各WebサーバはセッションIDにより自動的に接続先のPostgreSQLサーバを選択 セッションIDの各文字を数値として足した後、セッションデータサーバの台数のモジュロでサーバIDを決定 session_pgsql (PHPのセッションセーブハンドラ)は上記のセッションサーバの選択を行う Webシステム Traffic Control Apache Apache Apache PostgreSQL PostgreSQL PostgreSQL 2005/12/2
複数データセンタを利用するシステム構成例 “レイヤー7スイッチ機能のシステム構成例”のシステムを複数のデータセンタに設置 DNSを利用して負荷を分散 可用性を向上させるために短いTTLを利用する場合は永続性に注意が必要 DNSサーバ PostgreSQL Webシステム Traffic Control Apache PostgreSQL Webシステム Traffic Control Apache PostgreSQL Webシステム Traffic Control Apache 2005/12/2
その他のツール Pgpool PGCluster UltraMonkey Balance Pen DNS Balance OpenMosix PostgreSQLサーバのレプリケーション、負荷分散ツール http://www2b.biglobe.ne.jp/~caco/pgpool/ PGCluster http://pgcluster.projects.postgresql.org/jp/ UltraMonkey オープンソースのロードバランサー。SourceForgeでも利用されている http://ultramonkey.jp/ Balance 汎用TCPプロキシ。ラウンドロビン方式による負荷分散と障害検知 http://www.inlab.de/balance.html Pen http://siag.nu/pen/ DNS Balance サーバの状態やルーティング情報を用いてDNS応答を送信 http://www.netlab.is.tsukuba.ac.jp/~yokota/izumi/dns_balance/ OpenMosix プロセスのマイグレイーションなどが行えるクラスタシステム http://openmosix.sourceforge.net/ 2005/12/2
最後に SSLの場合はどうなる? 安易なキャッシュ利用は危険? ユーザが送信したデータの検証が面倒で負荷が高い? セキュリティー・可用性に関する省略しています。実際のシステム構築の際にはセキュリティー・可用性について十分検討してください! 2005/12/2
負荷分散以外の工夫(1) データベースへのアクセスはシステムのボトルネックとなる傾向 DBへのアクセスを削減するためにメッセージダイジェストが利用可能 例1:フォームに記入後、実際にDBに登録する前に確認ページを表示。確認ページからの送信でDB保存 メッセージダイジェストを利用しない場合、2回以上のDBアクセスが発生する可能性が高い メッセージダイジェストを利用する事により重複した送信情報のチェックを回避 例2:Webページ参照可能期間を設定したページへのアクセス データベースに参照可能期間を保存した場合、ページアクセス毎にデータベースアクセスが発生 メッセージダイジェストを利用するとURLを生成した時点でのみデータベースアクセスが発生 2005/12/2
負荷分散以外の工夫(2) メッセージダイジェストとは? 実装は簡単かつ高性能 ハッシュ関数を用いデータが改ざんされていない事を保障 Webアプリケーションがクライアントに送信した情報が改ざんされていない事を保障可能 $_GET, $_POST, $_COOKIE 実装は簡単かつ高性能 単純な文字列処理のみで実装可能 文字列処理+ハッシュ関数実行はデータベースアクセスに比べ高速かつ負荷分散が容易となる場合も 2005/12/2
ラウンドロビンDNSは効果的? Webシステム構築の際、利用しているシステムの特徴を理解していないと失敗する例としてのラウンドロビンDNS DNSサーバにはDNSサーバとDNSキャッシュサーバの2種類 DNSキャッシュサーバは通常DNSサーバからの応答をキャッシュ ISPは通常、DNSキャッシュサーバのアドレスをDNSサーバアドレスとしてユーザに提供 したがってラウンドロビンDNSを利用した場合、TTLが長い場合思ったように負荷分散されない 短すぎるとDNSクエリに時間が必要となるので注意 2005/12/2
IP Anycast 「IP Anycast技術」 通常、インターネット上のホストに対して個別に割り当てるIPアドレスを、ある機能やサービスに対して割り当てることにより、そのアドレスを複数のホス トに担当させ、経路制御により負荷分散させることを可能にするための技術。IP Anycastを用いたサーバでは、同一のIPアドレスが複数のサーバにより共有され、ユーザからのリクエストは、経路制御的、ネットワーク的に近いサー バにより処理されます。 (出典: IIJプレスリリース http://www.iij.ad.jp/pressrelease/2004/0202.html) IP Anycastはインテグレータが構築するシステムではないが非常に負荷が高いシステムでは効果的 2005/12/2