하야시 쇼고 님의 "실전 레디스" 책을 정리한 포스팅 입니다.
1. 파이프라인
- 이전 응답을 기다리지 않고 여러 요청을 한꺼번에 서버에 보내는 방식
항목 | 설명 |
사용 목적 |
성능 최적화
|
대체 가능 기능 | MGET, MSET과 유사 (단, 파이프라인이 더 범용적) |
장점 | - 실행 순서 보장 - RTT(Round Trip Time) 절약 |
단점 |
- 조건 분기 불가
- 복잡한 로직 작성 어려움 - 원자성 보장 안 됨 |
예시
더보기
import redis
# Redis 클라이언트 연결
client = redis.StrictRedis(host='localhost', port=6379, db=0)
# 파이프라인 시작
pipe = client.pipeline()
# 여러 명령어를 파이프라인에 추가
pipe.set('key1', 'value1')
pipe.set('key2', 'value2')
pipe.set('key3', 'value3')
pipe.get('key1')
pipe.get('key2')
# 명령어를 한 번에 실행하고 응답 받기
responses = pipe.execute()
# 응답 출력
print(responses) # 응답: [True, True, True, 'value1', 'value2']
2. 루아
- 레디스에 내장된 스크립트 언어
기능
기능/특성 | 설명 |
원자성 보장 |
모든 명령은 하나의 명령처럼 실행됨 (중간에 실패 시 전체 롤백 가능)
|
복잡한 로직 |
if, for 사용 가능
|
읽기 작업 비동기 가능 |
읽기 작업은 트랜잭션 외로 비동기 처리가 가능 (보통은 call로 동기 실행)
|
샌드박스 환경 | 호스트 시스템 접근 제한 (전역 변수 사용 제한됨) |
표준 라이브러리 |
base, table, string, math, struct, cjson, bitop 등
|
복제 및 영속화 |
스크립트 실행 결과는 마스터 → 레플리카 복제, RDB/AOF에 포함됨
|
이페머럴 스크립트
- 한 번 실행하고 사라지는 임시 Lua 스크립트
명령어 | 설명 |
EVAL |
Lua 스크립트 직접 실행 (eval "..." numkeys key1 ... argv1 ...)
|
EVALSHA |
SHA1 해시값을 통해 이미 로드된 스크립트 실행
|
SCRIPT LOAD |
Lua 스크립트를 Redis에 로드하고 SHA1 해시 반환
|
SCRIPT FLUSH |
Redis 인스턴스에 저장된 모든 스크립트 삭제
- 메모리 사용량을 줄이기 위해 삭제 - eval이나 evalsha로 실행한 스크립트는 레디스 인스턴스에 남아있음 |
SCRIPT KILL |
실행 중인 스크립트 강제 종료
- busy-replay-threshold: 타임아웃 설정 |
예제) eval
더보기
eval "local val = 0; for i = 1, ARGV[1] do val = val + i; end; return val" 0 10
- 1~ARGV[1]까지 루프 반복
- 각 반복마다 i값 누적
예제) evalsha
더보기
evalsha "5b6234158...." 2 key1 key2 value1 value2 value3
- 실행할 스크립트 파일의 해시값을 인자로 전달하여 실행함
예제) script load
더보기
script load "파일명"
- 특정 스크립트 파일을 sha1로 해시화하고 저장함
- 해시값 출력됨
예제) 반복문
더보기
require 'redis'
script = <<EOF
local counts = {}
for i, key in ipairs(KEYS) do
counts[i] = redis.call('SCARD', key)
end
return counts
EOF
redis = Redis.new
hashed_script=redis.script(:load, script)
redis.evalsha(hashed_script, keys: ['user:1:votes', 'user:2:votes', 'user:3:votes'])
puts result
예제) TTL 설정
더보기
require 'redis'
script = <<EOF
redis.call('SET', KEYS[1], ARGV[1])
redis.call('EXPIRE', KEYS[1], ARGV[2])
EOF
redis = Redis.new
hashed_script=redis.script(:load, script)
redis.evalsha(hashed_script, keys: ['user:1'], argv: ['hi', 30])
- 기본적으로 TTL 설정을 옵션으로 쓰려면, SET 명령어와만 함께 쓸 수 있음
- 데이터를 저장한 후, TTL 명령어로 설정해야 함
- 이러할 경우 RTT 오버헤드 발생
플래그
- 스크랩트 내에서 루아가 어떻게 동작할지 미리 알 수 없음
- 플래그를 통해 사전에 어떻게 동작할 지 전달하여 레디스를 제어함
플래그명 | 의미 |
no-writes |
해당 함수는 읽기 전용임을 선언 (쓰기 금지)
|
allow-oom |
OOM 상황에서도 실행 가능
|
allow-state |
오래된 상태에서도 실행 가능
|
no-cluster |
클러스터 환경에서 실행 금지
|
allow-cross-slot-keys |
클러스터 환경에서 다중 슬롯 키 접근 허용
|
레디스 함수
- 이페머럴 스크립트를 모듈화
이페머럴 스크립트의 문제점
문제점 | 설명 |
SHA1 기반 |
해시값 기반 실행으로 디버깅 어려움
|
재사용 불가 |
다른 스크립트에서 호출 불가 (모듈화 어려움)
|
버전 제한 |
Lua 5.1에 고정, 최신 Lua 기능 사용 불가
|
특징
- 재사용성
- 영속성: 복제, 스냅숏, AOF 등
예제) 함수 등록
더보기
function load "#!lua name=mylib
redis.register_function('calculator',
function(keys, args)
local val = 0
for i = 1, args[1] do
val = val + i
end
return val
end
"
- mylib 이라는 라이브러리에 함수를 등록
fcall calculator 0 10
function delete mylib
예시) 함수 실행 정지
더보기
function kill
shutdown nosave
예제) 플래그
더보기
#!lua name=mylib
local function sum(keys, args)
...
redis.register_function(
function_name='calculator',
callback=sum,
flags={'no-writes'}
)
루아 프로그래밍
- 루아 스크립트 기반
- 구조화, 관리, 제어가 발전함
예외 처리
방식 | 설명 |
redis.call(...) |
오류 발생 시 스크립트 즉시 중단
|
redis.pcall(...) |
오류 발생 시 중단하지 않고 오류 객체 반환
|
예제) redis.call()
더보기
redis.call("SET", "key", "value")
redis.breakpoint() -- 여기서 실행이 중단됨
local value = redis.call("GET", "key")
return value
redis.debug("This is a debug message!")
local val = redis.call("GET", "key")
redis.debug("Fetched value:", val)
return val
예제) redis.pcall()
더보기
local result = redis.pcall("INCR", "key") -- key가 숫자가 아니면 오류 발생
if type(result) == "table" and result.err then
return "Error: " .. result.err
end
return result
- 오류 발생 시 스크립트가 중단되지 않고, 오류 객체를 반환함
예제) redis.sha1hex()
더보기
local hash = redis.sha1hex("Hello, Redis!")
return hash -- "09f7e02f1290be211da707a266f153b3b10e6932"
'Database > Redis' 카테고리의 다른 글
[실전 레디스] 5-1. 레디스 운용 관리: 영속성 (0) | 2025.03.21 |
---|---|
[실전 레디스] 3-1. 고급 기능: 주요 기능 (0) | 2025.03.21 |
[실전 레디스] 2-4. 자료형과 기능: 공통 명령어 (0) | 2025.03.21 |
[실전 레디스] 2-3. 자료형과 기능: 보조 기능 (0) | 2025.03.21 |
[실전 레디스] 2-2. 자료형과 기능: 보조 자료형 (0) | 2025.03.20 |