Database/Redis

[실전 레디스] 3-1. 고급 기능: 주요 기능

noahkim_ 2025. 3. 21. 21:39

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

 

1. 트랜잭션

특징

  • 트랜잭션 안의 명령: MULTI 이후 → 실행 안 되고 큐에 저장됨 (DELAYED 실행)
  • 읽기 명령: 트랜잭션 바깥 → 즉시 실행됨 (IMMEDIATE 실행)
  • 롤백 지원 X (실패한 명령어 건너뛰고 남은 작업을 계속 처리함)

 

명령어

명령어 설명
MULTI
트랜잭션 시작.
- 이후 입력되는 명령어들을 큐에 저장함 (즉시 실행 X)
EXEC
트랜잭션 종료
- MULTI로 큐에 저장된 명령어들을 순차 실행
DISCARD
트랜잭션 중 큐에 저장된 모든 명령어를 취소하고 트랜잭션 종료
WATCH
특정 키 감시.
- EXEC 전까지 해당 키가 다른 클라이언트에 의해 수정되면 EXEC가 실패함
→ CAS(Compare And Swap) 패턴 구현 가능

 

예제) MULTI/EXEC

더보기
MULTI
  SET foo 10
  INCR foo
  INCR foo
  GET foo
EXEC

 

예제) DISCARD

더보기
MULTI
SET key1 "value1"
SET key2 "value2"
DISCARD  # 트랜잭션을 취소하고 변경 사항 반영 안 됨

 

예제) WATCH

더보기
WATCH balance  # balance 키 감시
MULTI
INCR balance  # balance 증가
EXEC  # balance 값이 변경되지 않았다면 실행, 변경되었으면 실패

 

낙관적 락

  • 트랜잭션 충돌이 일어나지 않을 것이라 기대하고 처리하는 방식
  • 프로그래밍적으로 락을 걸어 일관성을 보장
  • 읽기 작업은 트랜잭션 안에서 실행되지 않고 독립적인 동작
  • 그 사이에 다른 클라이언트가 데이터를 바꿔도 막을 방법이 없음

 

예제

더보기
require 'redis'
redis = Redis.new

def transfer(redis, amount)
  retry_count = 3

  retry_count.times do
    redis.watch("balance")  # 감시 시작
    balance = redis.get("balance").to_i

    if balance < amount
      redis.unwatch  # 감시 해제
      puts "잔액 부족"
      return false
    end

    redis.multi do |multi|
      multi.decrby("balance", amount)  # balance 감소
    end

    return true if redis.get("balance").to_i == balance - amount
  end

  puts "트랜잭션 실패: 충돌 발생"
  false
end

# 초기 잔액 설정
redis.set("balance", 100)

# 30만큼 출금 시도
transfer(redis, 30)

 

2. 모듈

  • Redis 서버에 외부 기능을 추가할 수 있는 확장 플러그인 시스템

 

특징

항목 설명
독립적 개발 가능
Redis 핵심 버전의 업데이트에 영향을 거의 받지 않음 → 버전 호환성 높음
고성능 유지
Redis 내부에서 동작하므로 native 성능 제공
자동 메모리 관리
Redis의 메모리 allocator를 이용해 GC 없이 안정적인 메모리 관리 가능
다양한 API 제공
- 저수준 API: 직접 명령어 정의, 메모리 핸들링
- 고수준 API: 쉽게 자료구조·명령어 구성

 

 

예제) 모듈 파일 생성  (c)

더보기
#include "redismodule.h"

// hello 명령어를 실행할 함수
int HelloCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
    if (argc != 1) {
        return RedisModule_WrongArity(ctx);
    }
    return RedisModule_ReplyWithSimpleString(ctx, "Hello, Redis!");
}

// 모듈 로드 시 실행되는 함수
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
    if (RedisModule_Init(ctx, "hellomodule", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR) {
        return REDISMODULE_ERR;
    }

    // hello 명령어 등록
    if (RedisModule_CreateCommand(ctx, "hello", HelloCommand, "readonly", 0, 0, 0) == REDISMODULE_ERR) {
        return REDISMODULE_ERR;
    }

    return REDISMODULE_OK;
}
  • RedisModule_Init: 함수로 모듈 등록 및 초기화
  • RedisModule_CreateCommand: 명령어 등록

 

