2013-04-16 1 views
0

가능한 한 효율적으로 redis 키의 목록을 얻으려고합니다. 우리는 redis 서버에서 이것을 모델링 할 수 있지만 문제는 해결할 수있는 적절한 방법입니다. 이 상황을 설명해 드리겠습니다.Redis에서 교차하고 다른 키를 찾는 방법

Redis에 문자열로 저장되는 많은 "고객"집합을 가정하십시오.

customer__100000 
customer__100001 
customer__100002 

각 고객마다 몇 가지 특성이 있습니다. 그것들은 그들이 살고있는 도시가 될 것입니다. 각 도시는 또한 레디 스에 보관되어 있습니다. 나는 고객 키 (프리 필터 세트를 교차.) 나는 그 열쇠가 있으면 내가 그 안에 가지고있는 별개의 도시 찾을 필요가 세트로 종료됩니다 다른 사전 처리를 통해

city__New York 
city__San Francisco 
city__Washington DC 

고객. 여기에있는 나의 최종 목표는 도시의 이름을 얻는 것입니다. 그러나 제가 괜찮 으면 도시 이름을 끌어 올 수있는 열쇠를 얻을 수 있다면.

규모에 대한 아이디어를 얻으려면 여기서 약 70 가지 속성 (도시 중 하나)과 각 속성이 50 - 100,000 인 200-300k 고객을 처리한다고 가정합니다. 가능한 한 효율적으로 유지하고 싶습니다.

답변

2

고객을 문자열로 저장하는 대신 해시로 저장해야합니다. 해시를위한 Redis의 ziplist 인코딩은 매우 공간 효율적입니다. 70 개 이상의 요소를 저장하는 경우 redis.conf의 hash-max-ziplist-entries 제한을 높이는 것이 좋습니다

Redis 해시를 사용하면 SORT으로 재미있는 일을 할 수 있습니다. 과 GETSTORE을 사용하면 고객으로부터 모든 도시를 가져 와서 목록으로 저장할 수 있습니다 (별개). 그런 다음 목록에 lpopsadd을 호출하여 목록을 집합으로 변환 할 수 있습니다. 여기

는 예 레디 스 루아 스크립트입니다

-- a key which holds a set of customer keys 
local set_of_customer_keys = KEYS[1] 
-- a maybe-existing key which will hold the set of cities 
local distinct_set = ARGV[1] 
-- attribute to get (defaults to city) 
local attribute = ARGV[2] or 'city' 
-- remove current set of distinct_cities 
redis.call("DEL", distinct_set) 
-- use SORT to build a list out of customer hash values for `attribute` 
local cities = redis.call("SORT", set_of_customer_keys, "BY", "nosort", "GET", "*->"..attribute) 
-- loop through all cities in the list and add them to the distinct cities set 
for i, city in pairs(cities) do 
    redis.call("SADD", distinct_set, city) 
end 
-- return the distinct cities 
return redis.call("SMEMBERS", distinct_set) 

또한 고객의 속성과 함께 영구적으로 저장되는 customer__100000__cities 설정을 유지하고 도시의 독특한 세트를 얻을 수 sinter *customer_cities_keys을 사용할 수 있지만 그 것 적은 메모리 효율.

+0

흥미로운 아이디어. 50,000 개의 도시를 철수시키고 100,000 개의 항목으로 끝날 수있는 세트에 모든 50,000 개를 효과적으로 추가하게 될 것이지만 50,000 개의 고객 세트를 감안할 때. 데이터의 파이프 라인 다운 및 백업으로 인해이 경로의 성능에 대해 궁금합니다. –

+0

물론 Lua 스크립트 서버 측을 실행하는 것이 좋습니다. –

+0

예, 확실히 Redis EVAL에서 호출 된 Lua 스크립트입니다. 내 추측은 50k 항목으로도 매우 빠를 것입니다. if 문 안에'EXPIRE'와'TTL'을 사용하여'distinct_set' 키를 메모 해 두는 것이 좋습니다. 나는 Redis리스트 대신에 도시를 위해 Lua 테이블을 사용하도록 Lua 스크립트를 업데이트했다. 나는 이제 이해하는 것이 더 간단하다고 생각합니다. – lastcanal

관련 문제