2009-09-01 19 views
1

1(選択済み)または0(選択されていない)の16種類のフィルタオプションを持つフォームを使用する検索アプリケーションで作業しています。 JSONがAJAX経由でGETリクエストを使用して取得された結果。多くのパラメータに基づいてキャッシュする方法

クエリ文字列は、その後、次のようになります。

FILTER_1 = 0 & filter_2 = 1 ...省略... & filter_16 = 1 &ページ= 20

それぞれ、検索結果には、少なくとも2ページこれを持っていますユーザが閲覧することができる。

質問:入力パラメータに基づいて検索結果をキャッシュするにはどうすればよいですか?私の最初のアイデアは、リクエストパラメータをmd5にして、ファイル名としてハッシュを使用してキャッシュファイルを書き込むことでした。

新しいリクエストが来るたびに、キャッシュファイルを検索し、キャッシュファイルがある場合は、データベースにクエリを行い、行をjson結果に変換する代わりに、そのファイルのデータを使用します。

しかし、これは多くの検索オプションのために良い考えではないようです。かなり多くのキャッシュファイル(16 * 16 ???)があります。アプリケーションは少数のユーザーしか使用しないため、すべての可能な組み合わせがキャッシュされることはありません。各結果にはXページが含まれているため、そのページはそれぞれ独自のキャッシュファイル(16 * 16 * X)になります。

このようなアプリケーションのための良いキャッシング戦略は何でしょうか?キャッシュを実装することは急に可能ですか?

答えて

1

検索パラメータはすべて0または1のいずれかのフラグであるため、ビットマスキングを考慮する必要があります。

あなたのフィルタの各々は、2の累乗である値を表すでしょう:PHPのbitwise operatorsを使用することにより

$filter_1 = 1; 
$filter_2 = 2; 
$filter_3 = 4; 
... 
$filter_8 = 256; 
... 
$filter_16 = 65536; 

を、あなたは簡単に単一の整数のすべての16個のフィルタ値を格納することができます。たとえば、値「257」は、filter_1とfilter_8の組み合わせでのみ到達できます。ユーザーがFILTER_1とfilter_8を選択した場合は、実行してビットマスクを決定することができる:

$bitmask = $filter_1 | $filter_8 //gives 257 

をすべてあなたのフィルタの状態を表すユニークなビットマスクを使用すると、単に無高価で、そのあなたのキャッシュキーなどにも使用することができますmd5操作が必要です。この場合、 "257"という名前のファイルをキャッシュに保存します。

この手法では、新しいレコードや更新されたレコードをチェックして一致するフィルタを特定し、その名前に「ビット」が設定されているファイルを削除できるため、キャッシュを無効にする簡単なツールが提供されます。 。 if (((int)$filename) & $filter == $filter) unlink($filename);。あなたのテーブルに頻繁な書き込みがあると、これはキャッシュをスキャンする際のパフォーマンス上の問題を引き起こす可能性がありますが、読み込み量の多いアプリケーションではまともなテクニックです。

これは、ビットまたはフラグを扱うときに使用するのが好きなアプローチです。しかし、このようなキャッシングが本当に必要な場合は注意深く検討する必要があります。システムのユーザーがごくわずかな場合は、実際にはいくつかの検索クエリに基づいてパフォーマンスの問題が発生していますか?また、MySQLにはクエリーキャッシングが組み込まれており、ハイリードアプリケーションでは非常に優れたパフォーマンスを発揮します。結果ページの生成ルーチンが高価な場合は、出力フラグメントをキャッシュすることは間違いなく有益ですが、ここではほんの一握りのユーザーに対してパフォーマンスのマイクロ秒を話しているだけでは、価値がないかもしれません。

1

なぜキャッシュが必要ですか?

アプリが少数のユーザーによってのみ使用される場合、キャッシュは実際には必要ない場合があります。

0

あなたが説明する要件(少数のユーザー)を考えると、すべての組み合わせをキャッシュすることは合理的です。もちろん、キャッシュは意味をなしません。典型的なクエリはどのくらい時間がかかりますか?アプリケーションは複数の人によってのみ使用されると言われているので、キャッシングする価値はありますか?私の大まかな見積もりは、クエリがこの場合に数秒かかることがなければ、キャッシングについて心配する必要はないということです。 1秒未満で、アプリケーションを超応答にしたくない場合は、キャッシングは必要ありません。

それ以外の場合、すべての組み合わせをキャッシュすることはOKであると言います。非常に多数のファイルが使用されたとしても、それらのファイルは65536個に過ぎず、多くの最新のオペレーティングシステムでは、ファイルにキャッシュする予定の場合、ディレクトリ内の何千ものファイルを簡単に処理できます。しかし、いずれにしても、キャッシュ内のアイテムの数を制限し、古いものを定期的にパージすることは合理的です。また、私はMD5を使用しません。キャッシュキー用のフィルタの0と1を連結するだけです(例:0101100010010100)。

0

最初に実際にキャッシュが必要であることを確認します(Toby提案など)。

その後、情報が新鮮である必要があると考えてください。古い値を洗い流す必要があります。例えば、memcachedのような既存のソリューションを使用することができます。

$key = calc_key(); 

$result = $memcache->get($key); 

if (!$result) { 
    $result = get_data_from_db(); 
    /* cache result for 3600 seconds == 1 hour */ 
    $memcache->set($key, $result, 0, 3600); 
} 

/* use $result */ 
関連する問題