ホーム > タグ > 高速化

高速化

イサム開発で使ったプログラミング等のTips

イサムの開発にあたって,いくつかの新しいテクニックを用いたので,新旧あわせて使ったテクニックを紹介したいと思います.

mod_rewriteでGETパラメータを変換

例えば,以下のようなURLを考えます.

http://4403.biz/ISAM/organization/NEC/

なんとなくパーマリンクっぽくて素敵ですよね.でも,この実体は以下のように処理したいと考えます.

http://4403.biz/ISAM/hoge.php?mode=organization&query=NEC

この変換をmod_rewriteで実現します.まぁ,Wordpressとかで使われている常套句ですね.mod_rewriteが有効な状態で,.htaccessに以下のように書きます.

RewriteEngine on
RewriteBase /ISAM/
RewriteRule "^(.*)/(.*)/$" "hoge.php?mode=$1&query=$2" [L]

簡単ね!ご存じだとは思いますが,これにGETパラメータがさらにくっつくような状況下では,QSAフラグも付けましょう.

hoge.phpでは受け取ったGETパラメータによって処理を振り分けたらいいと思います.これで実体を隠蔽しつつ,パーマリンクっぽいURLも提供できて,なんだかすごくいい感じです.クールURI!

mod_rewriteのBフラグ

上記の設定の後に,以下のようなアクセスを想定しましょう.

http://4403.biz/ISAM/organization/KDDI R&D Labs./

なんとなく上手くいかなさそうな気配がぷんぷんしますよね?実際にやってみると,このように展開されます.

http://4403.biz/ISAM/hoge.php?mode=organization&query=KDDI R&D_Labs_=

なんだか変なことになっている.紐解きましょう.GETパラメータがどうなっているかというと以下の通りです.

mode=organization
query=KDDI R
D_Labs_=

おい!って話ですね.問題点はR&Dの&をGETパラメータの接続詞と解釈してしまっています.解釈してしまっていますというか,それで正しいわけですが・・・.単純な解決策はURLエンコードです.しかし,そのためには,以下のようなアクセスを想定することになります.

http://4403.biz/ISAM/organization/KDDI%20R%26D%20Labs%2e/

こんなの恥ずかしくて見せられない!ということで,これをmod_rewrite中に実現したいわけですね.で,調べてみるとあるんですよ,これが.apache2.2.6以降らしいですが,Bフラグというものがあります.以下,引用.

B‘ (escape backreferences)
Apache has to unescape URLs before mapping them, so backreferences will be unescaped at the time they are applied. Using the B flag, non-alphanumeric characters in backreferences will be escaped. For example, consider the rule:
RewriteRule ^(.*)$ index.php?show=$1
This will map /C++ to index.php?show=/C++. But it will also map /C%2b%2b to index.php?show=/C++, because the %2b has been unescaped. With the B flag, it will instead map to index.php?show=/C%2b%2b.
This escaping is particularly necessary in a proxy situation, when the backend may break if presented with an unescaped URL.

mod_rewrite – Apache HTTP Server

簡単ね!というわけで,先ほどのRewriteRuleにBフラグを追加すると,こんなアクセスが来ても,

http://4403.biz/ISAM/organization/KDDI R&D Labs./

こんな風に渡されるので,

http://4403.biz/ISAM/hoge.php?mode=organization&query=KDDI%20R%26D%20Labs%2e

hoge.php側では$_GET[‘query’]をurldecodeしておけばいいですね.いい時代だね~.

memcachedの導入

インクリメンタルサーチでゴリゴリ検索させています.基本的にかなりの力業実装です.ですので,負荷を減らすためにキャッシュは重要になります.当初はMySQLのキャッシュ機能とAPCに丸投げしていたのですが,DBの更新が無ければ結果は不変なので,まるっとキャッシュしてしまえばいいのではないかと思ったので,memcachedしました.初挑戦です.

そもそもmemcachedとは何かといえば,以下のようなものだそうです.

Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.

memcached – a distributed memory object caching system

ということで目的にピッタリです.で.基本的な使い方を確認しましょう.PHPではpecl::memcacheを使うのがいいのかな?似たものにpecl::memcachedもあります.よくわかりません.今回はmemcacheを使います.基本的な使い方は以下の通りです.

$mem = new Memcache;
$mem->addServer('localhost', 11211);
$val = $mem->get($key);
if(!$val) {
  //$valを作る作業
  $mem->add($key, $val, MEMCACHE_COMPRESSED, 3600);
}
$mem->close();

簡単ですね.これを応用して,イサムをキャッシュしまくります.方針としては,$keyをSQLクエリにして,$valをHTML出力文字列としています.つまりは,SQLクエリをキーにしてページフルキャッシュとほぼ同等です.これでキャッシュにヒットすればサックサクのはずです.

