[解決済み] コハナベースのウェブサイトを最適化し、スピードとスケーラビリティを向上させる。
質問
私が Kohana で構築したサイトは、昨日、膨大な量のトラフィックに襲われ、一歩下がってデザインの一部を評価することになりました。Kohana ベースのアプリケーションを最適化するための標準的なテクニックにはどのようなものがあるのでしょうか。
私は、ベンチマークにも興味があります。私は
Benchmark::start()
と
Benchmark::stop()
を各コントローラ・メソッドに適用して、全ページの実行時間を確認したいのですが、グローバルかつ迅速にベンチマークを適用できますか?
私は今後Cache-libraryをもっと使うつもりですが、私が現在単に気づいていないだけでできることはたくさんあると思うので、より多くの提案を受け入れるつもりです。
どのように解決するのですか?
この回答で言うことは、Kohanaに限ったことではなく、おそらく多くのPHPプロジェクトに適用できます。
パフォーマンス、スケーラビリティ、PHP、...について話すとき、私の心に浮かぶいくつかのポイントがあります。
私はいくつかのプロジェクトに取り組んでいる間、これらのアイデアの多くを使用してきました - そしてそれらは役立ちました。
まず、パフォーマンスに関しては
多くの側面や疑問があります。
:
- サーバーの設定 (Apache、PHP、MySQL、その他の可能なデーモン、およびシステムの両方) に関するより多くのヘルプを得ることができます。 サーバ障害 といったところでしょうか。
- PHP コードです。
- データベースクエリ。
- ウェブサーバを使用するかどうか?
- 何らかのキャッシュ機構を使用することができますか?それとも、常に最新のデータが必要なのでしょうか?
リバースプロキシーを利用する
まず最初に、本当に便利なのは リバースプロキシ のように ヴァーニッシュ は、あなたのウェブサーバの前にある できるだけ多くのキャッシュを そのため、PHP/MySQL の計算を本当に必要とするリクエストのみ (もちろん、プロキシのキャッシュにないときは、他のリクエストもあります) が Apache/PHP/MySQL に到達します。
-
まず、あなたのCSS/Javascript/画像
-- まあ、静的なものすべて -- です。
は、おそらく Apache が常に提供する必要はないでしょう。
- ですから、リバースプロキシにそれらすべてをキャッシュさせることができます。
- これらの静的ファイルを提供することは、Apache にとっては大したことではありませんが、これらのために働く必要がないほど、 PHP でできることが多くなります。
- 覚えておいてください。Apache は一度に有限の、限られた数のリクエストしか処理することができません。
-
次に、リバースプロキシにキャッシュから可能な限り多くの PHP ページを提供させます。
それほど頻繁に変更されないページが
で、キャッシュから提供される可能性があります。PHP ベースのキャッシュを使う代わりに、もっと軽い別のサーバーに、これらの
(そして、時々PHPサーバーからそれらを取得するので、それらは常にほぼ最新です)
?
- 例えば、いくつかのRSSフィードがある場合 (パフォーマンスを最適化しようとするとき、一般にそれらを忘れがちです) を要求された場合 非常に頻繁に で、それらを数分間キャッシュすることで、Apache+PHP+MySQLへの数百/数千のリクエストを節約することができます!
- サイトの最もアクセス数の多いページについても同様で、少なくとも数分間は変更しないのであれば (例: ホームページ?) であれば、ユーザーが要求するたびにそれらを再作成して CPU を浪費する必要はありません。
-
匿名ユーザー向けに提供されるページには違いがあるかもしれません
(すべての匿名ユーザーに同じページが提供される)
と、識別されたユーザーに対して提供されるページ
("Hello Mr X, you have new messages", for instance)
?
- もしそうなら、リバースプロキシが匿名ユーザー向けに提供するページをキャッシュするよう設定することができます。 (セッションクッキーのようなクッキーに基づき、通常は)
- これは、Apache+PHP が、識別されたユーザー(ユーザーのごく一部かもしれませんが)しか扱わないことを意味します。
について
リバースプロキシによるキャッシュの利用
についてですが、PHPアプリケーションの場合、例えば、以下のようになります。
ベンチマーク結果では、APCとSquid Cacheでサーバーの能力が400%から700%向上しています。
.
(そう、彼らはSquidを使っていて、私はvarnishについて話していました。それは別の可能性です^^ Varnishはより新しく、しかしよりキャッシュに特化しています)
もしあなたがそれを十分に行い、あまりに多くのページを何度も再生成するのを止めることができれば、おそらくコードを最適化する必要さえなくなるでしょう ;-)
少なくとも、どんな種類の急ぎでもないでしょう...。そして、あまりプレッシャーがないときに最適化を実行するのが常に良いことです...。
余談ですが、OPで言ってますよね。
こはぜ屋で作ったサイトが、昨日ものすごい勢いで 昨日、ものすごい量のトラフィックがありました。
このような リバースプロキシが文字通りその日を救うことができる突然の状況です。 もし、あなたのウェブサイトが刻々と変化する最新情報に対応できるのであれば。
-
インストールし、設定し、常に
- 毎日、普通に -
を実行します。
- PHP ページをキャッシュに残さない、あるいは短時間だけ残すように設定する。こうすることで、常に最新のデータが表示される。
-
そして、slashdot や digg の効果を受ける日。
- PHP ページをキャッシュに残すようにリバース プロキシを設定する。または、より長い期間、ページを更新しないかもしれませんが、ウェブサイトが digg 効果を生き残ることを可能にします!
それについて どうすれば「Slashdotted」されたことを察知し、生き残ることができるのでしょうか? は、興味深い読み物かもしれません。
PHP側で。
まず第一に:あなたが使っているのは
最近のバージョンのPHP
? 定期的に新しいバージョンで、速度が改善されています;-)
例えば
PHP Branches 3.0から5.3-CVSのベンチマーク
.
PHP 5.3 を使用する十分な理由があることに注意してください。
(
いくつかのベンチマークを作成しました (フランス語)
で、結果は素晴らしいものでした)
...
もうひとつの理由は、もちろん、PHP 5.2が寿命に達しており、もうメンテナンスされていないことです!
オペコードキャッシュを使用していますか?
-
について考えています。
APC - PHP代替キャッシュ
を考えているのですが、例えば
(
pecl
,
マニュアル
)
これは私が最もよく見てきた解決策で、私が働いてきたすべてのサーバーで使われています。
- こちらもご覧ください。 スライド APC フェイスブック ,
- または ベンチマーク結果では、APCとSquid Cacheによりサーバーの能力が400%から700%向上しています。 .
- これは、場合によっては、サーバーの CPU 負荷を大幅に低下させることができます。 (私は、APC をインストールして opcode-cache 機能を有効にするだけで、一部のサーバーの CPU 負荷が 80% から 40% になるのを見たことがあります!)
-
基本的に、PHP スクリプトの実行は 2 つのステップで行われます。
- PHP のソースコードを opcode にコンパイルする。 (JAVAのバイトコードに相当)
- これらのオペコードの実行
- APC はこれらをメモリ内に保持するため、PHP スクリプト/ファイルが実行されるたびに行う作業は少なくなります: RAM から opcodes を取得し、それらを実行するだけです。
-
を見る必要があるかもしれません。
APC の
設定オプション
で、ちなみに
- には非常に多くのものがあり、いくつかは速度、CPU 負荷、使いやすさの両方に大きな影響を与えることができます。
-
たとえば
[apc.stat](https://php.net/manual/en/apc.configuration.php#ini.apc.stat)
を無効にすると、システム負荷の軽減にはなりますが、 opcode-cache 全体をフラッシュしない限り PHP ファイルに加えられた変更が反映されないことになります。 stat() するか、しないか?
データ用キャッシュの利用
なるべくなら 同じことを何度も繰り返さない .
私が考えているのは、もちろんSQLクエリについてです:あなたのページの多くはおそらく同じクエリを実行し、それらのいくつかの結果はおそらくほとんど常に同じです... ということは、たくさんの
ということは、たくさんの 役に立たない クエリということです。
のクエリを実行し、データベースは同じデータを何度も提供するために時間を費やさなければならないのです。
もちろん、これはWebサービスの呼び出し、他のWebサイトからの情報の取得、重い計算など、他のものにも当てはまりますが......。
特定するのは非常に興味深いことかもしれません。
- どのクエリが何度も実行され、常に同じデータを返しているか。
- その他の (重い) の計算は何度も行われ、常に同じ結果を返します。
そして、これらのデータや結果を何らかのキャッシュに保存して、簡単に取得できるようにします。 より速く -- そして、SQL サーバーに行く必要はありません。
素晴らしいキャッシュの仕組みは、たとえば
- APC : 先ほどお話した opcode-cache に加えて、メモリにデータを保存できるようになります。
- とか、あるいは memcached ( も参照してください。 ) がある場合、これは非常に便利です。 たくさん のデータを持っていたり 複数のサーバを使用している というように、分散されています。
- もちろん、ファイルについて考えることもできますし、おそらく他の多くのアイデアもあるでしょう。
あなたのフレームワークにはキャッシュ関連のものが付属していると確信しています。 と言っているように、おそらくすでに知っているでしょう。 と言っているので、すでにご存知でしょう。)
プロファイリング
さて、素敵なのは Xdebug を拡張して アプリケーションのプロファイリング を使うことで、いくつかの弱点を簡単に見つけることができます。
正しく設定されている のようなグラフィックツールで分析できるプロファイリング・ファイルを生成します。
- KCachegrind : 私のお気に入りですが、Linux/KDE 上でしか動きません。
- Wincachegrind Windows 用。残念ながら KCacheGrind よりもできることが少し少ないです -- 通常、コールグラフは表示されません。
- Webgrind は PHP ウェブサーバ上で動作するので、どこでも動作します -- しかし、おそらく機能は少ないでしょう。
例えば、ここに KCacheGrind のスクリーンショットがいくつかあります。
(ソース
pascal-martin.fr
)
(ソース
pascal-martin.fr
)
(ちなみに、2枚目のスクリーンショットにあるコールグラフは、私の記憶が正しければ、WinCacheGrindにもWebgrindにもできない典型的なものです ^^)
(@Mikushi さん、コメントありがとうございます)
もう一つ、あまり使ったことがないのですが、可能性としては
xhprof
拡張: これもプロファイリングに役立ち、コールグラフを生成できます -- しかし Xdebug よりも軽量なので、実運用サーバーにインストールできるはずです。
と並べて使うことができるはずです。 XHGui で、データの可視化に役立ちます。
SQL側で
さて、PHPについて少し話をしましたが、PHPが ボトルネックが PHP 側でない可能性が高いことに注意してください。 ではなく、データベース側である可能性が高いことに注意してください。
少なくとも2つか3つ、ここにあります。
-
判断する必要があります。
- アプリケーションが行う最も頻繁なクエリは何ですか。
-
最適化されているかどうか
(を使用しているか
右インデックス
を使用しています)。
を使用することで
EXPLAIN
の命令で、MySQLを使用している場合は- も参照してください。 SELECT およびその他のステートメントの最適化
-
例えば
log_slow_queries
を取るリクエストのリストを取得するために "too much" を取得し、最適化を開始します。
- これらのクエリのいくつかをキャッシュできるかどうか (私が以前言ったことを参照してください)
-
MySQLはうまく設定されていますか?私はそれについてあまり知らないのですが、何らかの影響を与える可能性のある設定オプションがいくつかあります。
- MySQL サーバーの最適化 は、それに関するいくつかの興味深い情報を与えてくれるかもしれません。
それでも、最も重要なのは2つ。
- 必要なければDBに行くな。 できる限りキャッシュする !
- DBにアクセスする必要があるときは、効率的なクエリを使用する:インデックスを使用し、プロファイルを使用する!
そして今度は何?
もしあなたがまだ読んでいるなら、他にどのような最適化が可能でしょうか?
まあ、まだ改善の余地はありますね...。アーキテクチャ指向のアイデアがいくつかあるかもしれません。
-
n 層アーキテクチャに変更する。
- MySQL を別のサーバーに置く (2 階建て: 一つは PHP 用、もう一つは MySQL 用)
- 複数の PHP サーバーを使用する (そして、それらの間でユーザーの負荷分散を行う)
- 静的ファイル用に別のマシンを使用し、より軽量なウェブサーバーを使用する、といった具合です。
- MySQL 用の複数のサーバー、PHP 用の複数のサーバー、およびそれらの前にある複数のリバース プロキシを使用する。
- もちろん、インストールする memcached デーモンをインストールし、できる限り多くのキャッシュを作成するためにそれらを使用します。
-
Apache よりも効率的なものを使用しますか?
-
についてよく聞くようになりました。
nginx
は、PHPや大量のウェブサイトを扱うのに最適とされています。私自身は使ったことがありませんが、ネットで調べれば面白い記事が見つかるかもしれません。
- 例えば PHP パフォーマンス III -- nginx の実行 .
- こちらもご覧ください。 PHP-FPM - FastCGI プロセスマネージャ これは PHP 5.3.3 にバンドルされており、nginx で素晴らしい働きをします。
-
についてよく聞くようになりました。
nginx
は、PHPや大量のウェブサイトを扱うのに最適とされています。私自身は使ったことがありませんが、ネットで調べれば面白い記事が見つかるかもしれません。
まあ、これらのアイデアのいくつかは、あなたの状況では少しやりすぎかもしれませんね^^。
でも、それでも...。でも、念のため、ちょっと勉強してみてはいかがでしょうか?)
そして、小花はどうでしょうか?
最初の質問は、Kohana を使用するアプリケーションの最適化についてでした... さて、私はいくつかの
のアイデアを投稿しましたが、これはすべてのPHPアプリケーションに当てはまります。
... ということは、Kohanaにも当てはまるということです ;-)
(特定のものでなくても ^^)
私は、キャッシュを使用すると言いました。Kohanaは、いくつかの
キャッシュをサポートしているようです。
(あなた自身がそれについて話したので、ここで新しいものは何もありません...)
早くできることがあれば、やってみましょう ;-)
必要のないことはしない方がいいとも言いましたが、Kohanaのデフォルトで有効になっているもので必要のないものはありませんか?
ネットを見ていると、少なくともXSSフィルタリングに関するものがあるようですが、それは必要でしょうか?
それでも、役に立つかもしれないリンクをいくつか紹介します。
結論は?
そして、結論として、シンプルに考えてみました。
- 5日分の給与を支払うために、あなたの会社はいくらかかるでしょうか? -- 偉大な最適化を行うための合理的な時間であることを考えると
- を購入するために、あなたの会社ではどれくらいの費用がかかるでしょうか? (を支払うか?) を購入し、そのメンテナンスにいくらかかりますか?
-
より大きな規模にする必要がある場合はどうしますか?
- アプリケーションのあらゆる部分を最適化するために、10 日間、それ以上、どれだけの費用がかかるでしょうか。
- さらにサーバーを数台増やすにはいくらかかりますか?
最適化すべきではないと言っているのではありません。
しかし
大きな報酬を得ることができる最適化を目指してください。
まず、オペコードキャッシュを使えば、サーバーのCPU負荷を10~50%軽減できるかもしれません...。そして、それはセットアップするのに数分しかかかりません ;-) 一方、2%のために3日間を費やすのは...。
ああ、それから、何かする前に。
監視システムを導入する
そうすれば、どのような改良がどのようになされたかを知ることができます。
モニタリングがなければ、何をしたのか、その効果を知ることができません。それが本当の最適化であるかどうかさえもわかりません!
例えば、次のようなものを使うことができます。
RRDtool
+
サボテン
.
また、CPU負荷が40%低下した状態で上司に素敵なグラフィックを見せることは、常に素晴らしいことです ;-)
とにかく、そして本当に結論から言うと
楽しんでください。
(そう、最適化は楽しいのです!)
(えー、こんなに書くとは思わなかった...。このうちの少なくともいくつかの部分が有用であることを願っています...。そして、私はこの答えを覚えておくべきです:いくつかの他の時に役立つかもしれない...)
関連
-
[解決済み】PHP - 構文エラー、予期しないT_CONSTANT_ECAPSED_STRING [閉店].
-
[解決済み] コマンドの同期がとれていない。
-
[解決済み】XAMPPエラー: www.example.com:443:0 サーバー証明書に、サーバー名と一致するIDが含まれていません。
-
[解決済み】PHPからPythonスクリプトを実行する
-
[解決済み】未定義のメソッド mysqli_stmt::get_result を呼び出す。
-
[解決済み】警告。数値でない値に遭遇しました
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] なぜGCCは、速度の代わりにサイズに最適化すると、15-20%速いコードを生成するのですか?
-
[解決済み】PHPパスワードのハッシュとソルトの安全性について
-
[解決済み] while (1) Vs. for (;;) 速度差はあるのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】接続の取得に失敗しました: php_network_getaddresses: getaddrinfo failed: 名前またはサービスが不明
-
[解決済み】不明なMySQLサーバーのホスト
-
[解決済み】XAMPPエラー: www.example.com:443:0 サーバー証明書に、サーバー名と一致するIDが含まれていません。
-
[解決済み】 $_SERVER['DOCUMENT_ROOT'] と $_SERVER['HTTP_HOST'] の違いについて]
-
[解決済み】ディレクトリ内のファイル数を数える PHP
-
[解決済み】既に開始されているPHPセッション【重複あり
-
[解決済み] Uncaught SyntaxError: JSON の位置 1 に予期しないトークン o があります。
-
[解決済み】Wordpressの子テーマのstyle.cssが効かない。
-
[解決済み】mysqli::query(): mysqli をフェッチできない
-
[解決済み] libapache2-mod-php7 パッケージの場所がわからない