web-dev-qa-db-ja.com

php5 + MySQLを200リクエスト/秒以上にスケーリングする方法は?

私はホームページのパフォーマンスを微調整しています。現在、3.14.byで毎秒約200のリクエストを処理して6つのSQLクエリを処理し、3.14.by/forumでphpBBフォーラムである毎秒20リクエストを処理しています。

奇妙なことに、一部のVPSと専用のAtom 330サーバーでは、数値はほぼ同じです。

サーバーソフトウェアは次のとおりです。Apache2+ mod_php prefork 4子(ここでは別の数を試してみました)、php5、APC、nginx、memcached for PHPセッションストレージ。

MySQLは、利用可能な容量の約30%を消費するように構成されていますRAM(VPSでは150Mb、専用サーバーでは700Mb)

これはどこかにボトルネックがあり、私が上がれないように見えます、何か提案はありますか? (つまり、6つ未満のSQLを実行すると処理が速くなることを知っていますが、sqldはクエリのキャッシュにより数%を超えないため、これは制限要因のようには見えません)

PreforkされたApache2をキックしてnginx + phpだけを残す方がはるかに速いことを誰かがテストしましたか?

いくつかのベンチマーク

Small 40-byte static file: 1484 r/s via nginx+Apache2, 2452 if we talk to Apache2 directly. 
Small "Hello world" php script: 458 r/s via ngin+Apache2.

pdate:キャッシュされたデータに対するMySQLのパフォーマンスがボトルネックになっているようです。 1つのSQLを含むページは354リクエスト/秒を示し、6つのSQLは180リクエスト/秒を示します。ここで何を調整できると思いますか? (MySQLでは100-200Mbをフォークできます)

[client]
port        = 3306
socket      = /var/run/mysqld/mysqld.sock

[mysqld_safe]
socket      = /var/run/mysqld/mysqld.sock
Nice        = 0

[mysqld]
default-character-set=cp1251
collation-server=cp1251_general_cs

skip-character-set-client-handshake

user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
skip-external-locking

bind-address        = 127.0.0.1

key_buffer      = 16M
max_allowed_packet  = 8M
thread_stack        = 64K
thread_cache_size   = 16
sort_buffer_size    = 8M
read_buffer_size    = 1M

myisam-recover      = BACKUP
max_connections        = 650
table_cache            = 256
thread_concurrency     = 10

query_cache_limit       = 1M
query_cache_size        = 16M

expire_logs_days    = 10
max_binlog_size         = 100M

[mysqldump]
quick
quote-names
max_allowed_packet  = 8M

[mysql]
[isamchk]
key_buffer      = 8M

!includedir /etc/mysql/conf.d/
16
BarsMonster

もちろん、試すことができることはたくさんあります。最善の策は、インデックスを使用しないクエリ(それらのログを有効にする)や他の最適化されていないクエリのログを追跡することです。長年にわたってパフォーマンス関連のオプションの膨大なリストをまとめてきたので、参考のためにここに小さなサブセットを含めました。以下は、試すことができる一般的な注意事項です(まだ行っていない場合)。

MySQL

  • query_cache_type = 1-SQLクエリのキャッシュがオンです。 2に設定すると、SQL_CACHEヒントが渡された場合にのみクエリがキャッシュされます。タイプ1と同様に、SQL_NO_CACHEヒントを使用して特定のクエリのキャッシュを無効にすることができます。
  • key_buffer_size = 128M(デフォルト:8M)-MyISAMテーブルインデックスのメモリバッファー。専用サーバーでは、key_buffer_sizeをサーバー上のメモリの総量の少なくとも4分の1、ただし半分以下に設定することを目指します。
  • query_cache_size = 64M(デフォルト:0)-クエリキャッシュのサイズ
  • back_log = 100(デフォルト:50、最大:65535)-未処理の接続要求のキュー。短時間で多くの接続がある場合にのみ問題
  • join_buffer_size = 1M(デフォルト:131072)-全表スキャン(インデックスなし)時に使用されるバッファー
  • table_cache = 2048(デフォルト:256)-max_user_connectionsに、最も重いSQLクエリに含まれるJOINの最大数を掛けます。目安として、ピーク時の「open_tables」変数を使用してください。 「opened_tables」変数も見てください。「open_tables」に近いはずです。
  • query_prealloc_size = 32K(デフォルト:8K)-ステートメントの解析と実行のための永続的なメモリ。複雑なクエリがある場合は増やす
  • sort_buffer_size = 16M(デフォルト:2M)-ソートに役立ちます(ORDER BYおよびGROUP BY操作)
  • read_buffer_size = 2M(デフォルト:128K)-順次スキャンに役立ちます。順次スキャンが多い場合は増やします。
  • read_rnd_buffer_size = 4M-MyISAMテーブルがソート後の読み取りを高速化するのに役立ちます
  • max_length_for_sort_data-ソートファイルに行ポインタの代わりに保存する行サイズ。ランダムなテーブル読み取りを回避できます
  • key_cache_age_threshold = 3000(デフォルト:300)-キーキャッシュをホットゾーンに保持する時間(ウォームに降格される前)
  • key_cache_division_limit = 50(デフォルト:100)-より高度なキャッシュ追い出しメカニズム(2レベル)を有効にします。最下位レベルに維持するパーセンテージを示します。 delay_key_write = ALL-インデックスが更新されるたびにテーブルのキーバッファーがフラッシュされるのではなく、テーブルが閉じられたときにのみフラッシュされます。これにより、キーへの書き込みが大幅に高速化されますが、この機能を使用する場合は、-myisam-recover = BACKUP、FORCEオプションを指定してサーバーを起動することにより、すべてのMyISAMテーブルの自動チェックを追加する必要があります
  • memlock = 1-プロセスをメモリにロックします(スワップイン/スワップアウトを減らすため)

