[Redis] 스프링에서 레디스 사용하기 — Redisson으로 저장 가능한 객체와 고급 기능

y001·2025년 4월 19일
0
post-thumbnail

앞선 글에서 Redisson과 Lua를 활용한 원자적 연산의 흐름과 구조를 소개했다. 이번 글에서는 Redisson이 어떤 객체를 Redis에 저장할 수 있는지, 그리고 이를 활용한 고급 기능들인 분산 락, 캐시, 원자 스크립트 실행은 어떤 구조로 제공되는지를 살펴본다.


0. Redis 자체가 지원하는 자료 구조는?

Redisson은 기본적으로 Redis에서 제공하는 자료구조 위에 추상화된 API를 얹는다. Redis에서 제공하는 핵심 자료형은 다음과 같다:

자료형설명명령어 예시
String일반 문자열 값SET, GET, INCR
Hash필드-값 쌍 저장HSET, HGET, HDEL
List순서 있는 값의 리스트LPUSH, RPUSH, LPOP, LRANGE
Set중복 없는 값의 집합SADD, SMEMBERS, SPOP
ZSet점수 기반 정렬된 집합ZADD, ZRANGE, ZREMRANGEBYSCORE
StreamKafka-like 메시지 큐XADD, XREADGROUP, XACK
Bitmap비트 연산SETBIT, GETBIT
HyperLogLog근사치 기반 카운터PFADD, PFCOUNT
Geo위치 기반 데이터GEOADD, GEORADIUS

1. Redisson이 제공하는 분산 객체들

Redisson은 Redis의 위 자료형을 Java 객체처럼 다룰 수 있도록 다양한 인터페이스를 제공한다. 대표적으로 다음과 같다:

■ 컬렉션 기반 객체

Redisson 객체Redis 구조설명
RMap<K, V>Hash일반적인 Map 인터페이스
RMapCache<K, V>Hash + TTL만료 시간 있는 Map
RList<V>ListArrayList처럼 사용 가능
RSet<V>Set중복 없는 집합
RQueue<V> / RDeque<V>List큐/스택 자료 구조 구현
RScoredSortedSet<V>ZSet점수 기반 정렬 집합
RLexSortedSetZSet사전순 정렬 집합

■ 원자 연산 객체

Redisson 객체설명
RAtomicLong분산 환경에서 안전한 long 타입 카운터
RAtomicDouble분산 환경에서 안전한 double 카운터
RLongAdder고속 누적기 (멀티 쓰레드 최적화)

■ 비동기 / 반응형 / JSON 객체

객체설명
RJsonBucket<T>JSON 직렬화 기반 저장소
reactive()반응형 API 지원 (Project Reactor)
rxJava()RxJava 기반 API 지원

2. Redisson의 고급 기능

Redisson은 단순한 키-값 저장소를 넘어서, 동시성 제어분산 환경을 위한 구조를 지원한다.

🔐 분산 락 (RLock)

val lock = redissonClient.getLock("lock:seat:123")
lock.tryLock(500, 3000, TimeUnit.MILLISECONDS)
// 좌석 예약 처리
lock.unlock()
  • 여러 인스턴스가 동시에 접근할 수 있는 상황에서 충돌 방지
  • 내부적으로 Redis 명령어 SET key value NX PX 기반 구현
  • RLock, RFencedLock, RReadWriteLock, RMultiLock 등 다양한 옵션 존재

🧠 분산 캐시 (RMapCache, RLocalCachedMap)

val mapCache = redissonClient.getMapCache<String, Movie>("cache:movie:list")
mapCache.put("popular", movieList, 10, TimeUnit.MINUTES)
  • TTL(Time To Live) 지정 가능
  • Local + Remote 캐시 동기화 지원 (invalidate 방식)
  • 캐시 무효화 시 Lua 스크립트 또는 Topic 이용

📜 원자 스크립트 실행 (RScript.eval)

val luaScript = loadLua("ip_ratelimit.lua")
val result = redissonClient
    .getScript(StringCodec.INSTANCE)
    .eval<Long>(
        RScript.Mode.READ_WRITE,
        luaScript,
        RScript.ReturnType.INTEGER,
        listOf(key, blockedKey),
        limit.toString(),
        now.toString(),
        expireMillis.toString()
    )
  • 여러 Redis 명령어를 하나의 트랜잭션처럼 처리 가능
  • 조건 분기, 반복문 등 복잡한 흐름 제어 가능
  • 레이스 컨디션 방지와 성능 최적화에 탁월

Lua 스크립트는 스크립트 단위로 원자성을 보장한다.
단, 스크립트 여러 개를 순차 실행한다고 해서 전체 트랜잭션처럼 묶이지는 않는다. 이럴 경우 RBatch, MULTI/EXEC, 또는 Kafka 기반의 흐름 제어 등 별도 조치 필요.


3. Redisson vs RedisTemplate 구조 비교

기능RedisTemplateRedisson
기본 자료형 지원OO
복합 객체 지원XO (RMap, RSet, RList 등)
분산 락X (직접 구현 필요)O (RLock)
캐시 TTL 지원O (set + expire)O (RMapCache)
로컬 캐시XO (RLocalCachedMap)
Lua 스크립트제한적O (RScript + Lua)
배치 처리제한적O (RBatch)
트랜잭션 처리MULTI/EXEC부분 지원 (Batch or Lua 내부 원자성)

마무리

Redisson은 Redis를 단순한 저장소가 아닌, 분산 시스템의 핵심 도구로 확장해준다. 특히 다양한 동시성 처리 도구와 캐시 전략, 복합 객체 구조를 제공해주기 때문에, 실제 비즈니스 로직을 보다 안정적이고 효율적으로 구성할 수 있다.

0개의 댓글