ホームページ >バックエンド開発 >PHPチュートリアル >PHP についての瞑想 - パート 6 - Drupal のパフォーマンスの問題 - Zuo Qinghou - 『Programmer』 2008 年 11 月号

PHP についての瞑想 - パート 6 - Drupal のパフォーマンスの問題 - Zuo Qinghou - 『Programmer』 2008 年 11 月号

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBオリジナル
2016-06-23 13:24:39871ブラウズ

作成時刻: 2008-11-09 01:12:51 最終更新時刻: 2008-11-09 01:12:51

この記事は、2008 年に「Programmer」誌の第 11 号に掲載されました

PHP 瞑想 No. 6: Drupal のパフォーマンスの問題
Zuo Qinghou

Drupal は、PHP に基づいたオープンソース CMS システムであり、技術的にも最も優れています。私の意見では、実装された良い PHP アプリケーションです。 Drupalのアーキテクチャは非常に優れており、マイクロカーネル+プラグインにより優れたスケーラビリティを実現しており、一般的なCMSの枠をはるかに超えています。この意味では、Drupal は Web OS と呼ぶのが適切だと思われます。 Drupal については言いたいことがたくさんあるので、将来的にはそれについて具体的に説明する記事を書くかもしれません。しかし、この記事で私が議論したいのは、Drupal コミュニティの誰もが直面するであろう、しかし誰もがそれを明確に理解しているわけではない問題、つまり Drupal のパフォーマンスの問題です。
顧客の要望により、Drupal で比較的包括的なテストを実行しました。当時の環境はデュアルサーバー(DBサーバー+Webサーバー)、ハードウェア構成はシングルCPU+4Gでした。データベースには数千のノード レコードがあります。 JMeter は、さまざまな状況 (さまざまなキャッシュ モジュールのオン/オフ、ログイン ユーザー/匿名ユーザー) の下で、さまざまなページの読み取りおよび書き込み操作をテストするために使用されてきました。
テスト結果は多くの人が考えているものと異なる可能性があります。主な結果は次の 2 つです:

1. ログイン ユーザーと匿名ユーザーのパフォーマンスの差は非常に大きいです。同じページでは、ログに記録されたユーザーの RPS (1 秒あたりのリクエスト数) は通常 20 を超えませんが、キャッシュが有効になっている匿名ユーザーの RPS は 100 を超えます。ファイルベースのキャッシュが使用されている場合は、300 を超えることもあります。
2. データベースの負荷は比較的小さいです。 Drupal は構成可能なコンテンツをデータベースに大量に配置するため、Drupal にはデータベースに対する要件が非常に高いという印象を持たれがちです。しかし実際には、キャッシュ モードでも非キャッシュ モードでも、DB サーバーの負荷は非常に小さい (CPU が 10% 未満) のに対し、Web サーバーの CPU は 80% を超えています。これは、すべての DB クエリの実行時間を追跡した後でも証明されています (すべての DB クエリの実行時間は、ページ生成時間のごく一部にすぎません)。

テストと思考を繰り返した結果、いくつかの結論に達しました。多数のログイン ユーザーが同時にログインしている場合の Drupal のボトルネックは、データベースやその他の場所ではなく、Drupal コードを実行するための CPU 時間であることは明らかです。このような状況が発生する理由は、PHP 自体の実行メカニズムと Drupal の実装方法に関係しています。 Drupal が非キャッシュ ページを生成する場合、そのページがどれほど単純であっても、最小限のモジュールのみが有効になっている場合でも、このプロセスは数十の PHP ファイルを呼び出し、数千行の PHP を実行する必要があります。コード。 PHP のメカニズムでは、PHP コードやオブジェクトをメモリ内に常駐させることはできないため、リクエストに応じて毎回完全な初期化作業を実行する必要があります。匿名ユーザーが高速である理由は、Drupal がキャッシュされたページを実行するときに完全なブートストラップ プロセスを実行しないためです。キャッシュされている場合は、キャッシュを読み取ってから作業を終了します。もちろんこちらの方が速いです。
この結論に基づいて、いくつかのことが説明できます:

