Redis는 오픈소스 in-memory 데이터 스토어다. 빠른 속도의 데이터베이스, 캐싱에 주로 사용되고, 간단한 Redis Pub/Sub을 이용해 메시지 브로커로도 사용할 수 있다.
오늘은 Redis에서 제공하는 몇가지 자료구조를 간단히 테스트해본다.
실습환경 구성
실습을 위해 docker와 docker-compose를 활용해보자.
6379번 포트로 redis를 띄운다.
# redis-server.yml
version: "3.7"
services:
redis:
image: redis:alpine
command: redis-server --port 6379
container_name: redis
hostname: redis
labels:
- "name=redis"
- "mode=standalone"
ports:
- "6379:6379"
먼저 컨테이너를 띄운다.
docker-compose up -d
shell에서 redis-cli를 실행해보자.
docker-compose exec redis sh
redis-cli
redis-cli를 이용하면 쉽게 이런저런 데이터를 추가하고 삭제해보며 테스트할 수 있다.
Hash
Redis에서 Hash는 쉽게 key:value 형태로 데이터를 저장할 수 있게 해준다.
먼저 데이터를 추가하고 가져오는 것을 테스트해본다.
HSET user:123 username leon age 35
// (integer) 2
HGET user:123 age
// "31"
HGETALL user:123
/*
1) "name"
2) "leon"
3) "age"
4) "31"
*/
HSET user:123 address seoul
// (integer) 1
HGETALL user:123
/*
1) "name"
2) "leon"
3) "age"
4) "31"
5) "address"
6) "seoul"
*/
List
List라는 자료구조도 있다.
LPUSH user:list 'leon kong'
// (integer) 1
LRANGE user:list 0 -1
// 1) "leon kong"
Sorted Set
개인적으로 가장 재미있는 자료구조라고 생각한다.
가중치와 함께 데이터를 저장하며, 꽤나 효율적인 시간복잡도를 가지고 있다.
대부분의 연산은 O(log(n))으로 처리 가능하다.
현업에서는 사용자의 랭킹을 매기거나 할 때, 점수와 데이터를 그때그때 삽입하고, 필요할 때 바로 꺼내쓴다.
핀볼 게임을 예로 들어보자.
플레이어가 게임을 하는 동안 점수를 올릴 때마다 sorted set의 해당 플레이어에 대한 점수를 지속적으로 갱신한다.
이후 게임이 종료될 때 그 플레이어의 등수를 가져오면 되는데, 이는 O(log(n))으로 가능하다.
이런 이유에서 여러 형태의 랭킹계산에 흔히 사용되곤 한다.
ZADD ranking:level 100 user:1
(integer) 1
ZADD ranking:level 99 user:2
(integer) 1
ZADD ranking:level 87 user:3
(integer) 1
ZADD ranking:level 115 user:4
(integer) 1
ZADD ranking:level 108 user:2
(integer) 0
user:2의 level은 마지막에 보다시피 업데이트 되었다.
레벨이 높은 유저 순으로 가져오려면 어떻게 하면 될까?
ZRANGE ranking:level 0 -1 REV WITHSCORES
1) "user:4"
2) "115"
3) "user:2"
4) "108"
5) "user:1"
6) "100"
7) "user:3"
8) "87"
user:2는 1차례 레벨이 갱신되었다. user:2의 랭킹을 알아보려면 어떻게 하면 될까?
ZREVRANK ranking:level user:2
(integer) 1
0번째부터 있기 때문에 1번째라는 것은 2등을 의미한다.
참고로 ZRANK는 낮은 숫자부터(ascending order) 랭킹을 매긴다.
높은 숫자가 높은 랭킹으로 연결되야 하는 경우 ZREVRANK를 이용한다.
EXPIRE
참고로 삽입한 자료는 expire를 걸 수 있다.
EXPIRE user:123 10
위 명령어는 10초 뒤 key가 삭제되도록 한다.
DEL
더 직접적으로 데이터를 삭제하는 방법도 있다.
DEL user:list
마치며
이제 실습을 종료하자. 도커 컴포즈를 내리고 이미지를 제거한다.
docker-compose down --rmi local