본문 바로가기
개발

[Redis] 레디스 기본타입(Sorted Sets)

by 박연호의 개발 블로그 2024. 3. 30.
redis 공식문서를 보고 정리한 글입니다.

 

redis sorted set은 score로 정렬된 중복되지 않은 문자열의 집합입니다. 같은 score를 가지는 문자열이 존재하는 경우 사전순으로 정렬 됩니다. sorted sets은 온라인 게임의 랭킹 시스템이나, api rate limiters에 사용할 수 있습니다.

 


ZMPOP

O(K) + O(M*log(N)), K는 keys의 개수, N은 set의 element 개수, M은 pop하려는 데이터 개수

ZMPOP numkeys key [key ...] <MIN | MAX> [COUNT count]

keys로 입력받은 sorted sets들에서 MIN/MAX 데이터를 count개수만큼(default 1)삭제 후 반환함. 입력받은 key(sorted set) 중에서 데이터가 없으면 건너띔.

 

set1 : [
    { one 1 }
    { two 2 }
    { three 3}
]

set2 : [
    { one 1 }
    { two 2 }
    { three 3}
]

위의 구조에서 zmpop 2 set1 set2 max count 2 명령어를 실행하면, 2개의 sorted sets(set1, set2) 데이터가 있으면 순서대로 가장 큰 값 2개를 가져오게 됩니다. 먼저 set1에서 three, two를 반환하고, set에서 해당 데이터를 삭제합니다.

 

다시 zmpop 2 set1 set2 max count 2를 실행하면, set1에 데이터가 아직 있기 때문에 one를 반환합니다. 다시 zmpop 2 set1 set2 max count 2를 실행하면 set2에서 데이터를 찾아 반환하게 됩니다.

> zadd set1 1 one 2 two 3 trhee
(integer) 3
> zadd set2 1 one 2 two 3 trhee
(integer) 3
> zmpop 2 set1 set2 max count 2
1) "set1"
2) 1) 1) "trhee"
      2) "3"
   2) 1) "two"
      2) "2"
> zmpop 2 set1 set2 max count 2
1) "set1"
2) 1) 1) "one"
      2) "1"
> zmpop 2 set1 set2 max count 2
1) "set2"
2) 1) 1) "trhee"
      2) "3"
   2) 1) "two"
      2) "2"
> zmpop 2 set1 set2 max count 2
1) "set2"
2) 1) 1) "one"
      2) "1"

 

 

BZMPOP

O(K) + O(M*log(N)), K는 keys의 개수, N은 set의 element 개수, M은 pop하려는 데이터 개수

BZMPOP timeout numkeys key [key ...] <MIN | MAX> [COUNT count]

sorted sets에 데이터가 있거나, MULTI/EXEC block안에서는 ZMPOP와 동일하게 동작합니다. 하지만 sorted sets에 데이터가 없는 경우 다른 클라이언트가 데이터를 채워줄때까지 또는 지정된 timeout 시간동안 block 됩니다.timeout 값이 0이면 무한입니다.

 

 

ZPOPMAX

O(log(N) * M), N은 sorted set의 데이터 개수, M은 pop하려는 데이터 개수

ZPOPMAX key [count]

sorted sets에서 높은 score에 해당하는 데이터를 count만큼 삭제 후 반환합니다.  count의 기본값은 1이며, 가장 높은 데이터를 기준으로 count만큼 반환합니다.

 

 

BZPOPMAX

O(log(N)), sorted set에 존재하는 데이터의 개수

BZPOPMAX key [key ...] timeout

ZPOPMAX의 block 버전입니다. sorted sets에 데이터가 없는 경우 다른 클라이언트가 데이터를 채워줄때까지 또는 지정된 timeout 시간 block 됩니다. timeout 값이 0이면 무한입니다.

 

 

ZPOPMIN

O(log(N) * M), N은 sorted set의 데이터 개수, M은 pop하려는 데이터 개수

ZPOPMIN key [count]

sorted sets에서 낮은 score에 해당하는 데이터를 count만큼 삭제 후 반환합니다.  count의 기본값은 1이며, 가장 낮은 데이터를 기준으로 count만큼 반환합니다.

 

 

BZPOPMIN

O(log(N)), sorted set에 존재하는 데이터의 개수

BZPOPMIN key [key ...] timeout

ZPOPMIN의 block 버전입니다. sorted sets에 데이터가 없는 경우 다른 클라이언트가 데이터를 채워줄때까지 또는 지정된 timeout 시간 block 됩니다. timeout 값이 0이면 무한입니다.

 

 

ZADD

각 데이터 마다 O(log(N))이며, N은 sorted set의 데이터 개수

ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member
  ...]

 

