본문 바로가기

분산락과 캐싱으로 트래픽 대응 (1)

@정소민fan2026. 1. 1. 19:44

서버가 여러 대인 환경이나 MSA 구조에서는 단일 서버에서의 동기화 방식만으로는 부족하다. 여러 서비스에 걸쳐 데이터의 일관성을 유지해야 하는 '분산 락'과, 시스템 성능을 비약적으로 끌어올리는 '캐싱' 전략의 개념을 알아보자


1. 분산 락: 여러 서버 사이의 트랜잭션

분산 락은 여러 서비스나 인스턴스가 하나의 자원을 공유할 때, 데이터가 꼬이지 않도록 제어하는 기술이다. 특히 각각 다른 DB를 사용하는 MSA 환경에서 하나의 트랜잭션처럼 묶인 로직을 처리할 때 필수적이다.

가장 대중적인 도구는 Redis다. 키-값 기반의 원자성을 이용해 DB에 직접 락을 거는 것보다 부하를 훨씬 줄일 수 있다.

Redis를 활용한 분산 락의 종류

  1. Simple Lock: SETNX(키가 없으면 저장, 있으면 실패) 명령을 사용한다. 락을 획득하지 못하면 즉시 실패 예외를 던진다. 구현은 쉽지만 실패 시 사용자가 바로 에러를 보게 되어 경험이 좋지 않을 수 있다.
  2. Spin Lock: 락 획득에 실패했을 때, 일정 횟수나 시간 동안 계속해서 락 획득을 재시도한다. 지속적인 재시도 때문에 네트워크 비용이 발생하고 Redis에 부하를 줄 수 있다.
  3. Pub/Sub 기반 락 (Redisson 등): 스핀 락의 폴링 방식을 개선한 방식이다. 락 획득에 실패하면 큐에서 기다리는 게 아니라, 락 해제 이벤트를 구독하고 기다린다. 락이 풀리면 신호를 받고 그때 시도하므로 훨씬 효율적이고 원자적 처리가 가능하다.

⚠️ 주의: 락과 트랜잭션의 순서

정합성을 위해 반드시 지켜야 하는 공식이 있다. 락 획득 → 트랜잭션 시작 → 비즈니스 로직 실행 → 트랜잭션 종료(커밋) → 락 해제 이 순서가 뒤섞여서 트랜잭션이 끝나기 전에 락이 먼저 풀려버리면, 커밋되기도 전에 다른 요청이 들어와 데이터를 수정하는 대참사가 발생한다.


2. 캐싱

캐싱은 자주 접근하는 데이터를 미리 가까운 곳에 저장해두는 개념이다. 이는 백엔드뿐만 아니라 컴퓨터공학 전반에서 사용된다.

  • DNS: IP 주소를 기록해둬서 매번 네임 서버에 물어보는 단계를 줄인다.
  • CPU: 느린 디스크 대신 빠른 캐시 메모리에 자주 쓰는 데이터를 둔다.
  • CDN: 이미지나 영상 같은 무거운 정적 컨텐츠를 사용자 근처 서버에 캐싱해 응답 속도를 높인다.

서버 캐싱 전략: 로컬 캐시 vs 분산 캐시

  1. 로컬 캐시 : 애플리케이션 메모리에 직접 저장한다. 속도가 압도적으로 빠르지만, 서버가 여러 대라면 서버마다 캐시 내용이 달라지는 데이터 불일치 문제가 생긴다.
  2. 분산 캐시 : Redis 같은 별도의 캐시 서버를 운영한다. 모든 인스턴스가 같은 데이터를 공유할 수 있어 일관성 문제가 해결되지만, 네트워크 통신 비용과 인프라 운영 비용이 추가된다.

3. 효율적인 캐시 운영을 위한 전략

캐시 메모리는 한정된 자원이므로 무한정 쌓아둘 수 없다.

  • 삭제 알고리즘 (Eviction): 가장 오랫동안 사용되지 않은 데이터를 먼저 지우는 LRU 방식이 대표적이다.
  • 만료 시간 (TTL): 데이터의 유효 기간을 설정해 정합성 문제를 방지한다.
  • 혼합 전략: 정말 자주 쓰이는 데이터는 각 서버의 로컬 캐시에, 그 외의 공통 데이터는 분산 캐시 서버에 두는 다단계 캐싱도 실무에서 자주 쓰인다.

4. 실전 사례: AI 모델 서버와 분산 락

AI 모델을 사용하는 서버는 계산량이 많아 응답에 1초 이상 걸리는 경우가 많다. 여기서 동시성 문제가 발생한다.

상황: 1. 똑같은 요청이 0.1초 간격으로 100개가 들어온다.

2. 첫 번째 요청이 AI 모델에게 계산을 시킨다. (아직 캐싱 전)

3. 두 번째~백 번째 요청도 캐시에 데이터가 없으니 줄줄이 AI 모델에게 똑같은 계산을 요청한다.

4. 서버는 과부하로 뻗어버린다.

해결책: 이럴 때 분산 락을 활용한다. 동일한 요청에 대해 가장 먼저 들어온 작업만 락을 잡고 AI 모델에게 계산을 요청하게 한다. 나머지 요청들은 락이 풀릴 때까지 기다렸다가, 첫 번째 작업이 캐시에 올려둔 결과값을 바로 받아가게 설계하면 서버 부하를 획기적으로 줄일 수 있다.

 

제가 정리해둔 초안은 gemini 블로그 포스터로 재생산한 글입니다

gemini 짱

정소민fan
@정소민fan :: 코딩은 관성이야

코딩은 관성적으로 해야합니다 즐거운 코딩 되세요

목차