web-dev-qa-db-ja.com

PHP、MySQL、および汎用I / Oのパフォーマンスの問題をトラブルシューティングする方法

私はWordPressベースのWebサイトを共有ホスティングで実行しています。その応答時間は非常にまともです(HTMLページを取得するために約2秒、すべてのリソースをロードするために5秒))。

私はそれを専用の仮想サーバー(Ubuntu 12.04 LTS)に移動することを計画していました。これにより、理論的には改善され、共有されていないため、一貫性が向上します。ただし、ページが生成されるまでに10秒かかるため、パフォーマンスが大幅に低下しました。

サーバーで_/etc/hosts_を編集し、ドメインを_127.0.0.1_にマッピングして、ネットワークの問題を除外しました。 Apacheロードテスターabを使用してHTMLを取得したので、JS、CSS、画像はすべて除外されています。それでも10秒かかりました。

MySQLも使用するサーバーにZpanelをインストールしましたが、そのページは非常に高速(1.5秒)で表示され、phpMyAdminも表示されます。 wordpressデータベースでphpMyAdminを介して直接クエリを実行すると、クエリ時間が10〜30ミリ秒の領域で非常に高速に返されます。

メモリも十分で、使用可能な1Gbの物理メモリのうち800Mbしか使用されていないため、スワップの問題でもないようです。 PHPのパフォーマンスを向上させるために、APCもインストールしましたが、効果はありませんでした。

他に何を探すべきですか?このパフォーマンス低下の原因は何ですか?クラウドベースの仮想サーバーで実行しているので、何らかのI/Oの問題でしょうか?

私はプロバイダーに問題を提起できるようにしたいと思っていますが、何らかの診断からの実際のデータを表示せずに、彼が私のアプリケーションを非難するのではないかと心配しています。