これをよくよく考えると,実行時間命なシステムでDBへの書き込みや更新がボトルネックになっている場合,とりまmemcachedにはき出しておいて,別プロセスで非同期にmemcachedから取り出してDBに格納するとかしてレイテンシを隠蔽できそう.そんなクリティカルなシステムを作ったことないですけどね.

エスケープとか

エスケープも別に珍しいことはしてなくて,strip_tagsやらmysql_escape_stringやらhtmlentitiesやらを使ってます.「エスケープは出力時に」という基本に忠実です.SQL文の構築はプレースホルダーを用いているので,そんなに変なことは起きないはずだと信じてます.攻撃しないで!

PHPの小ネタ

PHPはHTMLの中に直接スクリプトが書けるという実に変態な言語なので,様々な変態テクニックが駆使可能です.例えば,if文の途中でphp終了タグでぶった切って,HTMLを出力(というかそのまま表示)して,php開始タグで再びif文に復帰するとかいう常識的に考えられないような変態スーパーテクニックが利用可能です.可読性?なにそれ?誰が読むの?

それはそれとして,多少便利なものとしては,includeを用いたページ分割です.include命令によって別のphpファイルを読み込む(C言語の#includeのように)ことができるので,共通であるヘッダ部とフッタ部を別ファイルに分割することで,コード修正時の修正範囲を限定的にすることができます.ちなみに,これはHTMLヘッダ部でもできますので,かなり応用が利きますよ.

スーパーテクではありませんが,jQueryと組み合わせてajaxでインクリメンタルサーチやサジェストを実現しています.

WordPressの高速化いろいろ

以前はMovableTypeでブログをやっていたのですが,今はWordPressに乗り換えました.MTはスタティックHTMLを発行する(ダイナミックパブリッシングもあるけど)ので,記事数が増えてくると再構築に時間がかかるのがネックでした.対して,WPはPHPを駆使したダイナミック出力であり,再構築が不要です.まぁ,乗り換えの理由にはそれ以外にも色々とあったんですが,それはそれで.

閑話休題.Wordpressは動的出力になっているので,オーバーヘッドが気になります.MTはスタティックHTMLだったので,この差はかなり気になるところです.ですので,WPを如何に高速化させるかが重要なポイントになってきます.というわけで,このブログに適用している高速化手法を紹介したいと思います.このような手法で高速化させていますが,レスポンスはいかがですか?

WPプラグイン

まずはWP側でできることからやっていきましょう.高速化を目的として導入しているプラグインは以下の通りです.

ほとんど定番ですね.簡単に説明します.jQuery lazy loadは画像の読み込みを遅延させます.具体的には,画像が表示される位置までスクロールされると読み込みを行います.そのため,イニシャルトラフィックを減らすことができるので,体感的な高速化が図れます.WP CSSはgzipとかしてるらしいです.後述するmod_pagespeedと効果が重複している気もするので,いらないかもしれません.先にWP Super Cacheを説明します.というか,定番過ぎるので説明の必要はないと思いますが,基本的な高速化プラグインです.色々とコンテンツをキャッシュしてくれます.基本的に,このWP Super Cacheによる高速化効果が1番高いです.手っ取り早く高速化したい人はこれを導入すればいいと思います.

で,残ったWP Memcached Managerはmemcachedを用いてキャッシングするプラグインです.導入方法はここら辺を参考にすると良いと思います.利用には,memcachedをインストールして,起動させておく必要があります.特に考えなくても利用できます.ただ,機能してはいるんですが,memcachedがかなり暇なようなので,割当メモリは16MBに減らしています.これでも多いぐらい見たいです.記事数がまだ少ないですからね.

APC

PHPの高速化といえば,APCが主力です.これはpeclから簡単にインストールできます.これもインストールしてしまえば,特に何も考えることなく利用できます.デフォルトの設定でも良いのですが,サーバ側のメモリを余らせていても仕方がないので,48MB割り当てるように変更しています.それだけです.APCはWPに限らず,あらゆるPHPアプリに効果を発揮しますので,WebプログラミングにはPHPを好んで使うボクには嬉しい限りです.

mod_pagespeed

導入方法などは以前のエントリで紹介しました.ただし,不具合があったので,いくつかの設定を変更しました.現在は以下の設定で動かしています.

ModPagespeedEnableFilters remove_comments
ModPagespeedEnableFilters collapse_whitespace,elide_attributes
ModPagespeedEnableFilters move_css_to_head
ModPagespeedEnableFilters extend_cache

rewrite系を無効にしました.変更があってもキャッシュが効いていて,反映されなかったり,いくつかのjQueryが機能しなくなったりしたので,外しました.カスタマイズが終わって,安定運用期になったら,また有効にしてみようかなと思っています.

Home > タグ > 高速化

アフィリエイト

Return to page top