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に上げました。その結果、プロセッサの使用率がいくらか上昇しましたが、それでも接続タイムアウトが発生しました。
方程式からPHPを削除すると、どの程度うまく機能しますか?CLI mysqlクライアントを使用してサーバーに接続します。dbサーバー自体とアプリサーバーの両方から試してください。
time mysql -h localhost -D dbname -u username -ppassword -e ''
これは近くにないかもしれませんが、ディスクへのフラッシュを待っている可能性がありますか?多分タイムアウト?
障害が発生すると、最大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