Projects/HubEleven

[동시성 처리] 동시성 문제 (Race Condition) 해결 방법 3가지 관점 - (3) Redis Distributed Lock

annovation 2026. 3. 11. 23:52

Redis Distributed Lock

  • Redis에서 제공하는 대표적인 라이브러리 Luttuce 와 Reddison 을 활용하여 해결할 수 있다.

💡Lettuce

 

1) 특징

  • 비동기(Async) 및 동기(Sync) 방식 모두 지원하는 Redis 클라이언트이다.
❗️Redis 클라이언트 란?
애플리케이션(Spring, Node 등)이 Redis 서버와 통신하기 위해 사용하는 라이브러리
  • Netty 기반의 비동기 I/O 처리를 지원한다.
❗️Netty 란?
Lettuce가 Redis 서버와 통신할 때 사용하는 비동기 내부 네트워크 프레임워크
  • Lettuce는 분산락을 제공하는 라이브러리가 아니라 Redis 명령을 실행하는 클라이언트이기 때문에 lock을 Redis 명령어로 직접 구현해야 한다.
❗️setnx 명령어를 활용하여 분산락 구현
setnx : Set If Not Exist의 줄임말로, 특정 key에 value 값이 존재하지 않을 경우에 값을 설정(set) 하는 명령어
  • spin Lock 방식
- lock을 획득하려는 스레드가 lock을 사용할 수 있는지 반복적으로 확인하면서 lock을 시도하는 방식
- retry 로직을 작성해야한다.
  • Spring Data Redis 라이브러리에서 기본적으로 사용 가능하다.
  • Spring Boot 2.x 이상에서는 기본 Redis 클라이언트로 Lettuce가 사용된다.
  • Redis 명령을 이용한 간단한 분산 락 구현은 가능하다.

2) 장점

  • Lettuce는 Redis Cluster 환경에서도 사용할 수 있다.
❗️Redis 클러스터 환경(cluster environment) 이란? (공식 문서)
여러 개의 Redis 서버를 묶어서 하나의 Redis처럼 사용하는 구조
데이터를 여러 서버에 나눠 저장(sharding) 하는 것

 

3) 단점 (참고 자료)

  • 단순한 분산 락을 구현하는 데 사용할 수 있지만, 완전한 Redisson 수준의 분산 락을 제공하지 않음

4) 사용 방법

  • infrastructure/redis/RedisLockRepository.java
@RequiredArgsConstructor
@Component
public class RedisLockRepository {
    private RedisTemplate<String, String> redisTemplate;

    public Boolean lock(Long key) {
        return redisTemplate
                .opsForValue()
                .setIfAbsent(generateKey(key), "lock", Duration.ofMillis(3_000));
    }

    public Boolean unlock(Long key) {
        return redisTemplate.delete(generateKey(key));
    }

    public String generateKey(Long key) {
        return key.toString();
    }
}

 

➡️ lock(Long key) 메서드

public boolean lock(Long key) {
    return redisTemplate.opsForValue()
        .setIfAbsent(key, "lock", Duration.ofMillis(3000));
}
  • Duration.ofMillis(3_000) : 3초 후 자동으로 lock 삭제

 

실제 Redis 명령

SET key value NX PX 3000
  • key가 없으면 생성 → 락 획득
  • key가 있으면 실패 → 이미 다른 스레드가 락 사용중

➡️ unlock(Longe key) 메서드

public void unlock(Long key) {
    redisTemplate.delete(key);
}

 

 

실제 Redis 명령

DEL key
  • lock 삭제 → 다른 프로세스가 lock 획득 가능

💡Reddison

 

1) 특징

 

2) 장점

 

3) 단점

 

4) 사용 방법


참고 자료