Database/Redis

[실전 레디스] 2-1. 자료형과 기능: 기본 자료형

noahkim_ 2025. 3. 20. 00:51

하야시 쇼고 님의 "실전 레디스" 책을 정리한 포스팅 입니다.


1. 개요

네임스페이스

  • 전역 스페이스에서 모든 키를 관리함
  • 키를 그룹화하기 위해 prefix 또는 DB 번호로 분리 가능

 

예시) prefix

더보기

구조: user:<id>:<field>

SET user:1001:name "Redis"
SET user:1001:email "redis@example.com"
MGET user:1001:name user:1001:email
  • 키 충돌 방지
  • 그룹 관리 용이

 

예시) DB 번호

더보기

0: 세션 관리용

SELECT 0
SET session:1234 "login"

 

1: 캐시 관리용

SELECT 1
SET cache:home_page "cached html"
  • 키 간 공유가 안됨 → 논리 분할에 적합

 

키 어노테이션

  • 각 키간 관계를 주석 처럼 명시하거나 트리거 로직을 구현하는데 활용됨

 

예시) 트리거

더보기

게시글이 삭제되면 관련 댓글 캐시도 삭제

DEL post:1234
DEL comment:post:1234:*

 

Lua Script로 관련 키 자동 삭제 트리거 

local post_id = ARGV[1]
redis.call("DEL", "post:" .. post_id)
local keys = redis.call("KEYS", "comment:post:" .. post_id .. ":*")
for i, key in ipairs(keys) do redis.call("DEL", key) end

return #keys
EVAL "script" 0 1234

 

2. String

항목 내용
특징
- binary safe: 이미지, 실행파일도 저장 가능
- 크기: 최대 512MB까지 가능
주요 용도
- 문자열
- 숫자 (정수, 실수)
- 바이너리 데이터 (이미지 등)
활용 사례 - 카운터 (조회수 등)
- 실시간 지표/메트릭스
- 캐시: 세션, 쿠키, 바이너리 데이터

 

명령어

1개 등록 / 읽기

더보기
set foo bar
get foo

# 맨 뒤에 붙이기
append key value

# 길이 읽기
strlen key
getrange key 0 4

 

여러개 등록 / 읽기

더보기
mset mykey1 myvalue1 mykey2 myvalue2 mykey3 myvalue3
mget mykey1 mykey
  • 한번에 하는것이 효율적 
  • 하나씩 하는 것은 RTT가 발생함 (Round Trip Time)

 

정수 증가 / 감소

더보기
set hit_count 100
incr hit_count 
incrby hit_count 2 # 인수값만큼 증가
decr hit_count
decrby hit_count 2 # 인수값만큼 감소

 

실수 증가 / 감소

더보기
set real_number 1.5
incrbyfloat real_number 1.1
incrbyfloat real_number -1.1

 

활용

지정된 키가 존재하지 않을 때만 등록하기

더보기

NX(Not Exist)

mset user:2 "Suzuki Jiro" user:3 "Takahashi Saburo" user:4 "Tanaka Shiro" user:5 "Ito Goro"
set user:2 "Matanabe Rokuro" NX
set user:6 "Matanabe Rokuro" NX
get user:2 # Suzuki Jiro
get user:6 # Matanabe Rokuro
  • 키가 존재하지 않을 때만 저장

 

TTL 설정

더보기
SETEX user:7 300 "Yamamoto Nanaro" # 해당 키의 TTL 시간 설정 (초)
TTL user:7 # 키의 남은 TTL 시간 확인

 

3. List

  • 문자열 컬렉션
  • 순서 유지

 

명령어

쓰기

더보기

방향 지정

lpush lkey lvalue1 lvalue2
rpush lkey lvalue3 lvalue4

 

특정 원소 앞뒤로
linsert lkey before lvalue1 lvalue0
linsert lkey after lvalue4 lvalue5

 

값 수정 

lset lkey 0 first

 

꺼내기

더보기

pop

lpop lkey
rpop lkey
lmpop 1 lkey LEFT COUNT 2  # 1개의 키에 대해 2개 lpop
lmpop 1 lkey RIGHT COUNT 2 # 1개의 키에 대해 2개 rpop

 

blmpop (Blocking Multi-List POP)

BLMPOP <timeout> <numkeys> <key1> [key2 ...] <LEFT|RIGHT> [COUNT <count>]

blmpop 10 1 lkey LEFT COUNT 2 # 1개의 키에 대해 2개 rpop 명령을 블로킹으로 수행
  • 여러 개의 리스트에서 요소를 블로킹 방식으로 꺼내는 명령어
  • 리스트에 요소가 있으면 → pop 후 종료
  • 리스트에 요소가 없으면 → timeout 시간 동안 블로킹
    • 요소가 추가될 때까지 대기함
    • 블로킹 시간이 초과되면 nil을 반환 

 

ltrim lkey 1 2    # 인덱스 1~2까지 남기기 (나머지 삭제)
ltrim lkey -2 -1  # 인덱스 -2~-1까지 남기기 (나머지 삭제)

 

삭제

더보기
lrem lkey 0 first # lkey에서 first 값 모두 삭제
lrem lkey 2 first # lkey에서 first 값 왼쪽에서 2개 삭제
lrem lkey -2 first # lkey에서 first 값 오른쪽에서 2개 삭제

 

확인

