0

私は簡潔にしようとしますが、それでも完全です。貴重な時間を費やして可能な解決策を教えてくれた人たちに、事前に感謝します。


Ubuntu 環境の PHP/Mysql アプリケーション。

元の問題:

Keep getting error 'to_many_connections'.

私がチェックするとき:

show processlist;

多くの睡眠プロセスがあります。したがって、それらが新しい着信接続をブロックするため、それらが to_many_connections エラーの原因であると考えました。

mysql 設定の変更:

Raise max_connections from 250 to 400;
lower wait_timeout from 60 to 15;

接続は機能しているように見えましたが、現在、Apache がメモリを大量に消費しています。この 2 つの設定を変更するだけで、11G から 25G 以上になりました。150 個の追加の mysql_connections が 14G の余分なメモリを消費するとは想像できませんか? また、Apacheのメモリ使用量を増やすためにwait_timeout設定を低くするとは思わないでしょう。より少ないメモリを使用するため、メモリ内の接続を少なくする必要がありますか? プロセスの使用率が上がると予想していましたが、メモリはそうではありませんでした。そして確かに、それらの膨大な量ではありません。

mysql設定を再試行しました:

keep max_connections at 400
raise wait_timeout to 30 sec

メモリ使用量は約 5 分間低下しましたが、その後再び上昇しました。

その他の注意事項:

特定のテーブルに対してロックされたプロセスがたくさんあることに気付きました。(mysql: show processlist;) 更新:テーブルは MyISSAM テーブルです。

また、いくつかのデータベースの実装を変更しましたが、これは理想的ではありません。コードのリファクタリングの段階にあるため、一部のページではデータベースへの 2 つの接続を使用しています。mysql_query 機能から PDO 機能への切り替え

アップデート:

新しい pdo 機能には、永続的な接続が明示的に false に設定されています (デフォルトは false ですが)。古い mysql 機能も永続的な接続を使用しません。

    public function __construct($dbname, $username, $password) {
        parent::__construct('mysql:hostname=localhost;dbname=' . $dbname . ';', $username, $password, array(
            PDO::ATTR_PERSISTENT => false,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8;"
        ));
    }

データベースに複数の接続を確立することがベスト プラクティスとはほど遠いことは承知していますが、現在のアプリケーションには多くのデザイン パターンが欠けており、すべてがまだ手続き型であり、mvc も OOP もありません。私の雇用主は結果を望んでおり、現時点では、アプリケーションを完全に書き直して、かなり前に実装されるべきであった設計/コーディング標準を使用するつもりはないため、私はこの種の慣行を行う義務があります. いずれにせよ、このコードが実際の原因であるとしたら、私は驚くでしょう。なぜなら、このコードは 1 週間以上完璧に動作しており、バーゲン期間 (1 か月の巨大なバーゲン/取引当店で)。

この問題についての洞察は大歓迎です。この時点で、これを解決するための次のステップが何であるかはわかりません。

update2 は問題が見つかったためクローズされましたが、元の投稿とは何の関係もありませんでした。

4

1 に答える 1

1

これらの大きな複雑な問題を抱えているあなたに同情します!あなたが試したかどうかを確認するために、いくつかのことを紹介します

  • re: apache メモリ - 私が最近行っている apache テストは、実際には MaxClients の数を減らすことを示しています。ab または siege テストでは、テスト環境で 256 ではなく 12 で実際にパフォーマンスが向上します。これまでのところ、本番環境ではなく開発環境で

  • ロックされた mysql プロセスに関して、使用しているテーブルの種類は何ですか? MyIsam は、InnoDB よりもロックの問題が発生しやすいと思います。Myisam はテーブル ロックであり、innodb は行 iirc です。

  • 書いてて気づいた

    新しい pdo 機能には、永続的な接続が false に設定されています

古いコードは永続的な接続を使用していますか? 私はあまり運が良かった、またはそれらを使用したことがありません

  • どのくらいキャッシュしますか?mysql クエリ キャッシングを有効にしていますか? Web サーバーと mysql の間で memcache または nosql システムを使用するのはどうですか?

多くの人が memcache などは遅い/クラッシュするアプリの解決策ではないと言うでしょうが、それがあなたにもっと多くの呼吸の余地を与えるなら、なぜですか? また、キャッシュがキャッシュではない場合について、少し哲学がありますか? たとえば、メモリに保存するだけでなくディスクにも保存するredis.ioを使用します。管理システムがmysqlを更新するたびに、この「キャッシュ」も更新します。データがダウンタイムを生き残るという意味で永続的です-最小限のウォームアップの問題-そして常に最新なのでラグなし。知的には、そのようなことを回避する警官のように感じるかもしれませんが、redis は、私たちの環境で同じタスクのために mysql を取得するよりも 6 倍高速です (箱から出してすぐに)...

更新 myisam を使用しているようです。ロックの問題はそれに起因する可能性があります。iirc を更新すると、その間テーブル全体がロックされ、クエリが積み重なり、雪だるま式になり、すべてが失敗する可能性があります。

re: キャッシング レイヤー キャッシングは、データベースへの接続が少なくなるため、問題を回避/延期できます。まったく接続しないページがいくつかあります。私は文字通り mysqld 停止を行うことができ、技術的に動的であっても機能します

関連するメモとして、ページの上部で定期的に DB に接続しますか、それとも必要な場合にのみ接続しますか?

更新 追加のコメントは、サード パーティ プロバイダーからの xml フィード (ページ リクエストで実行される - 政治的理由により事前キャッシュできませんでした!) が、サイトの他の領域と同じように遅くなるという同様の問題を思い出させてくれました。 XML フィードが遅くなると、ボトルネックが発生して Apache プロセスが滞り、サーバーの速度が低下します。つまり、ページが完了するのを待たない人もいますが、DB は中止されたリクエストに情報を提供しようとします。新しいものだけでなく、最初はDBの問題のように見えました

于 2013-01-09T09:49:46.393 に答える