하야시 쇼고 님의 "실전 레디스" 책을 정리한 포스팅 입니다.
1. 트랜잭션
명령어
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 값이 변경되지 않았다면 실행, 변경되었으면 실패
- CAS (Compare and Sweep)
- 트랜잭션 종료 전에 대상이 된 키가 변경되면 트랜잭션의 전체 실행을 중지
- 다시 수행해야 함
특징
- 롤백 지원 X
- 실패한 명령어 건너뛰고 남은 작업을 계속 처리함
낙관적 락
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. 모듈
- 버전 호환성 레디스 버전에 의존하지 않음
- 높은 성능
기능
- 자동 메모리 관리기능 제공
- 저수준 API / 고수준 API 제공
등록
#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;
}
- 모듈 파일 생성 (c)
- RedisModule_Init: 함수로 모듈 등록 및 초기화
- RedisModule_CreateCommand: 명령어 등록
gcc -shard -o hellomodule.so -fPIC hellomodule.c
MODULE LOAD /path/to/hellomodule.so
- 컴파일 및 등록
명령어
MODULE UNLOAD hellomodule
MODULE LIST
활용
- 자료형 정의
2. 키 공간 알림
- 데이터 변경이나 서버에 이벤트가 발생할 경우 알림을 제공하는 시스템
- 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 구독
SUBSCRIBE __keyspace@0__:mykey
- keyspace 알림 구독 (키가 변경될 때 알림)
SUBSCRIBE __keyevent@0__:set
- keyevent 알림 구독 (특정 이벤트 발생 시 알림)
6. 클라이언트 측 캐싱
- RTT 오버헤드를 줄이기 위한 기능
- 클라이언트에서 자주 사용하는 키를 캐싱하여 Redis 요청을 줄임
무효화 매커니즘
- 데이터 정합성을 보장하기 위한 기능
작동 방식
- 클라이언트가 키를 캐싱
- 서버는 전역 테이블(무효화 테이블) 에 캐싱된 키를 갖는 클라이언트의 목록을 기록해 둠
- 키가 업데이트될 경우, 서버는 해당 키를 가진 클라이언트들에게 무효화 메시지 전송
- 클라이언트는 무효화 메시지를 받고 해당 키를 무효화함
설정
CLIENT TRACKING ON
모드
브로드캐스트
- 여러 클라이언트가 동일한 키를 구독할 때 사용하는 방식
- 서버가 키 변경을 감지하면 모든 관련 클라이언트에 무효화 메시지를 전송함
설정
CLIENT TRACKING ON BCAST
RESP3
- Redis의 새로운 응답 프로토콜
- 데이터 유형을 명확하게 표현
- 클라이언트 캐싱을 위한 무효화 메시지 포함 가능
설정
HELLO 3
CLIENT TRACKING ON RESP3
'Database > Redis' 카테고리의 다른 글
[실전 레디스] 5-2. 레디스 운용 관리: 아키텍처 (0) | 2025.03.21 |
---|---|
[실전 레디스] 5-1. 레디스 운용 관리: 영속성 (0) | 2025.03.21 |
[실전 레디스] 3-1. 고급 기능: 루아 (0) | 2025.03.21 |
[실전 레디스] 2-4. 자료형과 기능: 공통 명령어 (0) | 2025.03.21 |
[실전 레디스] 2-3. 자료형과 기능: 보조 기능 (0) | 2025.03.21 |