2016-11-28 4 views
0

저는 Redis을 처음 사용했으며 Redis에 지원되는 다양한 데이터 구조가 있으며 요구 사항에 따라 그 중 하나를 선택할 수 있음을 알았습니다. 내 요구 사항은 문자열을 하나씩리스트 (key-list)에 삽입하고 한 번에 모두 검색 (제거)하려고합니다. 또한 나는 이것을 아주 자주하고 싶기 때문에 최적의 방법을 찾으려고 노력합니다. 어떤 데이터 구조/방법이 더 좋을까요? 사전에 감사합니다.Redis - 하나씩 문자열을 삽입하고 한 번에 모두 제거하는 데이터 구조

P.S : 검색 할 때 키를 제거하지 않고 목록을 검색하고 비워두면됩니다.

답변

1

List과 같은 소리가 나옵니다. LPUSH 또는 RPUSH으로 목록에 추가 한 다음 키를 LRANGEDEL과 함께 모두 검색하십시오.

P. 목록을 저장하는 것과 같은 Redis의 키는 비워 둘 수 없습니다. 목록의 멤버를 모두 제거하면 키 자체가 더 이상 존재하지 않으므로 비워 두는 대신 키를 삭제하면됩니다.

OP의 의견에 대한 답변으로 업데이트되었습니다. 실제로는 무료 점심은 없으며 방법에 관계없이 O (N) 개의 읽기 및 삭제가 필요합니다. 하나의 반복 만 수행하는 것이 바람직한 경우가있다. 네트워크 통신을 줄이기 위해, 그러나 이것은 그들 중 하나가 아닙니다.

어떤 방식 으로든 루아와 함께 두 기능을 모두 사용할 수있는 가장 가까운 기능을 얻을 수 있습니다.

$ cat popall.lua 
local r={} 
local e=redis.call('LPOP', KEYS[1]) 
while e do 
    r[#r+1]=e 
    e=redis.call('LPOP', KEYS[1]) 
end 
return r 
$ redis-cli LPUSH list 1 2 3 4 5 6 7 8 9 
(integer) 9 
$ redis-cli --eval popall.lua list 
1) "9" 
2) "8" 
3) "7" 
4) "6" 
5) "5" 
6) "4" 
7) "3" 
8) "2" 
9) "1" 
$ redis-cli EXISTS list 
(integer) 0 
+0

LRANGE와 DEL은 모두 O (N) 연산입니다. 리스트가 비게 될 때까지 POP는 N * O (1) 연산을 취합니다. 둘을 결합하는 방법이 있습니까? (즉) 팝하고 한 번에 모두를 반환, 단일 복용 O (N) – RaR

1

당신은 가능성이를 달성하기 위해 간단한 list를 사용하려면이 반드시 더 나은 다음 LRANGE & DEL이 수행되지 않습니다 유의하십시오. 당신이 세트를 사용하고자하는 한 가지 이유가 있지만, 나중에 그것에 관해서 설명 할 것입니다.

LPUSH을 사용하면 목록에 항목을 추가 할 수 있습니다. 이 작업을 처음 수행 할 수 있도록 목록이 존재하지 않아도됩니다. 이것은 O(1) (일정 시간) 작업이므로 최대한 빨리 수행 할 수 있습니다. 모든 항목을 검색하려면 LRANGE 0 -1을 사용하십시오. 이것은 과 같은 O(N)이 될 것입니다 (유사한 설정 작업). 마지막으로 DEL을 사용하고 다시 O(N)이 될 것이며 집합이나 목록을 사용하든 동일한 성능을 갖게됩니다.

앞에서 언급했듯이 목록에 세트를 사용하는 경우가 하나 있습니다. 그 때 당신은 중복을 방지하기를 원하지만 주문은 신경 쓰지 않습니다. 이 경우 SADD으로 회원을 추가하고 SMEMBERS으로 모든 회원을 검색합니다. 집합을 사용하면 주문고유성에 대한 거래를 제외하고는 목록을 사용하는 것과 똑같은 성능을 갖습니다. 중복을 방지하고 순서를 신경 쓰고 싶다면 정렬 된 집합을 사용하는 것이 좋습니다. 작전은 당신이 점수를 추적 할 필요가 있기 때문에 좀 더 복잡 할 것이지만, 여전히 상당히 간단합니다. 또한 정렬 된 집합을 사용하여 아주 작은 성능 저하가 발생합니다. 이것은 Redis가 매우 매우이므로 걱정할 사항이 아닙니다.

+1

우선, 정말 멋진 설명을 주셔서 감사합니다. 목록 또는 세트를 사용하여 제안한 방식은 최소 두 개의 O (N) 작업을 필요로합니다. 하나의 O (N) 작업에서이를 수행 할 수있는 방법이 없습니까? '(L/R) POP'는 하나를 제거하고 O (1) 연산 인 동일한 것을 반환합니다. 그런 식으로 O (N)을 복용하는 동안 모두를 터뜨리고 모두를 되돌릴 수있는 방법이 없습니까? – RaR

+1

@RaR 걱정할 필요가 없습니다. 그게 큰 포인트 야. 범위를 수행 한 다음 삭제하는 것보다는 반복해서 터뜨림으로써 최상의 성능을 얻을 수있는 것으로 보입니다. Redis 데이터 구조에 대해 일종의 "일괄 팝"이 있다고 나는 생각하지 않습니다. 목록 크기가 정말 크고 (수백만처럼)이 작업이 자주 발생하면 수동 팝업 방법을 수행하는 것이 좋습니다. 그렇지 않으면 범위/삭제 방법을 고수하는 것이 가장 좋습니다. –

1

구분 기호로 사용할 수있는 문자가 있으면 APPEND을 사용할 수도 있습니다. 그것은 O (1)입니다. 그런 다음 GETSET을 사용하여 전체 문자열을 가져 와서 재설정 할 수 있습니다. 단점은 그것이 필요한 경우 자신의 코드에서 다시 목록으로 변환해야한다는 것입니다.