0

Web サイトのカスタマイズ可能なフロント ページで、最近更新されたコンテンツを示すモジュールを 100 をはるかに超えるモジュールから選択して表示するオプションをユーザーに提供します。

すべてのデータは MySQL クエリによって生成され、その結果は memcached を介してキャッシュされます。現在のシステムは次のように機能します: ユーザーがモジュールを含むページをロードすると、モジュールはすぐにキャッシュからデータを提供され、クエリはキューに追加され、別のギアマン プロセスによって更新されます (ページのロードが行われるように)。 mysql クエリを待たないでください)。その後、そのクエリは 15 分ごとに 1 回実行され、キャッシュ内のデータが更新されます。最近要求されていないデータを継続的に更新しないように、クエリのキュー自体は定期的に削除されます。

問題は、何らかの理由でキャッシュが空の場合にどうするかです。これは頻繁に発生するわけではありませんが、発生した場合、ユーザーには現在空のモジュールが表示され、gearman プロセスでデータが更新されるため、少し後に同じ (または別の) ユーザーがページをリロードすると、表示するデータです。

私たちのトラフィックは、キャッシュが空のときにユーザーのためにライブでクエリを実行しようとすると、スタンピングで深刻な問題が発生するようなものです.同じ(おそらく遅い)クエリを何度も実行することになります.多くのユーザーがページをロードしました。スタンピングのリスクを冒さずに「ブランクモジュール」の問題を解決する方法はありますか?

4

1 に答える 1

2

これは興味深い実装ですが、MySQL の前に memcached を実装する最も一般的な方法とは少し異なります。

ほとんどの場合、ユーザーは memcached でクエリが最初に評価され、利用可能なエントリがあるかどうかを確認するように設定します。もしそうなら、彼らはmemcachedからサーバーを提供し、データベースにまったくクエリを実行しません。キャッシュ ミスがある場合は、データベースに対してクエリが実行され、結果が memcached に追加され、情報が呼び出し元に返されます。これは、通常、読み取りクエリ用のキャッシュを構築する方法です。

データが更新されている場合、データベースに対して更新が行われ、memcached 内の適切なデータが無効化または更新されます。挿入の場合も同様に、アプリケーションのニーズに応じて、キャッシュに関して何もしない (そしてそのレコードの次の読み取りでキャッシュに入力する) か、挿入に関連するデータを積極的にキャッシュに追加することができます。

このようにすれば、memcached から初期データを取得した後で、信頼できるデータを取得するためにデータベースを呼び出すという余分な手順を実行する必要がなくなります。memcached のデータは、更新/挿入時に更新/無効化された信頼できるデータのコピーになります。

あなたのコメントに基づいて、キャッシュミスの場合にデータベースで多数のクエリを回避するために試してみたいことの 1 つは、並べ替えのミューテックスを使用することです。たとえば、最初のクライアントが memcached にヒットし、そのルックアップでキャッシュ ミスが発生した場合、データが保留中であることを示す一時的な値を memcached に挿入してから、データベースに対してクエリを実行し、memcached データを更新することができます。結果。

クライアント側では、キャッシュ ミスまたは「保留中」の結果が得られた場合、特定の期間 (指数関数的に増やしたい場合があります) の後にキャッシュの再試行を開始するだけで済みます。したがって、おそらく最初に 1 秒待ってから、まだ「保留中」の結果が得られる場合は 2 秒でゲインを戻してから、4 秒で再試行します。

これにより、memcached サーバーに対するリクエストが増える可能性がありますが、データベース層の問題は解決するはずです。

于 2012-08-20T15:18:42.523 に答える