web-dev-qa-db-ja.com

PHPからEC2上のMySQLへの接続時間が長い

InnoDBを使用してデータベーススレーブに接続する際に断続的に問題が発生します。断続的に接続に2秒以上かかる。これらのサーバーは、AmazonのEC2でホストされています。

アプリサーバーはPHP 5.2/ApacheをUbuntuで実行しています。DBスレーブはPerconaのXtraDB5.1をUbuntu9.10で実行しています。データストレージにEBSRaidアレイを使用しています。

すでにスキップ名解決を使用し、アドレス0.0.0.0にバインドしています。

これは失敗しているPHPコードのスタブです

 $ tmp = mysqli_init(); 
 $ start_time = microtime(true); 
 $ tmp-> options(MYSQLI_OPT_CONNECT_TIMEOUT、2); 
 $ tmp-> real_connect($ DB_SERVERS [$ server] ['server']、
 $ DB_SERVERS [$ server] ['username']、
 $ DB_SERVERS [$ server] ['password']、
 $ DB_SERVERS [$ server] ['schema']、
 $ DB_SERVERS [$ server] ['port']); 
 if(mysqli_connect_errno()){
 $ timer = microtime(true)-$ start_time; 
 mail($ errors_to、 'DB connection error'、$ timer); 
} 

新しい接続のためにDBサーバーで利用可能な300Mb以上があり、サーバーは許可されている最大値(1,200のうち60)にはほど遠いです。両方のサーバーでのロードは、4コアのm1.xlargeインスタンスで2未満です。

Mysql設定からのいくつかのハイライト

 max_connections = 1200 
 
 thread_stack = 512K 
 thread_cache_size = 1024 
 thread_concurrency = 16 
 
 innodb-file -テーブルごと
 innodb_additional_mem_pool_size = 16M 
 innodb_buffer_pool_size = 13G 
 

減速の原因を追跡するための助けをいただければ幸いです。

[編集] ネットワークのsysctl値を更新していますが、問題が修正されていないようです。データベースサーバーとアプリケーションサーバーの両方で次の調整を行いました。

 net.ipv4.tcp_window_scaling = 1 
 net.ipv4.tcp_sack = 0 
 net.ipv4.tcp_timestamps = 0 
 net.ipv4.tcp_fin_timeout = 20 
 net.ipv4.tcp_keepalive_time = 180 
 net.ipv4.tcp_max_syn_backlog = 1280 
 net.ipv4.tcp_synack_retries = 1 
 net.core.rmem_max = 16777216 [._ ] net.core.wmem_max = 16777216 
 net.ipv4.tcp_rmem = 4096 87380 16777216 
 net.ipv4.tcp_wmem = 4096 87380 16777216 

[編集] jaimiebの提案に従って、トレースを追加し、時間を使用して次のデータをキャプチャしました。このサーバーは、この時刻に約51クエリ/秒を処理します。以下に概説する3分間のウィンドウの間に、接続エラーが1回(13:06:36に)発生しました。 1つの失敗と約9,200の成功した接続があったので、これはレポートの観点から意味のあるものを生み出すことはないと思います。

脚本:

 date >> /root/database_server.txt 
(time mysql -h database_Server -D schema_name -u appuser -p apppassword -e '')>/dev/null 2 >>/root/database_server.txt 

結果:

 
 ===アプリケーションサーバー1 === 
 Mon Feb 22 13:05:01 EST 2010 
 real 0m0.008s 
 user0m0 .001s 
 sys 0m0.000s 
 
 Mon Feb 22 13:06:01 EST 2010 
 real 0m0.007s 
 user 0m0.002s 
 sys 0m0.000s 
 
 Mon Feb 22 13:07:01 EST 2010 
 real 0m0.008s 
 user 0m0.000s 
 sys 0m0.001s 
 
 ===アプリケーションサーバー2 === 
 Mon Feb 22 13:05:01 EST 2010 
 real 0m0.009s 
 user 0m0.000s 
 sys 0m0.002s 
 
 Mon Feb 22 13:06:01 EST 2010 
 real 0m0.009s 
ユーザー0m0.001s 
 sys 0m0.003s 
 
 Mon Feb 22 13:07:01 EST 2010 
 real 0m0.008s 
 user0m0。 000s 
 sys 0m0.001s 
 
 ===データベースサーバー=== 
 Mon Feb 22 13:05:01 EST 2010 
 real0m0 .016s 
 user 0m0.000s 
 sys 0m0.010s 
 
 Mon Feb 22 13:06:01 EST 2010 
 real 0m0.006s 
ユーザー0 m0.010s 
 sys 0m0.000s 
 
 Mon Feb 22 13:07:01 EST 2010 
 real 0m0.016s 
 user0m0.000s 
 sys 0m0.010s 
 

[編集] LinkedInの質問で受け取った提案に従って、back_log値を高く設定してみました。デフォルト値(50)を実行していて、150に増やしました。また、アプリケーションとデータベースサーバーの両方でカーネル値/ proc/sys/net/core/somaxconn(最大ソケット接続)をデフォルトの128から256に上げました。その結果、プロセッサの使用率がいくらか上昇しましたが、それでも接続タイムアウトが発生しました。

4
Erik Giberti

方程式からPHPを削除すると、どの程度うまく機能しますか?CLI mysqlクライアントを使用してサーバーに接続します。dbサーバー自体とアプリサーバーの両方から試してください。

time mysql -h localhost -D dbname -u username -ppassword -e ''
2
jamieb

これは近くにないかもしれませんが、ディスクへのフラッシュを待っている可能性がありますか?多分タイムアウト?

障害が発生すると、最大1分のデータが失われる可能性があることに注意してください。

innodb_flush_log_at_trx_commit = 0(デフォルトは1)

これにより、InnoDBは1秒に1回だけログバッファーに書き込みとフラッシュを行います。 : http://dev.mysql.com/doc/refman/5.0/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit

0
sxw123