스프링부트에서 Redis를 캐시관련 데이터 조작하고 있었다.
캐시를 Redis로 사용하면서 저장하고 불러오고 수정하며 가공한다. Redis는 스프링부트에서 자체적으로 지원해준
다. 그래서 쉽게 접근가능하고 누구나 사용할 수 있다. 간편하게 사용할 수 있는 No-Sql 이다.
그래서 처리속도는 Sql 보다 빠르지만 데이터 리턴값들은 다 String 으로 따로 데이터 형식이 없이 나오므로 직접 전처리 작업 같은걸 해야한다. ㅎㅎ 그래도 뭐 새로운 부분을 배우는 거니까 한번 확인해보자 !
🔴 Redis 개요
Redis는 Remote Dictionary Server의 약자로, 메모리 기반의 NoSQL 데이터베이스입니다.
- Key-Value 저장소로 동작하며, 빠른 속도로 데이터를 처리할 수 있음
- 캐싱, 세션 저장, 메시지 큐, 실시간 데이터 처리 등에 주로 사용됨
- 데이터 지속성 (Persistence) 옵션이 있으며, 디스크 저장도 가능
📌 1. Redis의 주요 데이터 구조
데이터 타입설명주요 명령어
String | 기본적인 문자열 저장 (최대 512MB) | SET, GET, INCR, DECR, APPEND |
List | 순서가 있는 배열 (Linked List) | LPUSH, RPUSH, LPOP, RPOP, LRANGE |
Set | 중복을 허용하지 않는 집합 | SADD, SREM, SMEMBERS, SINTER |
Sorted Set | 점수를 기준으로 정렬된 집합 | ZADD, ZRANGE, ZREM, ZSCORE |
Hash | 필드-값 형태의 저장소 (Object 저장 가능) | HSET, HGET, HGETALL, HDEL |
Bitmap | 비트 단위로 데이터를 저장하는 구조 | SETBIT, GETBIT, BITCOUNT |
HyperLogLog | 큰 데이터셋에서 유니크한 개수를 추정하는 구조 | PFADD, PFCOUNT |
📌 2. Redis 주요 명령어
✅ 기본적인 Key-Value 명령어
SET key "value" # key에 value 저장
GET key # key의 값 가져오기
DEL key # key 삭제
EXPIRE key 60 # key에 60초 TTL 설정
TTL key # key의 남은 TTL 확인
✅ List 명령어 (Queue처럼 사용 가능)
LPUSH mylist "A" # 왼쪽(A)에서 데이터 삽입
RPUSH mylist "B" # 오른쪽(B)에서 데이터 삽입
LPOP mylist # 왼쪽에서 요소 꺼내기
RPOP mylist # 오른쪽에서 요소 꺼내기
LRANGE mylist 0 -1 # 모든 요소 조회
✅ Hash 명령어 (Object 형태 데이터 저장)
HSET user:100 name "John" age 25 # Hash 필드 저장
HGET user:100 name # name 필드 조회
HGETALL user:100 # 모든 필드 조회
HDEL user:100 age # 특정 필드 삭제
✅ Set 명령어 (중복 방지)
SADD myset "Apple" "Banana" # Set에 값 추가
SMEMBERS myset # 모든 값 조회
SREM myset "Banana" # 특정 값 삭제
SINTER set1 set2 # 교집합 조회
✅ Sorted Set 명령어 (점수를 이용한 정렬)
ZADD leaderboard 100 "Alice" # 점수 100인 Alice 추가
ZADD leaderboard 200 "Bob" # 점수 200인 Bob 추가
ZRANGE leaderboard 0 -1 # 낮은 점수부터 조회
ZRANK leaderboard "Alice" # Alice의 순위 조회
ZSCORE leaderboard "Bob" # Bob의 점수 조회
📌 3. Redis 트랜잭션 (MULTI & EXEC)
Redis는 기본적으로 원자적(Atomic) 연산을 지원하지만, 여러 개의 명령어를 하나의 트랜잭션으로 실행하려면 MULTI를 사용합니다.
MULTI
SET balance 100
INCR balance
EXEC
- MULTI: 트랜잭션 시작
- EXEC: 트랜잭션 실행 (중간에 에러가 나도 실행됨)
- DISCARD: 트랜잭션 취소
🚨 주의! Redis 트랜잭션은 Rollback(롤백) 기능이 없음!
📌 4. Redis 스크립팅 (Lua 스크립트)
Redis는 Lua 스크립트를 지원하여 복잡한 로직을 원자적으로 실행할 수 있음.
✅ Lua 스크립트 실행
EVAL "return 1+1" 0 # 1+1 실행 → 결과: 2
✅ Redis Lua 예제 (Key 증가 후 반환)
EVAL "redis.call('INCR', KEYS[1])" 1 mycounter
- redis.call('INCR', KEYS[1]) → Redis 명령어 실행
- 1 mycounter → Key가 1개이며, mycounter를 전달
✅ Lua에서 ARGV를 활용한 예제
EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 mykey "Hello"
➡️ "Hello" 값을 mykey에 저장
✅ 기본적인 Lua 실행
EVAL "return redis.call('GET', 'mykey')" 0
➡️ "Hello, Redis!" 출력
✅ Redis 명령어 실행
EVAL "return redis.call('GET', 'mykey')" 0
➡️ "mykey" 값을 가져옴
✅ Redis에서 Key 증가시키기
EVAL "redis.call('INCR', KEYS[1])" 1 mycounter
➡️ mycounter 값을 1 증가
✅ Key의 값 설정 (ARGV 사용)
EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 mykey "Hello"
➡️ "Hello" 값을 mykey에 저장
✅ 여러 개의 Key 값을 가져오기
EVAL "return {redis.call('GET', KEYS[1]), redis.call('GET', KEYS[2])}" 2 key1 key2
➡️ key1, key2의 값을 리스트로 반환
✅ 여러 개의 Key 값을 삭제
EVAL "redis.call('DEL', KEYS[1]); redis.call('DEL', KEYS[2])" 2 key1 key2
➡️ key1, key2 삭제
✅ Key 값이 존재하면 증가시키기
EVAL "if redis.call('EXISTS', KEYS[1]) == 1 then return redis.call('INCR', KEYS[1]) else return nil end" 1 mycounter
➡️ mycounter가 존재하면 증가, 없으면 nil 반환
✅ Key 값이 특정 값과 같으면 삭제
EVAL "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end" 1 mykey "Hello"
➡️ mykey 값이 "Hello"이면 삭제
✅ 여러 개의 Key 값 설정
EVAL "
for i=1, #KEYS do
redis.call('SET', KEYS[i], ARGV[i])
end
return 'OK'
" 2 key1 key2 "value1" "value2"
➡️ key1 → "value1", key2 → "value2" 저장
✅ Lua Script를 Redis에 로드
SCRIPT LOAD "return redis.call('GET', KEYS[1])"
➡️ sha1-hash 값을 반환
✅ EVALSHA로 실행
EVALSHA <sha1-hash> 1 mykey
➡️ mykey 값을 가져옴
🚀 EVALSHA를 사용하면 Redis 성능이 향상됨!
✅ 재고 수량 감소 스크립트
EVAL "
local stock = redis.call('GET', KEYS[1])
if tonumber(stock) > 0 then
redis.call('DECR', KEYS[1])
return 'OK'
else
return 'Out of stock'
end
" 1 product_stock
➡️ 재고가 0보다 크면 감소, 없으면 "Out of stock" 출력
📌 Lua & Redis 정리
특징설명
EVAL | Lua 스크립트 실행 |
EVALSHA | 캐시된 Lua 실행 (성능 향상) |
redis.call() | Redis 명령 실행 |
KEYS[n] | 전달된 Key 값 |
ARGV[n] | 전달된 Argument 값 |
⚡ Lua를 사용하면 Redis에서 더 복잡한 로직을 효율적으로 실행할 수 있음! 🚀
📌 5. Redis 퍼시스턴스 (데이터 지속성)
Redis는 기본적으로 메모리 기반이지만 데이터를 디스크에 저장할 수도 있습니다.
방법설명
RDB (Redis Database) | 특정 주기마다 데이터 스냅샷을 저장 |
AOF (Append-Only File) | 모든 명령어를 로그로 저장하여 복구 가능 |
✅ RDB 저장 & 복원
SAVE # 동기적으로 RDB 저장
BGSAVE # 비동기적으로 RDB 저장
✅ AOF 설정 (Append-Only File)
appendonly yes
appendfilename "appendonly.aof"
➡️ AOF 파일은 Redis 재시작 후 데이터 복구 가능
📌 6. Redis Pub/Sub (메시지 큐 기능)
Redis는 실시간 메시지 시스템으로도 활용될 수 있음.
✅ 메시지 발행 (PUBLISH)
PUBLISH mychannel "Hello, Redis!"
➡️ mychannel이라는 채널에 메시지 전송
✅ 메시지 구독 (SUBSCRIBE)
SUBSCRIBE mychannel
➡️ mychannel을 구독하면, 해당 채널의 메시지를 실시간으로 받을 수 있음.
📌 7. Redis 클러스터 (Scaling & Replication)
Redis는 **수직 확장(Replication) & 수평 확장(Clustering)**을 지원함.
✅ 마스터-슬레이브 복제 (Replication)
SLAVEOF <master_ip> <master_port>
➡️ 슬레이브 Redis가 마스터 Redis의 데이터를 복제
✅ Redis 클러스터 명령어
CLUSTER NODES # 클러스터 노드 조회
CLUSTER INFO # 클러스터 상태 확인
➡️ **샤딩(Sharding)**을 통해 여러 노드로 데이터를 분산 저장 가능
🎯 결론
Redis는 고속 Key-Value 저장소로 다양한 기능을 제공
- 캐시 시스템 (Session, 로그인 정보 저장)
- 메시지 큐 (Pub/Sub)
- 실시간 랭킹 시스템 (Sorted Set 활용)
- 데이터 분석 (HyperLogLog, Bitmap 활용)
⚡ 빠른 속도가 필요하거나, 실시간 처리가 중요한 경우 Redis를 적극 활용하면 좋다! 🚀