2012-01-26 11 views
2

私は、ユーザーがさまざまな検索基準を使用して特定のレシピをクエリできるようにするウェブサイトを持っています。たとえば、「鶏肉、ニンニク、パスタを使用し、オリーブオイルは使用しない30分以内にすべてのレシピを表示できます」と言うことができます。.NET Webアプリケーションで複雑な検索クエリをキャッシュする最良の方法は何ですか?

このクエリは、JSON経由でWebサーバーに送信され、SearchQueryオブジェクト(さまざまなプロパティ、配列など)にデシリアライズされます。

実際のデータベースクエリ自体はかなり高価であり、非常に頻繁に使用される多くのデフォルトの検索テンプレートがあります。このため、一般的なクエリのキャッシュを開始したいと考えています。私は様々なキャッシング技術を少し調べて、その件に関する他のSO投稿を読んでいますが、私はまだどの方法を検討するのかアドバイスを探しています。今、私は、次のオプションを検討している:

System.Web.Cachingに建てられ
  1. これは期限が切れるとき、キャッシュ内にあるどのように多くのアイテムを制御の多くは、その優先順位を提供します。ただし、キャッシュされたオブジェクトは、ハッシュ可能なオブジェクトではなく、文字列でキーインされます。 SearchQueryオブジェクトを文字列に変換できるだけでなく、ハッシュも完璧で、衝突を起こさないようにする必要があります。
  2. 私の独自のInMemoryキャッシュを開発してください:本当に好きなのは、すべてのセッションでメモリ内に残るDictionary<SearchQuery, Results>オブジェクトです。検索結果はかなり大きくなり始める可能性があるので、キャッシュされるクエリの数を制限し、古いクエリが期限切れになる方法を提供したいと考えています。 FIFOキューのようなものはここでうまくいくでしょう。私はスレッドの安全性などのことを心配しています。私のキャッシュを書くことがここで努力する価値があるのだろうかと思っています。

NCacheVelocityなど、他のサードパーティのキャッシュプロバイダも調べました。これらは両方とも分散キャッシュ・プロバイダであり、現時点で必要なものに対してはおそらく完全に過剰です。さらに、私が見たすべてのキャッシュシステムは、オブジェクトが文字列でキーイングされている必要があります。理想的には、処理中のキャッシュを保持し、オブジェクトのハッシュ値をキー入力できるようにし、有効期限や優先順位を制御できるようにします。

ここで私を助けてくれる無料のオープンソースソリューションに関するアドバイスや参考文献をお待ちしております。ありがとう!

答えて

4

あなたが言っていることに基づいて、私はSystem.Web.Cachingを使用し、それをあなたの残りのシステムから遮蔽するDataAccess層に構築することをお勧めします。コールされると、リアルタイムのクエリを作成したり、ビジネス/アプリケーションのニーズに基づいてキャッシュされたオブジェクトからプルすることができます。私は今日これを行うが、Memcachedとする。

+0

基本的にオプション1です。 'SearchQuery'を文字列にハッシュする方法を見つけますか? –

+0

はい、Lib + Method +などのキーを使って呼び出しの固有キーを生成しますが、SearchQuery/Paramsに基づいて同じことができます。 –

+0

'SearchQuery'のためのユニークな文字列ハッシュを得る能力は、より柔軟性があります。たとえば、Webサーバーを追加して、分散キャッシュをいつか設定したい場合は、もっと多くのオプションを利用できます。 –

2

キャッシングアプリケーションブロックEnterprise libraryを見てください。 Webアプリケーション全体のキャッシュを必要としているとすれば、これはあなたが探している解決策かもしれません。

+0

さて、私はちょっとだけでなく、AppFabricのものを調べました。しかし、私の状況では、ASP.NETに組み込まれている 'System.Web.Caching'サポートよりも、実際にこれに利点はありません。 –

+0

この投稿はあなたの状況を考慮して、私の提案に反していますが、読む価値はあります:http://stackoverflow.com/questions/21870/system-web-caching-vs-enterprise-library-caching-block私は「ラッパーの作成」ステートメントに非常に同意します。なぜなら、どのソリューションを選択しても、後で必要に応じて簡単に中断するのは簡単です。 – rie819

+0

うわー!確かに、私はスケールアウトする場合は、私はいつかNCacheやAppFabricにドロップすることができますので、すべてのものをラップしたいと思います。素晴らしいアドバイス。 –

2

インメモリキャッシュは実装が非常に簡単です。 SearchQueryオブジェクトの一意性を他のものと比較して検証することについて特に懸念する必要がある理由は考えられません。つまり、キーは文字列でなければなりませんが、元のオブジェクトを結果とともにハッシュをヒットした直後に、キャッシュを作成し、等価性を検証します。あなたが指摘した利点(有効期限など)にはSystem.Web.Cachingを使用します。衝突が発生した場合、2番目のものはキャッシュされません。しかし、これは非常にまれです。

また、検索結果を格納するために必要なメモリの量も簡単です。単一の行のすべてのフィールドのデータを完全に詳細に保持する必要はありません。各結果にすばやくアクセスするだけで済みます(例: int主キー。

最後に、キャッシュ可能な検索の結果が何千もある場合は、それぞれのIDを保持する必要はありません。最初の100個(またはヒット)。あなたが検索結果をどのように使っているかを分析した場合、それは数ページを超える珍しい人です。誰かがした場合、あなたはもう一度クエリを実行することができます。

基本的には、各共通検索の最初のXレコードのプライマリキーを保存しているだけで、キャッシュにヒットした場合は、一握りの非常に安価な検索を実行するだけですインデックス付きキー。

1

私は、SearchQueryオブジェクトからデータベースクエリを生成することはコストがかからず、クエリを実行して得られた結果(つまり行セット)をキャッシュしたいと考えています。

SearchQueryオブジェクトからクエリテキストを生成し、そのテキストをSystem.Web.Cachingを使用するルックアップのキーとして使用できます。

Cacheクラスのドキュメントを簡単に読んで、キーを一意にする必要があります。キーのハッシュではなく、クエリテキストを使用した場合のようになります。

EDIT

あなたが長いキャッシュキーを懸念している場合は、以下のリンクをチェック:

Cache key length in asp.net

Maximum length of cache keys in HttpRuntime.Cache object?

をCacheクラスは内部でキャッシュされたアイテムを格納しているようです辞書には、キーのハッシュが使用されています。同じハッシュを持つキー(クエリーテキスト)は、辞書内の同じバケットで終了します。クイックリニア検索では、キャッシュルックアップ時に必要なものを見つけることができます。だから私はあなたが長いキーストリングで大丈夫だろうと思う。

asp.netキャッシングはかなりよく考えられており、これはあなたが別のものが必要なケースではないと私は考えています。

+0

そうですか、 'SearchQuery'のシリアライズされたXMLやJSONのキーです - 本当に長いキャッシュキーに問題があるのだろうか?どちらにしても、キーアイテムにはちょっとしたことがあるようです私はオブジェクトでキーと内部でキーの衝突を処理できる独自のメモリ内キャッシュを実装する方が良いです。 –

+0

@Mike私の編集長鍵を参照してください –

+0

そうです、多くの人が非常に冗長なキーを使用することに興味があるようです。内部的にキャッシュは32ビットのハッシュで保存されているので、最初にキーをオブジェクトにしておく必要があります:) –

関連する問題