2014-09-05 36 views
0

我有一個約500個項目的靜態對象列表。Redis緩存靜態列表按過濾器搜索

此對象具有類似於(id [int],Name [string],attribute1 [string],attribute2 [string])的屬性。

我已經將此對象序列化爲字符串並作爲 字符串鍵值存儲到redis中。但是我需要根據 不同的用戶搜索過濾器來過濾這個500個項目的列表,並將這個列表的子集給予用戶。

我可以用兩種方法做到這一點,一是將此列表添加到表和索引,並使用sql應用搜索過濾器。其他是我從redis每次拉這個列表,並反序列化爲 對象列表,並使用linq應用過濾器。我在不同的服務器上安裝了redis,DB也是如此,我也不想在每臺Web服務器上都有該緩存的副本。

那麼,爲達到最佳性能,最好的方法是什麼?或者有沒有 不同的方式來做到更快?

回答

1

取而代之的是你列出的兩種方法(在客戶端使用SQL或反序列化和過濾)我想建議一個稍微不同的方法,它本質上是一個Redis索引。

這個想法很簡單:假設您的對象的鍵名是obj1,obj2 ... objn,並且屬性1的值是val1,val2 ... valm,對於屬性1的每個值x,創建一個帶有鍵的Redis集名稱如attribute1:valx:index。該集合的成員將是具有屬性1 = valx的對象的關鍵名稱。要做到這一點,請確保:

  • 當您使用valx的ATTRIBUTE1值objy,添加objyattribute1:valx:index關鍵。
  • 將objy的屬性1從valx更新爲valz時,請從attribute1:valx:index中刪除objy,並將其添加到attribute1:valz:index
  • 當您使用attribute1 = valx刪除objy時,請從attribute1:valx:index刪除objy
  • 可選地,上面的內容應該是原子性的(即使用Lua或WATCH/MULTI/EXEC塊),如果這對您的應用程序很重要。

這些點是維護索引所需要的。使用索引時,通過獲取attribute1:valx:index集合的成員(例如SMEMBERS)來查找通過attribute1 = valx過濾的對象,然後通過其鍵名稱(例如objy)獲取實際對象。或者,使用SORT .. GET(例如SORT attribute1:valx:index GET obj*)是另一種只使用一個命令的方法。

對屬性2重複相同的操作。還有一些要點:

  • 研究使用Redis的哈希來存儲您的對象(例如HSET objy attribute1 valx)以節省序列化開銷並更輕鬆地處理Redis中的值。
  • 上面描述的簡單索引可以更進一步考慮 - 考慮使用集合操作,例如SUNION,SDIFF & SINTER以獲得更復雜的過濾選項。