[〜#〜] update [〜#〜] HTTPリクエストを実行したときにsar出力(毎秒)を使用:

_02:31:29        CPU     %user     %Nice   %system   %iowait    %steal     %idle
02:31:30        all      0.00      0.00      0.00      0.00      0.00    100.00
02:31:31        all      2.22      0.00      2.22      0.00      0.00     95.56
02:31:32        all     41.67      0.00      6.25      0.00      2.08     50.00
02:31:33        all     86.36      0.00     13.64      0.00      0.00      0.00
02:31:34        all     75.00      0.00     25.00      0.00      0.00      0.00
02:31:35        all     93.18      0.00      6.82      0.00      0.00      0.00
02:31:36        all     90.70      0.00      9.30      0.00      0.00      0.00
02:31:37        all     71.05      0.00      0.00      0.00      0.00     28.95
02:31:38        all     14.89      0.00     10.64      0.00      2.13     72.34
02:31:39        all      2.56      0.00      0.00      0.00      0.00     97.44
02:31:40        all      0.00      0.00      0.00      0.00      0.00    100.00
02:31:41        all      0.00      0.00      0.00      0.00      0.00    100.00
_

PDATE 2 jostenの提案の後。

I/O:

iotopOSError: Netlink error: No such file or directory (2)で失敗し、_sar -d_も_Requested activities not available in file /var/log/sysstat/sa14_で失敗します。これは、iostatも失敗するのと同じように、これが仮想マシンであるためだと思います。 _%iowait_によって報告された_sar 1 10_が常に0%であるのは、そのためでしょうか?

CPU負荷:

htopのCPU%を超えているプロセスは、実際には_Apache2_です。私はこれがおそらくデータベースであると期待していましたが、そうではありませんでした。新しいHTTPリクエストを実行すると、数秒間で最大94%になります。これが原因のようです。

_strace -f -t_と1つの要約_strace -c -f_を実行しました。 lstat呼び出し(57786)が非常に多く、2455でエラーが発生しているようです。これが正常かどうかはわかりません。それ以外の最上位の呼び出しは_wait4_で、これは正常であると私は推測します(待機しているだけです)、およびmunmap。以下のトップ5。

_% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 51.06    0.124742         897       139         6 wait4
 14.90    0.036388           1     57786      2455 lstat
  9.67    0.023622          13      1857           munmap
  7.69    0.018790          37       514           brk
  6.70    0.016361         481        34           clone
  2.87    0.006999          74        94        12 select
_

strace自体がApacheの速度を2倍遅くしました。長いトレースを理解して、CPUが数秒間スパイクする原因を示すものがあるかどうかを確認しようとしています。

パフォーマンスの良いサーバーのlstatの一般的な時間はどれくらいですか?ストレージアクセスの障害である場合にプロバイダーに建設的な方法で文句を言うことができるように、いくつかの情報を収集したいと思います。

[〜#〜] update [〜#〜]fioランダム読み取りテストの出力:

_random-read: (g=0): rw=randread, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1
fio 1.59
Starting 1 process
random-read: Laying out IO file(s) (1 file(s) / 128MB)
Jobs: 1 (f=1): [r] [100.0% done] [12185K/0K /s] [2975 /0  iops] [eta 00m:00s]
random-read: (groupid=0, jobs=1): err= 0: pid=24264
  read : io=131072KB, bw=10298KB/s, iops=2574 , runt= 12728msec
    clat (usec): min=119 , max=162219 , avg=380.34, stdev=957.37
     lat (usec): min=119 , max=162219 , avg=380.89, stdev=957.40
    bw (KB/s) : min= 7200, max=13424, per=99.89%, avg=10285.72, stdev=1608.68
  cpu          : usr=2.80%, sys=18.65%, ctx=33511, majf=0, minf=23
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=32768/0/0, short=0/0/0
     lat (usec): 250=45.57%, 500=37.17%, 750=3.41%, 1000=7.83%
     lat (msec): 2=5.67%, 4=0.27%, 10=0.08%, 20=0.01%, 250=0.01%

Run status group 0 (all jobs):
   READ: io=131072KB, aggrb=10297KB/s, minb=10545KB/s, maxb=10545KB/s, mint=12728msec, maxt=12728msec
_

私が今持っている唯一のヒントは、fio出力のCPUラインは、他のシステムと比較した場合、かなりのアクティビティを示しているように見えるということです。ローカルのUbuntuマシンで実行したところ、出力は次のとおりでした。

_cpu          : usr=0.19%, sys=0.59%, ctx=32923, majf=0, minf=23
_

usrパーセンテージは、私のサーバーで報告されているもののごく一部のようです。

[〜#〜] update [〜#〜] Re PHP APC。はい、インストールされています。phpinfoからの出力:

_APC Support enabled
Version 3.1.7
APC Debugging   Disabled
MMAP Support    Enabled
MMAP File Mask  no value
Locking type    pthread mutex Locks
Serialization Support   php
Revision    $Revision: 307215 $
Build Date  May 2 2011 19:00:42
_

確認すべき特定の設定はありますか?これらは私が持っている設定です(ローカル値、マスター値):

_apc.cache_by_default    On  On
apc.canonicalize    On  On
apc.coredump_unmap  Off Off
apc.enable_cli  Off Off
apc.enabled On  On
apc.file_md5    Off Off
apc.file_update_protection  2   2
apc.filters no value    no value
apc.gc_ttl  3600    3600
apc.include_once_override   Off Off
apc.lazy_classes    Off Off
apc.lazy_functions  Off Off
apc.max_file_size   1M  1M
apc.mmap_file_mask  no value    no value
apc.num_files_hint  1000    1000
apc.preload_path    no value    no value
apc.report_autofilter   Off Off
apc.rfc1867 Off Off
apc.rfc1867_freq    0   0
apc.rfc1867_name    APC_UPLOAD_PROGRESS APC_UPLOAD_PROGRESS
apc.rfc1867_prefix  upload_ upload_
apc.rfc1867_ttl 3600    3600
apc.serializer  default default
apc.shm_segments    1   1
apc.shm_size    32M 32M
apc.slam_defense    On  On
apc.stat    On  On
apc.stat_ctime  Off Off
apc.ttl 0   0
apc.use_request_time    On  On
apc.user_entries_hint   4096    4096
apc.user_ttl    0   0
apc.write_lock  On  On
_

[〜#〜] update [〜#〜] _apc.shm_size_を96Mに増やしました。キャッシュのフルカウントは0になり、Webサイトを何度か更新した後、キャッシュへのヒット数は96.5%になりました。 APCのメモリ使用量は25.4MBです。

ロード時間を3秒ほど短縮したようですが、画像などを取得せずにサーバー自体から純粋なwgetを実行すると、約4〜5秒になりました。他のホスティングよりも2倍以上遅いですが、間違いなく改善。

サーバーが完全にアイドル状態のときにこれらのページをレンダリングするのに時間がかかるのはなぜか不思議です(開発PCにAPCがインストールされておらず、そのような動作はありません)。そして、残りの秒数が無駄になっているのはまだ奇妙です。

4
jbx

これは、ApacheがPHPのコンパイルに多くの時間を費やしている他のケースのように見えます。オペコードキャッシュ(APCなど)がインストールされていることを確認しましたか?役立つ場合は、phpinfo()の出力にロードされたモジュールとして表示されます。それ以外の場合、mod_php内でのApacheの動作を追跡するには、最善の策はXHProfです。

Google経由でここに到着したjbx以外の方へ:ところで、他の答えは素晴らしいです。それらを読んでください。しかし、それらの答えと、それらに対するjbxの応答は、私がこの結論に到達するのに役立ちました。

2
BMDan

最初に問題が何であるかを判断する必要があります。 PHP、MySQL、I/O、負荷、メモリ、CPU、カーネルなどの場合。sarはシステムのメトリックを記録します。あなたはその行為でそれを捕まえる必要があるでしょう。 atopを構成して、プロセスアカウンティングを実行できます。これは間違いなく役立ちます。

I/Oかどうかを判断するため

iotopatopなどのツールを使用して、ディスクの使用状況を確認します。これらのツールは、IOの原因も教えてくれます。一般に、iowaitがsustainedで10%を超える場合、これが問題になる可能性があります。

sarはディスクIOをログに記録します。 sar -dを実行して確認できます(%util列を参照)。

ロードされているかどうかを判断するため

htoptopuptimeなどのツールを使用します。再度、これを実行中のプロセスに関連付けて、プロセスが実行していることの詳細を確認します。これは、スケジューラーの負荷を報告することに注意してください。 CPU使用率は反映されていません。

それがCPUかどうかを判別するため

sarは、その日を救うためにもう一度やって来ます。この情報はsar -P ALLで確認できます。リアルタイムデータにはmpstat -P ALLを使用することもできます。一般に、CPUは、すべてのCPUが100%の場合にのみ問題になります。 80%以上は、それらが使用されていることを意味します(ただし、必ずしも飽和しているわけではありません)。

それがメモリ(VM)であるかどうかを判断するため

vmstatを使用する必要があります。 vmstat -S M 1そして、swapio、およびsystem列を観察します。明らかに、大量のスワッピングはパフォーマンスに影響を与える可能性があります。 systemセクションもあります。大量の割り込みでも同じことができます。

割り込みかどうかを判断するため

vmstat -S M 1を使用できます。残念ながら、システムに正常な状態のベースラインがない場合、割り込みが問題であるかどうかを判断するのは困難です。大量の割り込み(カーネルからのアクションを必要とするハードウェアによって引き起こされる)は、システムをクロールさせます。 NICの障害は、これを行うことで悪名高いです。

カーネルであるかどうかを判別するため

これはトリッキーですが、通常はstraceperf、またはsysdigツールが必要です。そのようなツールの1つがperf topです。要約付きのstrace-c)は素晴らしいですが、システムリソースに関連して分類されません(したがって、提供されるデータは推測にすぎません)。 perf topを使用して、それがカーネルであるという結論に達するのが理想的です。マシンがサポートしている場合は、stap(SystemTap)を使用することもできます。また、straceはパフォーマンスに影響を与えることにも注意してください。システムが非常に重要な場合は、sysdigを使用する必要があります。

MySQL/PHPかどうかを判断するには

基本的に、私が上に投稿したものに従う必要があります(たとえば、perfは、カーネル時間の長い原因となっているコマンドに関する情報を提供できます。iotopatophtopそれらを使用しているシステムリソースに関する情報を提供できます);基本的に、上記のツールを使用して、何が負荷の原因であるかを特定します。

MySQLであると判断したら

実行しているクエリである可能性があります(したがって、MySQLのそのクエリでEXPLAINを使用する必要があります)。また、データベースが最適化されていること、および実行しているクエリが最適化されていることを確認する必要があります。また、使用しているテーブルエンジンが、実行していることに理想的であることを確認する必要もあります(MyISAMがInnoDBであるはずの大きなテーブルがたくさんあります)。上記のいずれも問題ではないと判断しても、MySQLが疑われる場合は、影響を受けるテーブルのデータをアーカイブして、そのテーブルへのアクセス(テーブルスキャン)を減らすことができます。また、制約の整合性を検証し、キャッシュバッファリングを有効にして、インデックスが最適であることを確認することもできます。

このプロセスに役立つツールはmytopです。しかし、mytopが提供するすべての情報は、mysqlクライアントで簡単にアクセスできます。実行するいくつかの有用なステートメント:

  • SHOW FULL PROCESSLIST\Gは、現在実行中のSQLステートメントの完全なリストと、サーバーに対するそれらのステータスを取得します。
  • SHOW ENGINE INNODB STATUS\G(InnoDBのみ)
  • EXPLAIN EXTENDED <QUERY> MySQLの実行を確認するクエリを説明します。
  • SHOW GLOBAL STATUS\Gサーバー全体のステータス

PHPであると判断したら

ツールを使用してPHPコード(xdebugなど)をプロファイリングし、生成されたプロファイルをKCacheGrindで開いて、プロファイリングされた=のパフォーマンス分析を確認できます。 PHPコード。

これらのいずれでもない場合は、サーバーをアップグレードする必要があります。

10
user101130

見渡してください 私が別の質問に与えた答え 手がかりとしてこれに似ています。

問題は、WordPress領域外の他のページが正常に読み込まれているが、WordPress自体が詰まっている場合、私が推奨する一般的なもの以外に3つのことが思い浮かびます。

  1. WordPressコードを新しいセットアップに移行したとき、ファイルシステムのすべてのパスをwp-config.phpに正しく設定したことを確認しましたか?その理由は、MySQL DB for WordPressオプションでパスが設定されている場合、パスが正しくなくてもWordPressが機能することがあるためです。それらがwp-config.phpにあることを確認すると、正しいディレクトリを使用するようにWordPressを強制し、一時フォルダとキャッシュフォルダが期待どおりに機能するようにします。
  2. データベースの速度低下?それが私ができる唯一の他のことはWordPressに固有のことですが、他のページのロードを許可します。 MySQL my.cnfがサイトのDBニーズに対して正常に機能していることを確認しますか?
  3. WordPressコードにGzip圧縮を有効にするプラグインまたは設定がありますか?一般に、Gzip圧縮は、PHPコードよりも効率的にGzip圧縮を処理できるため、ApacheまたはNgnixを介してサーバー側で実行する必要があります。したがって、WordPressでキャッシュを有効にしている場合は、PHP(WordPressが使用するもの)はGzip圧縮に適していないため、無効にします。

一般的に、私はクラウドサーバー上に問題なく大量のCMSサイト(最近ではWordPress)をセットアップしました。 10秒のページ読み込みは、クラウドホストが不十分であることの症状ではありません。私はここで私が推薦するものと私の他の答えを検討することをお勧めします。また、問題であるセットアップでクリーンWordPressインストールを実行してデバッグすることをお勧めします。それがサイト全体と比較してうまく機能する場合、サイト固有のコードに構成の問題があることは明らかです。

編集:別のアイデアがあります。あなたの設定のどこかにApache認証(htaccess)がありますか? localhostから許可するように設定されていますか?下記参照。この設定が機能することもありますが、Allow from localhostAllowのリストの最初、またはAllowのリストの唯一の項目である場合、逆引きDNSの奇妙さから窒息する可能性があります。可能であればそれを無効にすることをお勧めします。有効になっている場合と比較して、サイトの読み込み速度を確認してください。

Order Deny,Allow
Deny from all
Allow from 127.0.0.1 ::1
Allow from localhost
2
JakeGould

トラフィックの多いサイトの最大のI/Oソースの1つは、_/tmp_ I/Oです。

  1. _/tmp_は、多くのCMSシステムのphpセッションデータ用に読み取られます。たとえば、すべてのページ遷移でWordPressは、訪問者が新しいページにアクセスする権限を持っているかどうかを判断します。

  2. _/tmp_は、返されたデータまたは作成された一時的な選択セットが/ tmpにあるSQLSELECTに対して何度も書き込まれる/読み取られます。

遅いマシンのクライアントを新しい(できれば速い)マシンに移行するときに最初に行うことは、メモリのサイズです。私の速い30秒のアルゴリズムは次のとおりです。

(使用済みトップメモリ​​+使用済みスワップ)* 2

次に、新しいマシンで_/tmp_をtmpfs(メモリ)+mysqltuner(数日ごと)+ mysql(really mariadb)をmysqltunerが主に静かになるまで調整します。

パフォーマンスの遅いサーバーに新しい命を吹き込むために必要なのは、この単純なトリックだけである場合もあります。

これが行われた後、マシンがまだ遅い場合は、各サブシステムの調整を検討し始めます。

チューニングするときは、常に現在の状態を知らせるツールから始めます。

したがって、メモリのサイズ変更には、top(メモリ+スワップ+ロード)を使用します。

Apacheの場合、ログをチェックして、MaxRequestWorkersのようなメッセージが超過していないことを確認します。

古い場合[〜#〜] php [〜#〜]バージョンはAPCモニターを使用して、APCが実際に機能していることを確認します+十分なメモリがあります+ヒット率が高い-90%以上が適切です目標。

最新のPHPバージョンでは、数年前にAPCに取って代わったOpcacheでも同じことが行われます。

MySQLの場合、最初にMariaDBに切り替えます(私の経験ではより高速です)。

CMSesの場合、WordPressのように、キャッシュプラグインが機能することを誰かのWordに絶対に伝えないでください。 abを使用してサイトの速度をテストします。最初に、キャッシュなしで+キャッシュプラグインを追加して、再テストします。

ヒント:ZenCacheから始めてください。驚かれることでしょう。

最後に、slowloris [〜#〜] ddos​​ [〜#〜]セットアップしたすべての新しいサーバーに対する攻撃をシミュレートします。これは、DDOSの動作が、ネットワークレイアウト+アダプター速度+マシンリソースによって異なるためです。 Apache 4xxステータスコード(通常は400 + 408)がApacheログに表示されるのに十分な時間DDOS攻撃に耐えられるようにシステムを調整し、fail2banを使用してこれらのIPをブロックします。

I/Oチューニングの大部分は、マシンにサイトをデプロイする前に、slowlorisDDOSなどの異常な負荷状況を生成することです。このようにして、広告費やスラッシュドット効果のような実際の負荷の下で、またはDDOSや高価値攻撃のような攻撃負荷の下で、または_robots.txt_ +マシンからすべてのリソースを吸い出します。

2
David Favor