Apache

  • 生成方法を変更します(たとえば、mpmに)
  • 可能であればログを無効にする
  • AllowOverride None-可能な限り.htaccessを無効にします。使用されていない場合は、.htaccessファイルを探すためにApacheを停止するため、ファイル検索要求を保存します。
  • SendBufferSize-OSのデフォルトに設定します。輻輳したネットワークでは、このパラメーターを通常ダウンロードされる最大のファイルのサイズに近い値に設定する必要があります
  • キープアライブオフ(デフォルトはオン)-lingerdをインストールしてネットワーク接続を適切に閉じ、より高速に
  • DirectoryIndex index.php-ファイルリストをできるだけ短く、絶対的なものにします。
  • オプションFollowSymLinks-Apacheでのファイルアクセスプロセスを簡略化する
  • Mod_rewriteまたは少なくとも複雑な正規表現の使用を避けます
  • ServerToken = prod

[〜#〜] php [〜#〜]

  • variables_order = "GPCS"(環境変数が必要ない場合)
  • register_globals = Off-セキュリティリスクであるだけでなく、パフォーマンスにも影響します
  • Include_pathを可能な限り最小限に保つ(余分なファイルシステム検索を回避する)
  • display_errors = Off-エラーの表示を無効にします。すべての本番サーバーに強く推奨されます(問題が発生した場合に醜いエラーメッセージを表示しません)。
  • magic_quotes_gpc =オフ
  • magic_quotes _ * =オフ
  • output_buffering = On
  • 可能であればログを無効にする
  • exposed_php =オフ
  • register_argc_argv =オフ
  • always_populate_raw_post_data =オフ
  • phpが最初に探す場所にphp.iniファイルを配置します。
  • session.gc_divisor = 1000または10000
  • session.save_path = "N;/path"-大規模なサイトでは、使用を検討してください。セッションファイルをサブディレクトリに分割します

OS調整

  • 使用済みのハードディスクを-o noatimeオプション(アクセス時間なし)でマウントします。また、このオプションを/ etc/fstabファイルに追加します。
  • / proc/sys/vm/swappiness(0から100)を調整して、何が最良の結果になるかを確認します
  • RAM Disks-mount --bind -ttmpfs/tmp/tmpを使用します
29
Ivan Peevski

ボトルネックがCPUでない場合は、IO-ネットワークまたはディスクのいずれかです。つまり、IOがどれだけ進んでいるかを確認する必要があります。そのネットワークを考えたことはありません(10 Mbpsの半二重リンクを使用している場合を除きますが、自動検出が適切に機能していない場合に備えてスイッチを確認する価値はあります)。

これにより、ディスクIOが残ります。これは、特にVPSで大きな要因になる可能性があります。 sarまたはiostatを使用してディスクを確認し、次に、ディスクが頻繁に使用されている場合に詳細を確認する方法をググる。

1
gbjbaanb

Nginxmemcached )または Varnish のいずれかでキャッシュを調べます。

少なくとも、SaveTheRbtzが言ったようにNginxで静的ファイルを処理する必要があります。

1
Espennilsen

サーバーには問題がないように見えるので、おそらく負荷ジェネレーターに問題があります。複数のマシンで実行してみてください。

1
OliverS

Apacheが許可する最大接続数に達しているように思えます。Apacheの設定を見てください。 I/Oやメモリのような他の制限に縛られていない場合は、サーバー制限と最大クライアント数を増やすと効果的です。 mpm_prefork_moduleまたはmpm_worker_moduleの値を確認し、必要に応じて調整してください。

 ServerLimit 512 
 MaxClients 512 
1
Erik Giberti

この負荷はツールまたは実際の負荷によって生成されたものですか?

Memcachedを確認してください。接続速度が高いと、アプリケーションで遅延が発生する問題が発生しました。

Load Generatorを使用している場合、小さな静的ページにアクセスすると何が得られますか?

ロード中に、ネットワークスタックでTIME_WAIT状態を確認することができます。おそらく、接続キューがいっぱいになっています。

あなたが見ることができる約100の理由と項目がありますが、これ以上の情報なしで、私はこの時点で推測を捨てています。

0
jeffatrackaid