본문 바로가기

Redis 자료구조와 사용방법

@정소민fan2025. 11. 19. 22:57

Redis를 단순히 Get/Set만 하는 저장소로 알면 손해다. Redis가 제공하는 다양한 자료구조(Data Structures)를 상황에 맞게 골라 쓰는 것이 성능 최적화의 핵심이다. 요새 신입 개발자의 기본 소양이 된 듯 하다. 면접에 가니까 Redis 왜 안썼냐고 질문하는 곳도 있었다.


[DB] Redis, 자료구조와 명령어 완벽 정리 (String부터 Stream까지)

Redis는 In-memory Data Structure Store다. 즉, 메모리 위에서 동작하는 '자료구조' 서버라는 뜻이다. 어떤 데이터를 어떻게 저장하느냐에 따라 사용할 자료구조가 달라진다. 하나씩 뜯어보자.

1. 기본 설정 및 명령어

Redis는 기본적으로 16개(0~15번)의 격리된 데이터베이스 공간을 가진다.

  • DB 이동: select [index] (기본은 0번)
  • 전체 키 조회: keys * (주의: 데이터가 많을 때 사용하면 서버 렉 걸림. 운영에선 금지)
  • 전체 데이터 삭제: flushdb (현재 DB 삭제), flushall (모든 DB 삭제)

2. String (문자열)

가장 기본이 되는 1:1(Key-Value) 구조다.

  • 저장: set [key] [value]
    • 덮어쓰기 방지: set [key] [value] nx (Not Exist, 값이 없을 때만 저장. 분산 락 구현에 쓰임)
    • TTL 설정: set [key] [value] ex [초] (지정 시간 후 자동 삭제)
  • 조회: get [key]
  • 삭제: del [key]
  • 증감(Atomic): incr [key] (+1), decr [key] (-1)

활용 팁: 객체 캐싱

RDB에 있는 객체 데이터를 저장할 땐 주로 JSON String으로 직렬화해서 저장한다.

set posting:1 "{\"title\":\"hello java\", \"contents\":\"redis...\"}"

3. List (리스트)

Deque(Double Ended Queue) 구조다. 양쪽 끝에서 넣고 뺄 수 있다.

  • 삽입: lpush (왼쪽 넣기), rpush (오른쪽 넣기)
  • 추출: lpop (왼쪽 빼기), rpop (오른쪽 빼기)
  • 조회: lrange [key] [start] [stop]
    • lrange mylist 0 -1 (전체 조회, 파이썬 슬라이싱과 유사)
  • 길이: llen [key]

활용 사례

  • 최근 방문 페이지 (단순): 들어올 때마다 lpush. 하지만 중복 제거가 안 된다는 단점이 있음.

4. Set (집합)

순서가 없고 중복을 허용하지 않는 자료구조다.

  • 추가: sadd [key] [value]
  • 조회: smembers [key] (모든 요소 조회)
  • 확인: sismember [key] [value] (특정 값이 있는지 확인, 있으면 1 없으면 0)
  • 삭제: srem [key] [value]
  • 개수: scard [key]

활용 사례

  • 좋아요 기능: 한 유저는 한 게시물에 한 번만 좋아요 가능.
  • 일일 순수 방문자(UV): IP 등을 저장해 중복 제거.

5. Sorted Set (ZSet - 정렬된 집합)

Set에 Score(점수)를 달아서 정렬한다. 자바의 TreeSet가 같다고 생각하면 된다.

  • 추가: zadd [key] [score] [member]
    • 이미 존재하는 member라면 score가 갱신되며 재정렬된다.
  • 조회:
    • zrange [key] 0 -1 (오름차순)
    • zrevrange [key] 0 -1 (내림차순)
    • withscores 옵션을 붙이면 점수까지 같이 나옴.
  • 순위 조회: zrank (오름차순 등수), zrevrank (내림차순 등수)

활용 사례

  • 실시간 랭킹(Leaderboard): Score에 점수나 경험치를 넣음.
  • 최근 본 상품 (중복 제거): Score에 timestamp를 넣음. 같은 상품을 다시 보면 최신 시간으로 갱신되면서 맨 앞으로 옴. (List보다 강력함)

6. Hash (해시)

하나의 Key 안에 또 다른 Key-Value Map이 들어있는 구조다. 객체 하나를 필드별로 관리할 때 좋다.

  • 구조: Key -> { field1: value, field2: value }
  • 설정: hset [key] [field] [value] ...
  • 조회: hget [key] [field], hgetall [key] (전체)
  • 증감: hincrby [key] [field] [num]

7. Messaging: Pub/Sub & Stream

Redis는 메시지 브로커 역할도 수행할 수 있다.

① Pub/Sub (발행/구독)

실시간 알림에 적합하다. 단, 메시지가 저장되지 않는다. (Fire and Forget)

  • 구독: subscribe [channel]
  • 발행: publish [channel] [message]
  • 특징: 채널을 보고 있는 모든 서버(구독자)에게 메시지가 전파된다. 구독자가 없으면 메시지는 증발한다.

② Stream (스트림)

로그 파일처럼 데이터가 계속 추가되는 구조다. Pub/Sub과 달리 데이터가 저장된다.

  • 발행: xadd [key] * [field] [value] (*은 ID 자동생성)
  • 읽기: xread block [ms] streams [key] $
    • $ 옵션: 지금 이후 들어오는 새로운 메시지만 읽겠다.
  • 조회: xrange [key] [start] [end]

한계점

Redis는 기본적으로 메모리 기반이다. 데이터 영속성(AOF, RDB) 옵션이 있지만, 절대 유실되면 안 되는 중요한 메시지(결제, 주문 등)라면 Redis Stream보다는 Kafka를 쓰는 것이 정신건강에 이롭다.

'코딩' 카테고리의 다른 글

객체지향은 신이고 테스트는 무적이다  (2) 2025.11.17
의존성 역전으로 테스트 편하게 만들기 !!  (0) 2025.11.08
PG 결제  (0) 2025.10.21
PNG 변환기 만들기  (0) 2025.10.21
이분 탐색  (0) 2025.10.10
정소민fan
@정소민fan :: 코딩은 관성이야

코딩은 관성적으로 해야합니다 즐거운 코딩 되세요

목차