Linux/Apache/PostgreSQL/PHPを利用した高性能Web

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