RedRock 쉽게 이해하기

KKTRKKT·2024년 5월 24일
0

쉽게 이해하기

목록 보기
2/4

RedLock이란?

RedLock은 Redis 기반의 분산 잠금 메커니즘으로, 분산 환경에서 동일한 리소스에 대해 동시에 접근하는 여러 프로세스나 스레드를 제어하기 위해 사용됩니다. 이는 특히 여러 인스턴스에서 실행되는 애플리케이션들이 공유 리소스에 대한 잠금을 효율적으로 관리할 수 있도록 돕습니다.

RedLock의 작동 원리

  1. 잠금 획득:

    • 클라이언트는 다섯 개의 Redis 노드에 잠금 요청을 보냅니다.
    • 각 노드에 고유한 랜덤 문자열과 잠금 만료 시간을 설정합니다.
    • 클라이언트는 과반수 이상의 노드(다섯 개 중 세 개 이상)에서 잠금을 성공적으로 획득해야 합니다.
  2. 잠금 유지:

    • 클라이언트는 잠금이 만료되기 전에 잠금을 갱신해야 합니다.
    • 잠금 갱신을 위해 다시 과반수 이상의 노드에서 잠금 연장 요청을 보냅니다.
  3. 잠금 해제:

    • 작업이 완료되면 클라이언트는 각 Redis 노드에 잠금 해제 요청을 보냅니다.
    • 고유한 랜덤 문자열을 확인하여 해당 잠금을 해제합니다.

RedLock의 주요 특징

  • 높은 가용성: 여러 노드에 분산되어 있어 하나의 노드가 실패하더라도 잠금 기능을 유지할 수 있습니다.
  • 데드락 방지: 잠금 만료 시간이 있어 데드락 상황을 방지합니다.
  • 신뢰성: 과반수 이상의 노드에서 잠금을 획득해야 하므로 신뢰성이 보장됩니다.

구현 예시

여러 개의 서버 인스턴스가 존재하는 분산 시스템에서 process_order라는 API 요청이 들어오면 이를 동시에 처리하지 않도록 RedLock을 사용하는 방법을 구체적인 예시와 함께 설명합니다.

1. Redis 서버 설정

먼저, 여러 개의 Redis 서버를 설정합니다. 여기서는 5개의 Redis 서버를 사용한다고 가정합니다.

redis_servers = [
    {'host': 'localhost', 'port': 6379},
    {'host': 'localhost', 'port': 6380},
    {'host': 'localhost', 'port': 6381},
    {'host': 'localhost', 'port': 6382},
    {'host': 'localhost', 'port': 6383},
]

2. RedLock 클래스 정의

잠금 획득과 해제를 담당하는 RedLock 클래스를 정의합니다.

import redis
import time
import uuid

class RedLock:
    def __init__(self, redis_servers):
        self.servers = [redis.StrictRedis(host=s['host'], port=s['port']) for s in redis_servers]
        self.quorum = len(self.servers) // 2 + 1

    def acquire_lock(self, resource, ttl):
        identifier = str(uuid.uuid4())
        end = time.time() + ttl / 1000.0

        while time.time() < end:
            n = 0
            for server in self.servers:
                if server.set(resource, identifier, nx=True, px=ttl):
                    n += 1

            if n >= self.quorum:
                return identifier

            time.sleep(0.01)

        return False

    def release_lock(self, resource, identifier):
        for server in self.servers:
            if server.get(resource) == identifier:
                server.delete(resource)

3. API 요청 처리

process_order라는 API 요청을 처리할 때 RedLock을 사용하여 잠금을 걸고 해제하는 로직을 추가합니다.

lock_manager = RedLock(redis_servers)
resource = 'process_order'
ttl = 10000  # 10 seconds

def process_order():
    # 잠금 획득
    lock_identifier = lock_manager.acquire_lock(resource, ttl)
    if lock_identifier:
        try:
            print(f'Lock acquired: {lock_identifier}')
            # 여기서 실제로 API 요청을 처리합니다.
            print('Processing order...')
            time.sleep(5)  # 예시로 5초간 처리한다고 가정
        finally:
            # 잠금 해제
            lock_manager.release_lock(resource, lock_identifier)
            print('Lock released')
    else:
        print('Failed to acquire lock')

실행 예시

여러 개의 서버 인스턴스가 process_order API를 호출한다고 가정해봅시다. 각 서버 인스턴스는 RedLock을 사용하여 잠금을 시도합니다. 잠금을 성공적으로 획득한 인스턴스만이 API 요청을 처리하고, 다른 인스턴스는 잠금이 해제될 때까지 대기합니다.

# 서버 인스턴스 1에서 process_order 호출
process_order()

# 서버 인스턴스 2에서 process_order 호출 (서버 인스턴스 1이 잠금을 보유 중인 동안 호출하면 실패)
process_order()

실행 결과 예시

  1. 첫 번째 서버 인스턴스가 잠금을 획득하고 API 요청을 처리합니다.

    Lock acquired: 123e4567-e89b-12d3-a456-426614174000
    Processing order...
    Lock released
  2. 두 번째 서버 인스턴스가 잠금을 획득하지 못하고 대기하거나 실패 메시지를 출력합니다.

    Failed to acquire lock

이와 같이 RedLock을 사용하면 분산 환경에서 동일한 리소스에 대한 동시 접근을 효율적으로 제어할 수 있습니다.

profile
https://kktrkkt.github.io/

0개의 댓글