sorted set에 socre를 명시하여 데이터를 삽입합니다. member가 이미 존재한다면, count만 업데이트 됩니다.

score값의 정수범위는(-9007199254740992 ~ 9007199254740992), 실수범위는 double precision floating point number 입니다.

 

sorted set에 데이터를 추가할때 옵션을 설정할 수 있습니다.

- XX : member가 이미 존재하는 경우 score만 수정

- NX : member가 없는 경우에만 삽입

- LT : 입력한 score가 현재 member의 score보다 작은 경우 socre 수정

- GT : 입력한 score가 현재 member의 score보다 큰 경우 socre 수정 

- CH : sorted set에 새로운 데이터가 삽입/socre가 수정된 경우 삽입/수정된 member의 수를 반환

- INCR : member의 score값을 주어진 값만큼 증가

 

 

ZCARD

O(1)

ZCARD key

sorted set에 저장된 원소 개수를 반환

 

 

ZCOUNT

O(long(N)), N은 sorted set에 저장된 원소의 개수

ZCOUNT key min max

sorted set에서 score이 min이상~max이하 데이터 개수를 반환

 

 

ZDIFF

O(L+(N-K)log(N)), 최악의 경우 L은 모든 sorted set의 총 데이터 개수, N은 첫 번째 sorted set의 크기, K는 결과 sorted set의 크기

ZDIFF numkeys key [key ...] [WITHSCORES]

여러 sorted set의 중복되지 않은 데이터를 반환합니다. 데이터의 스코어까지 같이 표현하고 싶으면 withscores 옵션 전달.

 

set1와 set2에는 one, two가 모두 존재하지만 three는 set2에만 있음.

> zadd set1 1 one
(integer) 1
> zadd set1 2 two
(integer) 1
> zadd set1 3 three
(integer) 1
> zadd set2 1 one
(integer) 1
> zadd set2 2 two
(integer) 1
> zdiff 2 set1 set2
1) "three"
> zdiff 2 set1 set2 withscores
1) "three"
2) "3"

 

 

ZDIFFSTORE

O(L+(N-K)log(N)), 최악의 경우 L은 모든 sorted set의 총 데이터 개수, N은 첫 번째 sorted set의 크기, K는 결과 sorted set의 크기

ZDIFFSTORE destination numkeys key [key ...]

여러 sorted set의 중복되지 않은 데이터를 destination에 저장합니다. destination에 데이터가 이미 존재하면 덮어 씌어집니다.

 

> zadd set1 1 one
(integer) 1
> zadd set1 2 two
(integer) 1
> zadd set1 3 three
(integer) 1
> zadd set2 1 one
(integer) 1
> zadd set2 2 two
(integer) 1
> zdiff 2 set1 set2
1) "three"
> zdiff 2 set1 set2 withscores
1) "three"
2) "3"
> zdiffstore set3 2 set1 set3
(integer) 3
> zrange set3 0 -1
1) "one"
2) "two"
3) "three"

 

 

ZINCRBY

O(log(N)), N은 sorted set의 데이터 개수

ZINCRBY key increment member

member에 해당하는 socre 값을 1 증가합니다. 만약 member가 없으면 member를 만들고 score를 increment로 설정합니다. 만약 key에 해당하는 sorted set이 없으면 sorted set을 만들고 increment를 score로 가지는 member를 만듭니다.

 

 

ZINTER

O(N*K) + O(M*log(M)), 최악의 경우 N은 가장 작은 입력 sorted set, K는 입력한 sorted set의 개수, M은 결과 sorted set의 데이터 개수

 

ZINTER numkeys key [key ...] [WEIGHTS weight [weight ...]]
  [AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]

여러 sorted set가 중복으로 가진 데이터를 반환합니다.

 

 

ZINTERCARD

O(N*K), N은 가장 작은 입력 sorted set, K는 입력 sorted set의 개수

ZINTERCARD numkeys key [key ...] [LIMIT limit]

ZINTER 명령어와 비슷하지면 set을 반환하는 대신 결과 카디널리티(개수)만 반환합니다.

 

 

ZINTERSTORE

O(N*K) + O(M*log(M)), 최악의 경우 N은 가장 작은 입력 sorted set, K는 입력한 sorted set의 개수, M은 결과 sorted set의 데이터 개수

ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight
  [weight ...]] [AGGREGATE <SUM | MIN | MAX>]

여러 sorted set에 중복으로 가진 데이터를 destination에 저장합니다.

 

 

ZLEXCOUNT

O(log(N)), N은 sorted set에 존재하는 데이터 개수

ZLEXCOUNT key min max

sroted set에 모든 데이터가 같은 score를 가지고 있을 때, 사전순으로 데이터를 정렬했을 때 min~max 사이의 데이터를 반환합니다.