예제) 컴파일 및 등록

더보기
gcc -shard -o hellomodule.so -fPIC hellomodule.c
MODULE LOAD /path/to/hellomodule.so

 

예제) MODULE 명령어

더보기
MODULE UNLOAD hellomodule
MODULE LIST

 

3. 키 공간 알림

  • 데이터 변경이나 서버에 이벤트가 발생할 경우 알림을 제공하는 시스템
  • Pub/Sub 기능을 사용하여 클라이언트에게 알람을 보냄

 

특징

클라이언트 설정 필요
  • 클라이언트 측에서 알람을 받기 위해 notify-keyspace-events 지시자 설정을 활성화해야 함

 

감지할 이벤트의 종류를 지정할 수 있음
  • notify-keyspace-events 설정 값으로 셋팅함

 

두 가지 유형의 알림 지원
  • Keyspace Notifications (__keyspace@0__:mykey)
  • Keyevent Notifications (__keyevent@0__:set)

 

notify-keyspace-events 지시자

지시자 설명 예시 이벤트
K Keyspace 알림 활성화 (키 단위 알림)
__keyspace@0__:mykey
E Keyevent 알림 활성화 (이벤트 단위 알림)
__keyevent@0__:set
A 모든 이벤트 활성화 (AKE)
set, del, expire 등 모든 이벤트
g 일반적인 GET, DEL, EXISTS 관련 이벤트 get, del, exists
s SET, SETEX, PSETEX 관련 이벤트 set, setex
x EXPIRE, PERSIST, TTL 관련 이벤트
expire, persist, ttl
e EVICT (LRU 정책에 따른 삭제) 관련 이벤트 evict
m RENAME, RENAME NX 관련 이벤트
rename, renamenx
d DEL, UNLINK 관련 이벤트 del, unlink
l LIST 관련 이벤트 (LPUSH, RPUSH, LPOP, RPOP) lpush, rpop
h HASH 관련 이벤트 (HSET, HDEL, HMSET) hset, hdel
z ZSET (Sorted Set) 관련 이벤트 zadd, zrem
t SET (String Type) 관련 이벤트 set
f Lua 스크립트 실행 관련 이벤트 eval, evalsha

 

설정

1. 알림 기능 활성화

더보기
config set notify-keyspace-events KEA
  • K: Keyspace 이벤트 활성화
  • E: Keyevent 이벤트 활성화
  • A: 모든 이벤트 감지

 

2. Pub/Sub 구독

더보기

keyspace 알림 구독 (키가 변경될 때 알림)

SUBSCRIBE __keyspace@0__:mykey

 

keyevent 알림 구독 (특정 이벤트 발생 시 알림)

SUBSCRIBE __keyevent@0__:set

 

6. 클라이언트 측 캐싱

  • RTT 오버헤드를 줄이기 위한 기능
  • 클라이언트에서 자주 사용하는 키를 캐싱하여 Redis 요청을 줄임

 

무효화 매커니즘

  • 데이터 정합성을 보장하기 위한 기능

 

작동 방식
  1. 클라이언트가 키를 캐싱
  2. 서버는 전역 테이블(무효화 테이블) 에 캐싱된 키를 갖는 클라이언트의 목록을 기록해 둠
  3. 키가 업데이트될 경우, 서버는 해당 키를 가진 클라이언트들에게 무효화 메시지 전송
  4. 클라이언트는 무효화 메시지를 받고 해당 키를 무효화함

 

설정

더보기
CLIENT TRACKING ON

 

모드

브로드캐스트 
  • 여러 클라이언트가 동일한 키를 구독할 때 사용하는 방식
  • 서버가 키 변경을 감지하면 모든 관련 클라이언트에 무효화 메시지를 전송함

 

설정

더보기
CLIENT TRACKING ON BCAST

 

RESP3
  • Redis의 새로운 응답 프로토콜
  • 데이터 유형을 명확하게 표현
  • 클라이언트 캐싱을 위한 무효화 메시지 포함 가능

 

설정

더보기
HELLO 3

CLIENT TRACKING ON RESP3