개발자를위한레디스 3장 - 레디스 자료구조
자료구조 정리
Redis 자료구조 정리
Redis는 다양한 자료구조를 지원하며, 각각의 자료구조는 특화된 명령어들과 함께 특정한 사용 시나리오에 적합합니다. 아래는 주요 자료구조별 특징, 명령어, 쓰임새, 예시를 정리한 내용입니다.
String
- 설명: 기본적인 자료구조로, 문자열, 정수, 부동소수점 값을 저장 가능.
- 명령어
SET key value
GET key
INCR key
,DECR key
APPEND key value
STRLEN key
- 특징
- 최대 512MB까지 저장 가능
- 숫자 연산도 지원
- 쓰임새
- 캐시 저장, 단일 값 저장, 카운터
- 예시
1 2
SET username "alice" INCR page_views
List
- 설명: 삽입 순서를 유지하는 문자열의 리스트 (Linked List)
- 명령어
LPUSH key value [value ...]
RPUSH key value [value ...]
LPOP key
,RPOP key
LRANGE key start stop
LLEN key
- 특징
- 큐, 스택, 로그 저장에 유용
- 블로킹 연산 (
BLPOP
,BRPOP
) 지원
- 쓰임새
- 메시지 큐, 실시간 로그 수집
- 예시
1 2
LPUSH logs "ERROR: Disk full" LRANGE logs 0 -1
Set
- 설명: 중복을 허용하지 않는 유일한 값들의 집합
- 명령어
SADD key member [member ...]
SREM key member
SISMEMBER key member
SMEMBERS key
SUNION
,SINTER
,SDIFF
- 특징
- 빠른 존재 유무 확인
- 집합 연산 가능
- 쓰임새
- 태그 관리, 친구 목록
- 예시
1 2
SADD tags "redis" "database" "nosql" SISMEMBER tags "redis"
Sorted Set (ZSet)
- 설명: 각 원소에 score(정렬 기준 숫자)를 부여하여 정렬된 집합
- 명령어
ZADD key score member
ZRANGE key start stop [WITHSCORES]
ZREM key member
ZSCORE key member
ZRANK key member
ZRANK key (b (f BYLEX
: b를 포함해서 f까지 사전순으로 값 조회( “[” 를 쓴다면 미포함. 한글도 가능)
- 특징
- 순위 시스템 구현에 적합
- score 기반 정렬
- 쓰임새
- 리더보드, 우선순위 큐
- 예시
1 2
ZADD leaderboard 100 "user1" 150 "user2" ZRANGE leaderboard 0 -1 WITHSCORES
list와 sorted set에서 index를 접근할 수 있는데 sorted set에서 index 더 효율적이라면서요?
Redis에서 List보다 Sorted Set이 인덱스 접근(index access) 시 더 빠른 이유는 내부 자료구조와 시간 복잡도의 차이 때문입니다.
list의 인덱스 접근 시간복잡도는 O(n), sorted set 시간복잡도는 O(log n)입니다.
list vs sorted set
위에서 언급했듯이 Redis에서 List보다 Sorted Set이 인덱스 접근(index access) 시 더 빠른 이유는 내부 자료구조와 시간 복잡도의 차이 때문입니다.
왜 List의 인덱스 접근이 느린가?
Redis의 List는 내부적으로 양방향 연결 리스트로 구현되어 있어서, LINDEX 명령어로 특정 인덱스를 조회할 때, 시작 지점부터 하나씩 순차적으로 이동해야 합니다.
-> 시간복잡도 O(n)
1
LINDEX mylist 10000 # 앞에서부터 10000번 이동해야 함
왜 Sorted Set은 인덱스 접근이 빠른가?
Redis의 Sorted Set은 내부적으로 스킵 리스트(Skip List)로 구성되어 있습니다. 이 구조는 정렬된 상태를 유지하면서도 평균적으로 O(log n)의 시간복잡도로 탐색이 가능함.
1
ZRANGE myzset 10000 10000 # 인덱스로 빠르게 접근 가능
자료구조 | 내부 구현 | 인덱스 접근 시간복잡도 | 특징 |
---|---|---|---|
List | Doubly Linked List (양방향 연결 리스트) | O(n) | 인덱스 접근 시 앞에서부터 순차 탐색 필요 |
Sorted Set | Skip List (스킵 리스트) + Hash Table | O(log n) | 키를 기준으로 정렬되어 있으며 빠른 탐색이 가능 |
그럼 언제 어떤 자료구조를 사용해야하나요?
List
: 삽입/삭제가 많고, 인덱스 접근이 드물 때 (LPUSH, RPUSH, LPOP, RPOP 중심)Sorted Set
: 순위 기반 조회나 인덱스 기반 접근이 필요한 경우 (ZRANGE, ZREVRANGE, ZRANK 등)
Hash
- 설명: key-value 쌍을 저장하는 Map 구조
- 명령어
HSET key field value
HGET key field
HDEL key field
HGETALL key
HLEN key
- 특징
- 객체 저장에 적합
- 공간 효율적
- 쓰임새
- 사용자 정보 저장, 구성 데이터 저장
- 예시
1 2
HSET user:1 name "Alice" age "30" HGETALL user:1
HyperLogLog
- 설명: 개수 셈(counting)의 근사치를 계산 (대량의 유니크 값 추정)
- 명령어
PFADD key element
PFCOUNT key
PFMERGE destkey sourcekey
- 특징
- 메모리 사용량 고정 (약 12KB)
- 쓰임새
- UV 카운팅, 중복 제거
- 예시
1 2
PFADD visitors "user1" "user2" "user3" PFCOUNT visitors
Bitmap
- 설명: 비트 단위 연산을 위한 자료구조
- 명령어
SETBIT key offset value
GETBIT key offset
BITCOUNT key
BITOP operation destkey key [key ...]
- 특징
- 사용자 활동 기록 등 플래그 기반 처리에 적합
- 쓰임새
- 출석 체크, 플래그 관리
- 예시
1 2
SETBIT online_users 123 1 GETBIT online_users 123
Stream
- 설명: 로그/이벤트 처리용 Append-only 자료구조 (Kafka 유사)
- 명령어
XADD key * field value
XREAD COUNT count STREAMS key id
XGROUP
,XACK
,XREADGROUP
- 특징
- Consumer Group 지원
- 쓰임새
- 실시간 로그, 이벤트 큐
- 예시
1 2
XADD mystream * sensor-id 123 temp 25.5 XREAD STREAMS mystream 0
Geospatial
- 설명: 위치 정보를 저장하고 조회
- 명령어
GEOADD key longitude latitude member
GEORADIUS key longitude latitude radius m|km|ft|mi
GEODIST key member1 member2
- 특징
- 반경 내 사용자 검색 등에 유용
- 쓰임새
- 배달 위치 추적, 매장 근접 검색
- 예시
1 2
GEOADD stores 13.361389 38.115556 "Palermo" GEORADIUS stores 15 37 200 km
Redis 키(Key) 관련 명령어 정리
Redis에서 키는 데이터를 식별하는 기본 단위이며, 다양한 명령어를 통해 키의 존재 확인, 삭제, 만료 설정, 패턴 탐색 등을 수행할 수 있습니다.
Redis는 단일 스레드 기반이며, 대부분의 명령어는 동기적으로 처리됩니다. 이로 인해 KEYS
, FLUSHALL
처럼 많은 데이터를 한 번에 처리하는 명령어는 전체 Redis 성능을 저하시킬 수 있으며, 운영 환경에서는 사용을 지양해야 합니다.
SCAN처럼 점진적으로 처리하는 Non-blocking 명령어를 사용하는 것이 안전합니다.
기본 키 조작
명령어 | 설명 | 예시 | |
---|---|---|---|
EXISTS key | 키가 존재하는지 확인 (존재하면 1, 없으면 0 반환) | EXISTS mykey | |
DEL key [key ...] | 하나 이상의 키를 삭제 | DEL key1 key2 | |
UNLINK key [key ...] | 키 비동기 삭제. 큰 키에 적합 (Redis 4.0+) | UNLINK mykey | |
TYPE key | 해당 키의 자료형 반환 (string , list , set , zset , hash 등) | TYPE mykey | |
RENAME key newkey | 키 이름을 변경 (기존 키가 있어야 함) | RENAME oldkey newkey | |
RENAMENX key newkey | 새 키가 존재하지 않을 경우에만 이름 변경 | RENAMENX oldkey newkey | |
TTL key | 키의 남은 TTL(Time To Live)을 초 단위로 반환 (-1은 만료 없음, -2는 존재하지 않음) | TTL session:123 | |
EXPIRE key seconds | TTL 설정 | EXPIRE token:123 3600 | |
EXPIREAT key timestamp | 유닉스 타임스탬프 기반 만료 시간 설정 | EXPIREAT mykey 1735689600 | |
EXPIRETIME key | UNIX timestamp로 TTL 만료 시각 조회 (Redis 7.0+) | EXPIRETIME mykey | |
PERSIST key | TTL 제거 (영구 키로 변경) | PERSIST temp:data |
키 탐색 및 정렬
명령어 | 설명 | 예시 |
---|---|---|
KEYS pattern | 패턴에 맞는 모든 키 조회 (운영 환경에서 주의: 성능 이슈) | KEYS user:* |
SCAN cursor [MATCH pattern] [COUNT n] | 키를 순차적으로 안전하게 조회. 대량 키 탐색 시 권장. 주의: MATCH는 필터가 아니라 post-filter처럼 동작 | SCAN 0 MATCH session:* COUNT 100 |
SORT key [BY pattern] [GET pattern] | 리스트, 셋, 정렬셋의 값을 정렬하여 반환 | SORT user_ids BY score:* |
KEYS는 O(n) 명령으로 운영 환경에서 사용 주의해야합니다. SCAN이 더 안전합니다.
SCAN과 비슷하게 자료구조별로, SSCAN(set), HSCAN(hash), ZSCAN(sorted set)이 있습니다.
랜덤 키 및 이동
명령어 | 설명 | 예시 |
---|---|---|
RANDOMKEY | 무작위 키 하나 반환 | RANDOMKEY |
MOVE key db | 키를 현재 DB에서 다른 DB로 이동 | MOVE mykey 1 |
직렬화 및 복사
명령어 | 설명 | 예시 |
---|---|---|
DUMP key | 직렬화된 값을 가져옴 (백업 용도) | DUMP mykey |
RESTORE key ttl serialized-value | DUMP 된 값을 복원 | RESTORE mykey 0 "serialized" |
COPY source destination [DB] [REPLACE] | Redis 6.2부터 도입. 키를 복사 | COPY mykey backup:mykey REPLACE |
기타 유틸리티
명령어 | 설명 | 예시 |
---|---|---|
OBJECT subcommand key | 내부 메모리 정보 확인 (REFCOUNT , ENCODING , IDLETIME 등) | OBJECT ENCODING mykey |
MEMORY USAGE key | 키가 사용하는 메모리의 바이트 수 반환 | MEMORY USAGE mykey |
DB 관련 명령어
명령어 | 설명 |
---|---|
SELECT db | 데이터베이스 선택 (0 ~ 15) |
FLUSHDB | 현재 선택된 DB의 모든 키 삭제 |
FLUSHALL | 전체 Redis 인스턴스의 모든 키 삭제 (모든 DB 초기화) |
[출처]