sql >> データベース >  >> RDS >> Mysql

並行性の問題を処理するための最良の方法

    ドニーの答え(ポーリング)はおそらくあなたの最良の選択肢です-シンプルでうまくいきます。ほぼすべてのケースをカバーします(非常に人気のあるサイトであっても、単純なPKルックアップがパフォーマンスを低下させる可能性は低いです)。

    完全を期すため、またポーリングを避けたい場合は、プッシュモデル> 。ウィキペディアの記事で説明されているさまざまな方法があります。ライトスルーキャッシュを維持できる場合(レコードを更新するたびに、キャッシュを更新します)、データベースの負荷をほぼ完全になくすことができます。

    ただし、タイムスタンプの「last_updated」列は使用しないでください。同じ秒内の編集は前代未聞ではありません。 2つのリクエストが同じサーバーに同時に着信した場合に、違いを検出できるように、追加情報(更新を行ったサーバー、リモートアドレス、ポートなど)を追加すれば、問題を回避できます。ただし、その精度が必要な場合は、一意のリビジョンフィールドを使用することもできます(必ずしも増分整数である必要はなく、そのレコードの存続期間内で一意である必要があります)。

    誰かが永続的な接続について言及しました-これはポーリングクエリのセットアップコストを削減します(すべての接続は当然、データベースとホストマシンのリソースを消費します)。単一の接続(または可能な限り少ない)を常に(または可能な限り長く)開いたままにして、それを(必要に応じてキャッシュとメモ化と組み合わせて)使用します。

    最後に、UPDATEまたはINSERTに条件を追加できるSQLステートメントがあります。私のSQlは本当に錆びていますが、UPDATE ... WHERE ...のようなものだと思います 。このレベルの保護に一致させるには、更新を送信する前に独自の行ロックを実行する必要があります(および必要になる可能性のあるすべてのエラー処理とクリーンアップ)。これが必要になる可能性はほとんどありません。完全を期すために言及しているだけです。

    編集:

    あなたの解決策はうまく聞こえます(キャッシュタイムスタンプ、別のサーバーへのプロキシポーリングリクエスト)。私が行う唯一の変更は、保存するたびにキャッシュされたタイムスタンプを更新することです。これにより、キャッシュが最新の状態に保たれます。また、保存時にデータベースから直接タイムスタンプをチェックして、古いキャッシュデータによる保存の侵入を防ぎます。

    キャッシュにAPCを使用する場合、2番目のHTTPサーバーは意味がありません。同じマシンで実行する必要があります(APCは共有メモリを使用します)。同じ物理マシンが作業を行いますが、2番目のHTTPサーバーのオーバーヘッドが追加されます。ポーリング要求を2番目のサーバー(この場合はlighttpd)にオフロードする場合は、2番目の物理マシンのApacheの前にlighttppdをセットアップし、共有キャッシュサーバー(memcache)を使用してlighttpdサーバーはキャッシュされたタイムスタンプを読み取ることができ、Apacheはキャッシュされたタイムスタンプを更新できます。 Apacheの前にlighttpdを配置する理由は、ほとんどのリクエストがポーリングリクエストである場合、より重いApacheプロセスの使用を回避することです。

    おそらく、2台目のサーバーはまったく必要ありません。 Apacheは追加のリクエストを処理できるはずです。できない場合は、構成を再検討します(具体的には、実行するワーカープロセスの数と、強制終了される前に処理できるリクエストの数を制御するディレクティブ)。



    1. ActiveRecord_Associations_CollectionProxyのRails未定義メソッド

    2. ORDER BY句でカスタムオーダーを定義するにはどうすればよいですか?

    3. MySQL複合インデックスが使用されていません

    4. mysqlmax_allowed_pa​​cketが自動的に1mにリセットされる理由