1. Drupal のパフォーマンスがさまざまな環境でそれほど変わらない理由。デュアル サーバーであっても、シングル サーバーであっても、メモリが非常に少ない仮想マシンであっても、ログオンしたユーザーの RPS 値は常に 10 ~ 20 の間になります。データベースには数百、数十万のレコードがあり、影響は大きくありません。ボトルネックは DB やメモリにあるのではなく、コードの実行プロセスにあるからです。
2. APC/XCache などのコード最適化プログラムを使用するとパフォーマンスが大幅に向上する理由。私自身の仮想マシン環境では、RPS が 3 ~ 4 から 12 に増加しました。 PHP コードの実行時間が短縮されるためです。

この結論から始めて、Drupal のログに記録されたユーザーのパフォーマンスの最適化に明らかな影響を与えるいくつかの対策を列挙してみましょう:

明らかな影響を与えない対策:

1. メモリを追加します。同時リクエストの数が 10 以上しかない場合、各リクエストが 20M のメモリを占有するとしても、メモリは 200M 以上しかありません。
2. DBサーバーとWebサーバーを分離するか、DBサーバーの構成を強化します。中程度のパフォーマンスの MySQL サーバーは、200 ~ 300 の同時実行に簡単に対処できます。同時実行の数が 10 を超える場合、DB サーバーは実際には非常にアイドル状態になります。
3. Windows から Linux への移行、Apache から Lighttpd への移行、MySQL から他のデータベースへの移行など、基本的なソフトウェアの最適化。これに加えて、Windows から Linux への移行では PHP の方が効率的です。 Windows ではより優れています)、他の対策の方が高速である可能性がありますが、ボトルネックがないため大幅な改善にはなりません。

明らかな効果があるもの:

1. APC/XCache などのコード最適化プログラムを使用すると、速度が数倍向上します。誰もがすでにこれを行っていると思います。
2. WebサーバーのCPU数を増やします。デュアルコアはシングルコアよりも明らかに高速であり、4 つの CPU は 2 つの CPU よりも明らかに高速です。
3. 複数の Web サーバー + 単一の DB サーバーの構成を使用して、コード実行の圧力を異なる Web サーバーに分散します。前述したように、単一の DB サーバーは 200 以上の同時実行を簡単に処理できます。これは、理論的には 10 台を超える Web サーバーをサポートできることを意味します。
4. Quercus などのエンジンを使用して PHP コードを Java にコンパイルし、Java VM で実行すると、理論的には大幅な改善が見られます。その理由は、第一に、Java は PHP よりも効率的に実行され、第二に、Java コードはキャッシュできるため、毎回リロードする必要がないからです。テスト結果は次のとおりです: http://www.workhave.org/resin-backed-php-drives-4x-performance-improvements-drupal 。 Drupal は Quercus の下で 4 倍のパフォーマンス向上がありますが、この数値は APC/eAccelerator の下での Drupal の向上と同様であるため、実用的な価値はあまりないかもしれません。

