[VoiceLink] 분산 1:1 매칭 동시성 제어: Redis Lua Script 원자적 선점과 Stale 세션 자동 격리로 이중 매칭 0건 달성하기

VoiceLink 분산 매칭 동시성 제어 구조 대표 이미지

실시간 1:1 음성 통화 플랫폼(VoiceLink)에서 수백 명의 동시 접속자가 매칭 큐에 진입할 때 가장 치명적인 장애는 동일한 사용자가 서로 다른 2개의 통화 세션에 동시에 배정되는 이중 매칭(Double Booking) 경합 상태(Race Condition)입니다.

다중 분산 애플리케이션 인스턴스 환경에서 일반적인 ZRANGEZREM 방식의 2-Step 조회는 동시성 트래픽이 몰릴 때 두 인스턴스가 동일한 대기자를 읽어 각자 다른 상대와 매칭을 체결해 버리는 치명적인 데이터 정합성 결함을 유발합니다. VoiceLink에서는 Redis Single-Threaded Lua Script의 원자적 연산과 TTL Presence Key를 결합한 Stale 세션 능동 격리 아키텍처를 구축하여 동시성 경합 상황에서도 이중 매칭을 0건으로 완전 방어했습니다.

더 읽기

Redis Cache Stampede 현상 극복기: 캐시 적용하면 DB 부하 끝 아닌가?

Redis Cache Stampede 현상 극복기: 캐시 적용하면 DB 부하 끝 아닌가? 핵심 주제 표지

캐시 적용하면 DB 부하 끝 아닌가?   서론   Redis 캐시를 도입할 때, 이런 생각이 들었다.   “조회 성능? 인기 데이터 레디스에 캐싱하고 만료시간(TTL) 걸어두면 DB 부하 끝 아닌가?”   그렇게 생각하고 메인 페이지…

JPA N+1 문제와 Fetch Join 실무 고찰: lazy loading이면 다 해결되나?

JPA N+1 문제와 Fetch Join 실무 고찰: lazy loading이면 다 해결되나? 핵심 주제 표지

lazy loading이면 다 해결되나?   서론   JPA를 공부하며 연관관계를 설정할 때, 이런 생각이 들었다.   “N+1 문제? 그냥 모든 연관관계 FetchType.LAZY로 걸어두면 되는 거 아닌가?”   그렇게 생각하고 엔티티마다 LAZY를 설정하고 테스트를 통과시켰다.…

PostgreSQL FOR UPDATE SKIP LOCKED: DB 락 경합 없이 고성능 작업 큐 구축하기

PostgreSQL FOR UPDATE SKIP LOCKED: DB 락 경합 없이 고성능 작업 큐 구축하기 핵심 주제 표지

비동기 백엔드 작업 큐(Worker Queue)를 구축할 때, 추가적인 외부 분산 브로커 인프라를 운영하기에는 리소스 부담이 크고 단일 트랜잭션 내에서 즉각적인 작업 상태 전환이 필요한 경우가 많습니다. “작업 큐? 그냥 DB 테이블에 STATUS 컬럼 두고…

Spring Boot와 Redisson 분산 락: @Transactional만 걸면 되는 거 아니야?

Spring Boot와 Redisson 분산 락: @Transactional만 걸면 되는 거 아니야? 핵심 주제 표지

@Transactional만 걸면 되는 거 아니야?   서론   동시성 제어를 처음 접했을 때, 이런 생각이 들었다.   “동시성 제어? 그냥 @Transactional 달고 DB에서 Select … FOR UPDATE 처리하면 되는 거 아닌가?”   그렇게 생각하고…