簡體   English   中英

在.NET webapp中緩存復雜搜索查詢的最佳方法是什么?

[英]What's the best way to cache complicated search queries in a .NET webapp?

我有一個網站,允許用戶使用各種搜索條件查詢特定的食譜。 例如,您可以說“向我展示我可以在30分鍾內使用雞肉,大蒜和面食而不是橄欖油制作的所有食譜。”

此查詢通過JSON發送到Web服務器,並反序列化為SearchQuery對象(具有各種屬性,數組等)。

實際的數據庫查詢本身相當昂貴,並且有很多默認搜索模板會經常使用。 出於這個原因,我想開始緩存常見的查詢。 我已經對各種緩存技術進行了一些調查,並閱讀了很多關於這個主題的其他SO帖子,但我仍然在尋找建議。 現在,我正在考慮以下選項:

  1. 內置System.Web.Caching這將提供對緩存中有多少項,它們到期時及其優先級的大量控制。 但是,緩存的對象由字符串鍵入,而不是可哈希的對象。 我不僅需要能夠將SearchQuery對象轉換為字符串,而且哈希必須是完美的並且不會產生任何沖突。
  2. 開發我自己的InMemory緩存:我真正喜歡的是一個Dictionary<SearchQuery, Results>對象,它在所有會話中都存在於內存中。 由於搜索結果可能會變得相當大,我希望能夠限制緩存多少查詢並為舊查詢提供過期方式。 像FIFO隊列這樣的東西在這里可以很好地工作。 我擔心線程安全等問題,我想知道編寫自己的緩存是否值得付出努力。

我還研究了其他一些第三方緩存提供程序,如NCacheVelocity 這些都是分布式緩存提供商,對我目前所需要的東西來說可能完全過度。 此外,似乎我看到的每個緩存系統仍然需要通過字符串鍵入對象。 理想情況下,我想要一些包含緩存的東西,允許我按對象的哈希值鍵入,並允許我控制到期時間和優先級。

我很感激任何建議或參考免費和優選的開源解決方案,可以幫助我在這里。 謝謝!

根據您的意思,我建議您使用System.Web.Caching並將其構建到DataAccess層中,以便將其與其他系統DataAccess來。 調用時,您可以根據業務/應用程序需求進行實時查詢或從緩存對象中提取。 我今天這樣做,但使用Memcached

快速查看企業庫緩存應用程序塊。 假設您需要一個Web應用程序范圍的緩存,這可能是您正在尋找的解決方案。

內存緩存應該很容易實現。 我無法想到為什么你應該特別關注驗證SearchQuery對象與任何其他對象的唯一性的任何原因 - 也就是說,當鍵必須是一個字符串時,你可以將原始對象與結果一起存儲在緩存,並在您對哈希進行點擊后直接驗證相等性。 我會使用System.Web.Caching來獲得您注意到的好處(到期等)。 如果碰巧碰撞,那么第二個就不會被緩存。 但這種情況極為罕見。

此外,存儲搜索結果所需的內存量應該是微不足道的。 您不需要完整詳細地保留每一行的每個字段的數據。 您只需要保持快速訪問每個結果的方式,例如int主鍵。

最后,如果可能有數千個搜索結果可以緩存,您甚至不需要為每個搜索結果保留一個ID - 只需保留前100個或其他內容(以及總點擊次數)。 我懷疑如果你分析人們如何使用搜索結果,那么這是一個超出幾頁的罕見人物。 如果有人這樣做,那么您可以再次運行查詢。

所以基本上你只是為每個常見搜索的第一個X記錄存儲一個主鍵,然后如果你的緩存命中,你所要做的就是對一些索引鍵進行非常便宜的查找。

我假設從SearchQuery對象生成數據庫查詢並不昂貴,並且您希望緩存從執行查詢獲得的結果(即行集)。

您可以從SearchQuery對象生成查詢文本,並使用該文本作為使用System.Web.Caching進行查找的鍵。

從快速閱讀Cache類的文檔看來,密鑰必須是唯一的 - 如果您使用它們查詢文本,它們將是它們 - 而不是密鑰的哈希。

編輯

如果您擔心長緩存密鑰,請檢查以下鏈接:

在asp.net中緩存密鑰長度

HttpRuntime.Cache對象中緩存鍵的最大長度?

似乎Cache類將緩存的項存儲在內部字典中,該字典使用密鑰的哈希 具有相同散列的密鑰(查詢文本)最終將在字典中的同一個存儲桶中進行,其中只需快速線性搜索以在執行高速緩存查找時找到所需的存儲區。 所以我認為你可以使用長鍵串。

asp.net緩存是經過深思熟慮的,我不認為這是你需要其他東西的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM