2016-12-01 52 views
0

我已經創建了一個Redis的鍵/值指數是這樣的:獲取Redis的值,同時掃描

set 7:12:321 '{"some:"JSON"}'

的關鍵是一個冒號分隔符分隔的,關鍵的每一部分表示一個分層索引。 get 7:12:321意味着,我知道確切的層次結構,並只需要一個單一的項目

scan 7:12:*意味着我想在層次結構和id 12的分層結構的第二層中的第一電平下ID 7的每個項目。

問題是:如果我想要JSON值,我必須首先scan(〜50000條目在幾個毫秒內)然後get每個按鍵(800毫秒)掃描返回。

這不是非常有效。這是我在stackoverflow搜索「掃描Redis值」時發現的唯一答案。

1 /是否有另一種掃描Redis的方式來獲取值或鍵/值對,而不僅僅是鍵?我試圖hscan具有如下:

hset myindex 7:12:321 '{"some:"JSON"}' hscan myindex MATCH 7:12:* 但它破壞了性能(50000項幾乎4S)

2 /是否有Redis的另一種數據結構,我可以以同樣的方式使用,但可能「掃描值「(hset?)

3 /我應該去與另一個數據存儲解決方案(例如PostgreSQL的ltree?),以適應我的用例與巨大的性能?

我一定錯過了一些非常明顯的東西,因爲這聽起來像是一個常見的用例。

感謝您的回答。

回答

2

優化當前解決方案

而不是getscan一個接一個返回的每個密鑰,您應該使用mget批量獲取鍵值對,或使用pipeline來減少RTT。當前解決方案

scan命令遍歷數據庫中的所有鍵的

效率問題,即使匹配模式的鍵的數量較少。當按鍵數量增加時,性能會下降。

另一種解決方案

由於分級指數是一個整數,就可以編碼分層索引成多個,並使用該數目作爲有序集合的得分。通過這種方式,您可以不按模式進行搜索,而可以按照分數範圍進行搜索,這對於有序集合來說非常快速。以下面爲例。假設第一個(最右邊的)等級索引小於1000,第二個索引小於100,那麼您可以將索引(例如7:12:321)編碼爲分數(321 + 12 * 1000 + 7 * 100 * 1000 = 712321)。然後將分數和值設置爲有序集:zadd myindex 712321 '{"some:"JSON"}'

當您想要搜索與7:12:*相匹配的密鑰時,只需使用zrangebyscore命令即可獲取712000到712999之間得分的數據:zrangebyscore myindex 712000 712999 withscores

以這種方式,您可以獲得密鑰(用返回的分數解碼)和值一起。它也應該比scan解決方案更快。

UPDATE

該解決方案有一個小問題:有序集合的成員必須是唯一的,所以你不能有2個按鍵具有相同的值(即JSON字符串)。

// insert OK 
zadd myindex 712321 '{"the_same":"JSON"}' 
// failed to insert, members should be unique 
zadd myindex 712322 '{"the_same":"JSON"}' 

爲了解決這個問題,你可以用JSON字符串相結合的關鍵在於使其獨特:

zadd myindex 712321 '7:12:321-{"the_same":"JSON"}' 
zadd myindex 712321 '7:12:322-{"the_same":"JSON"}' 
+0

非常感謝您的回答。得分的解決方案非常聰明。我必須去適應它,因爲層級鍵並不像我在我的問題中提到的那樣真正地被組織爲「純粹的」(我簡化了)。但是這個想法絕對值得嘗試。與此同時,我發現文檔中的'mget'我可以看到改進,但是,當然,不如您的解決方案聰明;)謝謝! – Javier92

+0

@ Javier92我發現原始解決方案存在一些小問題。請參閱我的解決方案更新。 –

+0

不要擔心,第一部分+密鑰的最後部分會生成唯一的標識符。中間的部分僅用於索引目的。所以創建一些獨特的json字段很容易。 – Javier92

2

只要您只需執行前綴搜索,您就可以考慮使用排序集和字典範圍。有關這一點,索引一般更多信息,請參閱http://redis.io/topics/indexes

用一個例子更新時間:

考慮以下 -

$ redis-cli 
127.0.0.1:6379> ZADD anotherindex 0 '7:12:321:{"some:"JSON"}' 
(integer) 1 
127.0.0.1:6379> ZRANGEBYLEX anotherindex [7:12: [7:12:\xff 
1) "7:12:321:{\"some:\"JSON\"}" 

現在去了解這個,所以你1)理解它做什麼2)知道如何避免可能的陷阱:)

+0

謝謝您的回答,但不知道我理解正確。在你提到的文檔中,'ZADD'總是以'0'爲關鍵字。因此,我的關鍵層次成爲價值?我的JSON在哪裏存儲。對不起,如果這對你來說微不足道。你能舉一個例子說明ZADD和ZRANGEBYLEX是什麼?非常感謝。 – Javier92

+0

感謝您的更新示例,儘管我現在才意識到!非常感激。我一定會用它作爲前綴搜索 – Javier92