모두 조회하려면 min, max를 -,+로 [는 값을 포함, (는 값을 제외합니다.

 

zlexcount set1 [b (f는 b포함 ~ f제외 범위의 데이터를 가져오며 b,c,d,e 총 4건이 반환됩니다.

> zadd set1 0 a 0 b 0 c 0 d 0 e 0 f 0 g
(integer) 7
> zlexcount set1 - +
(integer) 7
> zlexcount set1 [b (f
(integer) 4

 

 

ZMSCORE

O(N), N은 입력한 member의 개수

ZMSCORE key member [member ...]

member 데이터에 해당하는 score를 반환하며, 반약 member가 없으면 nil을 반환합니다.

 

 

ZPOPMAX

O(log(N)*M), N은 sorted set에 저장된 데이터 개수, M은 pop 하려는 데이터 개수

ZPOPMAX key [count]

score가 높은 데이터 count개를 삭제 후 반환합니다(높은 순대로). 만약 count가 member 개수보다 많은 경우 모두 삭제 후 반환합니다. 

 

 

ZPOPMIN

O(log(N)*M), N은 sorted set에 저장된 데이터 개수, M은 pop 하려는 데이터 개수

ZPOPMIN key [count]

score가 낮은 데이터 count개를 삭제 후 반환합니다(낮은 순대로). 만약 count가 member 개수보다 많은 경우 모두 삭제 후 반환합니다. 

 

 

ZRANDMEMBER

O(N), N은 반환하려고 하는 데이터 개수

ZRANDMEMBER key [count [WITHSCORES]]

sorted set에서 랜덤하게 데이터를 반환합니다. count가 양수인 경우 모두 중복되지 않은 데이터를 반환하며, 음수인 경우 중복된 데이터를 반환할 수 있습니다.

 

 

ZRANGE

O(log(N)+M), N은 key에 존재하는 데이터 개수, M은 반환하려고 하는 데이터 개수

ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count]
  [WITHSCORES]

기존의 ZREVRANGE, ZRANGEBYSCORE, ZREVRANGEBYSCORE, ZRANGEBYLEXZREVRANGEBYLEX 모두 deprecated가 되고 ZRANGE 하나만을 사용합니다.

 

기본적인 사용법은 데이터의 score가 적은 것부터 start ~ stop index 사이의 데이터를 반환합니다(start, stop 위치의 데이터도 포함).

전체를 조회할때는 0 ~ -1로 조회할 수 있으며, score가 같으면 member로 정렬되어 반환됩니다.

 

0, 1, 2, 3번째 인덱스의 데이터 값을 가져옵니다(score가 낮은 것 부터)

> zadd set 0 zero 1 one 2 two 3 three 4 four 5 five
> zrange set 0 3
1) "zero"
2) "one"
3) "two"
4) "three"

 

 

score를 역순으로 조회하려면 REV 옵션을 사용할 수 있습니다.

>  zrange set 0 3 rev
1) "five"
2) "four"
3) "three"
4) "two"

 

스코어를 조회 조건으로 사용하려면 BYSCORE를 사용할 수 있습니다. 1이상 ~ 3이하의 스코어 값을 조회합니다.

(를 붙이면 해당 스코어는 제외(초과/미만)할 수 있습니다.

> zrange set 1 3 byscore
1) "one"
2) "two"
3) "three"

> zrange set (1 3 byscore
1) "two"
2) "three"

 

 

값을 조회 조건으로 사용하려면 BYLEX를 사용할 수 있습니다. 단 이 옵션은 값을 기준으로 조회하기 때문에 score가 모두 같아야 합니다.

또한 반드시 값에 포함의 의미하는 '[', 또는 미포함'('을 사용해야 하며, 모두 조회하려면 값에 -, +를 사용하면 됩니다.

> zadd set1 0 a 0 b 0 c 0 d 0 e

// 모두 조회
 zrange set1 - + bylex
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"

// b는 포함하지만, e는 제외
> zrange set1 [b (e bylex
1) "b"
2) "c"
3) "d"

 

반환 개수를 제한할 때는 LIMIT을 사용할 수 있습니다. 단, 이 옵션은 BYSCORE, BYLEX를 사용했을 때만 사용할 수 있습니다.

set에서 0~4 인덱스의 값을 조회(one, two, three, four)한 데이터에서, 0 index <= 데이터 < 2 index 사이의 값을 반환합니다.

zrange set 0 4 limit 0 2 byscore
1) "zero"
2) "one"

 

 

ZRANGESTORE

O(long(N)+M), N은 key에 존재하는 데이터 개수, M은 destination key에 저장한 데이터의 개수

ZRANGESTORE dst src min max [BYSCORE | BYLEX] [REV] [LIMIT offset
  count]