もう 1 つの考え方は、コード自体を最適化することです。
ロガーユーザーにとって、Drupal はキャッシュ API を呼び出さないため、キャッシュ API の使用は基本的に無意味です。 Drupal.org の誰かが、ログインしているユーザーであっても、カスタマイズする必要のないページがたくさんある、つまりキャッシュできると指摘しました。しかし、Drupal はそのようなメカニズムを提供しません。ログインしたユーザーである限り、たとえ hello world を出力するだけであっても、Drupal は完全なブートストラップ プロセスを実行するため、実際には、ログインしたユーザーの状態で単一のページをキャッシュする方法はありません。
Drupal の最新バージョン (Drupal 6.4) の時点では、Drupal はロガー ユーザーに対して、一部のブロックをキャッシュ可能として設定するキャッシュ機能のみを提供しています。ブロックがサーバー時間を多く消費する場合、ブロック キャッシュは効果的に効率を向上させることができます。ただし、ブロック キャッシュはブートストラップ プロセスに影響を与えないため、ボトルネックがブートストラップ自体にある場合、ブロック キャッシュは無力になります。
Drupal.org コミュニティでは、ロガー ユーザーのキャッシュの問題について激しい議論が行われています。基本的な結論は、Drupal のアーキテクチャがこのようなものであるため、現時点では良い解決策はなく、Drupal が将来のバージョンで改善されることを期待することだけです。
Drupal のブートストラップ プロセスを研究したところ、おそらくこれが実行可能であることがわかりました。hook_boot 関数を実装します。これは、ブートストラップで最も実行される関数ですが、呼び出された時点では、ブートストラップ プロセスのほとんどはまだ実行されていません。フックブートでは、現在のページにキャッシュが必要かどうかを確認し、キャッシュが必要な場合は、キャッシュを直接読み取ってページを生成し、exit() を呼び出して強制的に終了します。これは理論的には可能ですが、ちょっと裏技的すぎます。
これは Drupal の場合ですが、他の PHP フレームワーク、特に半公式の Zend Framework のパフォーマンスはどうでしょうか?検索すると、インターネット上で PHP フレームワークの比較ベンチマークを見つけました。URL は http://www.avnetlabs.com/php/php-framework-comparison-benchmarks です。このレポートのデータによると、APC を使用しない場合、Zend Framework のパフォーマンスはネイティブ PHP の 10% にすぎず、3% 未満です。もちろん、このレポートのデータは必ずしも網羅的ではなく、異なる環境における Zend Framework のパフォーマンスも異なるはずです。ただし、Zend Framework のパフォーマンスが Baseline PHP よりも大幅に遅れていることは決定的です。
なぜ主流の PHP フレームワークのパフォーマンスにこのような問題があるのでしょうか?実際、これを理解するのは難しくありません。 PHP 瞑想シリーズの最初の記事での PHP 作業モデルに関する議論を振り返ると、PHP にはメモリ常駐プロセスがないため、リクエストが発生するたびにすべてのオブジェクトを初期化する必要があり、その結果、多くの時間が費やされます。プロセスコードの実行中。 PHP プログラムが単なる単純なスクリプトである場合には問題ありませんが、リクエストが処理されるたびに数千行のコードが繰り返し呼び出される複雑なアーキテクチャでは、この問題は非常に顕著になります。さらに、PHP の将来のバージョンでこのメカニズムが改善されない限り、この問題を完全に解決することはできません。
ということは、PHP は小規模な Web サイトにのみ適用でき、同時実行性の高い大規模な Web サイトでは使用できないということですか?もちろん違います。実際、PHP は Yahoo や他の多くの有名な巨大 Web サイトで広く使用されています。その理由は、PHP はコンテンツ ジェネレーターとしてのみ使用され、生成されたコンテンツはキャッシュされた静的テキストに変換されるためです。これは PHP プログラムのパフォーマンスとは関係ありません。ただし、ユーザーが Web サイトを閲覧するだけでなく、頻繁に Web サイトを操作する必要がある場合、PHP のパフォーマンスは C や Java と比較できないだけでなく、どちらもスクリプト言語である Python や Ruby とも比較できません。言い換えれば、PHP は Web 2.0 アプリケーションの第一選択ではなく、ニュース ポータルなどのコンテンツ発行サイトに適しています。
この一連の記事の最後では、PHP の限界について説明します。 PHP を愛する人にとっては、これはイライラするかもしれません。ただし、これによって PHP の優れた言語としての評判が損なわれることはありません。定規は短く、インチは長く、私たちが使い慣れているツールについては、その限界を理解する必要があります。それは、ツールをより効果的に使用するのにも役立ちます。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。