더보기
lrange lkey 0 10
lindex lkey 0 # 왼쪽에서 인덱스 원소 값을 출력
llen lkey
lpos lkey lvalue1 # 값의 인덱스 반환
lpos lkey lvalue1 count 2 # 왼쪽에서 lvalue값 2개 찾아서 각각 인덱스 반환
lpos lkey lvalue1 rank 2 # 두번쨰 값 인덱스 반환
lpos lkey lvalue1 maxlen 4 # 4까지의 길이로 제한하여 탐색

 

활용

인기 콘텐츠 표시 (타임라인 게시)

더보기
lpush recent_posts post1 ~ 15
ltrim recent_posts 0 9
lrange recent_posts 0 9
  • 최근 N개의 게시물 가져오기

 

4. Hash

  • 필드와 값이 여러 쌍으로 매핑된 자료구조
  • 필드와 값의 타입은 모두 문자열
  • 순서 없음

 

명령어

쓰기

더보기
hset myhash field1 value1 field2 value2 field3 value3
hincrby myhash field6 1
hincrbyfloat myhash field7 1.3

 

읽기

더보기
hget myhash field3
hgetall myhash
hkeys myhash
hvals myhash
hlen myhash
hexists myhash field2

hscan myhash 0
hscan myhash 0 match *field*
hscan myhash 0 count 1

 

삭제

더보기
hdel myhash field3

 

주의사항

구분 주의사항 설명 원인 / 배경
해결 방법 또는 고려 사항
필드 수 또는 값 크기 과다 압축 인코딩 사용 불가  ziplist 인코딩으로 메모리 절약
한계를 초과하면 hashtable로 전환
hash-max-ziplist-entries 조정
hash-max-ziplist-value 조정
해시 크기 과대 클러스터 사용 시 데이터가 샤드 간 분산되지 않음 Redis는 키 단위로 샤딩
하나의 해시는 한 노드에 저장됨
여러 개의 키로 나누어 저장
(예: user:1:profile, user:1:meta)
HDEL 명령 성능 저하 해시에 필드가 많을 경우, 삭제할 필드를 찾는 데 시간이 오래 걸림 내부적으로 해시 필드를 탐색하며 삭제
해시 필드 수 제한
불필요한 필드 정리

 

활용

상품 정보

더보기
hset product:1000 name "Red T-shirt" price 19900 stock 25 category "clothing"
  • 여러 속성이 있는 객체 스토리지를 저장할 때 유용 (상품 이름, 가격 등)

 

hgetall product:1000
hget product:1000 name
hmget product:1000 name price

 

5. Set

  • 고유한 문자열 집합
  • 순서 없음

 

명령어

추가

더보기
sadd skey value1 value2 value3

 

 

제거

더보기
spop skey
srem skey value2
  • srem: 특정 원소 값으로 삭제

 

조회

더보기
sismember skey value4
smembers skey
scard skey
sscan skey 0
sscan skey 0 count 1
sscan skey 0 match *1

 

집합연산

더보기
sdiff skey skey2
sdiffstore skey31 skey skey2
sinter skey skey2
sinterstore skey32 skey2
sintercard 1 skey1
sunion skey31 skey32
sunionstore skey33 skey31 skey32
  • sdiffstore: destination 집합에 결과를 저장

 

활용

고유 사용자 수 조사

더보기

하루 동안 방문한 사용자 ID 추적 (중복 방문 제외)

sadd users:2025-05-14 101
sadd users:2025-05-14 102
sadd users:2025-05-14 101
sadd users:2025-05-14 103
scard users:2025-05-14     # 방문자 수
smembers users:2025-05-14  # 방문자 목록

# 어제와 비교
sdiff users:2025-05-14 users:2025-05-13   # 오늘만 방문 (어제 X)
sinter users:2025-05-14 users:2025-05-13  # 어제 오늘 모두 방문
sunion users:2025-05-14 users:2025-05-13  # 어제 오늘 중 하루라도 방문

 

6. Sorted Set

  • 순서가 있는 집합
  • 모든 요소에 점수열이란 값을 가짐 (부동소수점)
  • 요소들은 항상 점수값으로 정렬됨 (오름차순)
  • 동일한 점수를 가진 요소들은 사전식으로 정렬됨

 

명령어

추가

더보기
zadd rank:event:1 255547 Saburo
zadd rank:event:1 276302 Jiro
zadd rank:event:1 311121 Shiro
zadd rank:event:1 324891 Taro

 

삭제

더보기
zpopmax rank:event:1
zpopmin rank:event:1
zmpop 1 rank:event:1 min count 2
zmpop 1 rank:event:1 max count 3
zrem rank:event:1 Taro

 

조회

더보기
zcard rank:event:1
zscan rank:event:1 0
zrank rank:event:1 Saburo
zrevrank rank:event:1 Saburo
zcount rank:event:1 200000 300000
zrange rank:event:1 0 1
zrangestore rank:event:1:low rank:event:1 0 1
zrevrange rank:event:1 0 1
zscore rank:event:1 Jiro
zmscore rank:event:1 Jiro Shiro

 

활용

실시간 랭킹

더보기
zincrby game:ranking 1500 "user123"
zincrby game:ranking 1000 "user456"
zincrby game:ranking 200 "user123"
zscan game:ranking 0
zrevrange game:ranking 0 9
zrevrange game:ranking 0 9 withscores
zrevrank game:ranking "user123"
zscore game:ranking "user123"
zremrangebyrank game:ranking 0 -2 # 가장 점수가 높은 애만 남도록
  • RDBMS에서 모델링할 때 성능 저하가 발생하기 쉬움
  • 정렬 유지 + 실시간으로 지속 갱신