ZRANGE와 기능은 같지만, 응답 데이터를 출력하는 것이 아닌 dst에 저장합니다.

 

 

ZRANK

O(log(N))

ZRANK key member [WITHSCORE]

member의 index를 반환합니다. index를 정하는 기준은 멤버를 score를 기준으로 오름차순 정렬했을 때의 member의 index 입니다.

ZREVRANK를 사용하면 socre를 내림차순으로 정렬했을 때의 member의 index를 구할 수 있습니다. 

 

ZREM

O(M*log(N)), N은 key의 데이터 개수, M은 삭제하려는 데이터 개수

ZREM key member [member ...]

key에서 한개 또는 여러개의 member를 제거

 

 

ZREMRANGEBYLEX

O(log(N)+M), N은 key의 데이터 개수, M은 삭제하려는 데이터 개수

ZREMRANGEBYLEX key min max

sorted set에 저장된 데이터의 score가 모두 같은 경우, min ~ max범위의 데이터를 삭제 합니다. 데이터를 모두 삭제하는 경우 min, max는 -,+가 되며, 특정 문자열을 사용할 경우 포함"[", "(" 제외를 사용해야 합니다.

> zadd set 0 a 0 b 0 c 0 d 0 e
> zremrangebylex set [b (d
2
> zrange set 0 -1
1) "a"
2) "d"
3) "e"

 

 

ZREMRANGEBYRANK

O(log(N)+M), N은 key의 데이터 개수, M은 삭제하려는 데이터 개수

ZREMRANGEBYRANK key start stop

score가 오름차순 정렬 기준으로, start index(이상) ~ stop index(이하) 사이의 데이터를 삭제합니다.

 

 

ZREMRANGEBYSCORE

O(log(N)+M)), N은 key의 데이터 개수, M은 삭제하려는 데이터 개수

ZREMRANGEBYSCORE key min max

score가 min ~ max 사이의 데이터를 삭제합니다. max, max값은 모두 삭제하려면 -inf, +inf(+생략가능)이며 min, max를 그냥 사용하면 지정한 값을 포함해서 삭제하며 min, max를 제외하려면 앞에 '('를 붙여야 합니다.

 

 

ZREVRANK

O(log(N))

ZREVRANK key member [WITHSCORE]

score가 내림차순 정렬 기준으로 member의 index값을 반환합니다.

 

 

ZSCAN

O(log(N)+M)), N은 key의 데이터 개수, M은 반환되는 개수

ZSCAN key cursor [MATCH pattern] [COUNT count]

 

 

ZSCORE

O(1)

ZSCORE key member

sorted set에서 member의 score를 반환합니다. key나 member가 없으면 nil을 반환합니다.

 

 

ZUNION

O(N) + O(M*log(M)), N은 입력받은 sorted set의 크기의 합, M은 결과 sorted set의 데이터 개수

ZUNION numkeys key [key ...] [WEIGHTS weight [weight ...]]
  [AGGREGATE <SUM | MIN | MAX>] [WITHSCORES]

set1 : (1,A), (2, B), (3,C)

set2 :           (4, B), (5,C), (6,D)

 

위의 구조에서 zunion 2 set1 set2를 하면 (1,A), (6,B), (6,C), (8,C)가 나온다. 이는 각 멤버의 스코어가 더해져서 새로운 sorted set이 구성된다, 따로 aggregate 옵션을 주지 않으면 기본적으로 score는 더해진다.

 

union 하기 전에 각 sorted set의 score에 가중치를 곱해줄 수 있다. zunion 2 set1 set2 weight 2 3을 하게 되면 set1의 socre에 *2, set2의 score에 *3이 곱해져 union 된다.

set1 : (1*2,A), (2*2, B), (3*2,C)

set2 :              (4*3, B), (5*3,C), (6*3,D)

결과 : (2, A), (16, B), (18, D), 21(C)

 

하지만 각각의 score를 더하지 않고, 더 작거나/큰 score를 사용하고 싶을 수도 있다. 이 경우 aggregate를 사용할 수 있다. 옵션 값은 sum | min | max이며 기본적으로 sum을 사용한다. 

 

zunion 2 set1 set2 aggregate min

set1 : (1,A), (2, B), (3,C)

set2 :           (4, B), (5,C), (6,D)

결과 : (1,A), (2, B), (3,C), 6,D)

 

 

ZUNIONSTORE

O(N) + O(M*log(M)), N은 입력받은 sorted set의 크기의 합, M은 결과 sorted set의 데이터 개수

ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight
  [weight ...]] [AGGREGATE <SUM | MIN | MAX>]

ZUNION와 동작은 같지만, 결과값을 출력하는 것이 아닌 destination에 저장합니다. 만약 destination이 이미 존재하는 경우 덮어 씌우게 됩니다.