RedLock은 Redis 기반의 분산 잠금 메커니즘으로, 분산 환경에서 동일한 리소스에 대해 동시에 접근하는 여러 프로세스나 스레드를 제어하기 위해 사용됩니다. 이는 특히 여러 인스턴스에서 실행되는 애플리케이션들이 공유 리소스에 대한 잠금을 효율적으로 관리할 수 있도록 돕습니다.
잠금 획득:
잠금 유지:
잠금 해제:
여러 개의 서버 인스턴스가 존재하는 분산 시스템에서 process_order라는 API 요청이 들어오면 이를 동시에 처리하지 않도록 RedLock을 사용하는 방법을 구체적인 예시와 함께 설명합니다.
먼저, 여러 개의 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},
]
잠금 획득과 해제를 담당하는 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)
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()
첫 번째 서버 인스턴스가 잠금을 획득하고 API 요청을 처리합니다.
Lock acquired: 123e4567-e89b-12d3-a456-426614174000
Processing order...
Lock released
두 번째 서버 인스턴스가 잠금을 획득하지 못하고 대기하거나 실패 메시지를 출력합니다.
Failed to acquire lock
이와 같이 RedLock을 사용하면 분산 환경에서 동일한 리소스에 대한 동시 접근을 효율적으로 제어할 수 있습니다.