pile·
백엔드·쏘카쏘카·

쏘카의 대규모 인증토큰 트래픽 대응 : 개발기

쏘카 어카운트팀이 성수기 대규모 인증토큰 트래픽 대응을 위해 실제 구현한 기술 내용을 상세히 소개한다. LazyConnectionDataSourceProxy를 활용한 Master/Slave DB 분리, 만료 토큰 이관으로 인증토큰 테이블 86% 경량화, Redis Look Aside + Write Around 캐시 전략까지 각 Phase별 구현 결과와 효과를 직접 다룬다.

핵심 포인트
  • LazyConnectionDataSourceProxy로 DB 커넥션 획득 시점을 쿼리 실행 시점으로 지연 — Read/Write 라우팅 분리 가능
  • Master DB는 토큰 발급/쓰기, Slave DB는 토큰 검증/읽기로 분리해 Master 과부하 해소
  • 인증토큰 테이블에서 만료 토큰 이관: 2,800만 건 → 200만 건으로 86% 슬림화
  • Redis Look Aside 패턴 적용: 캐시 히트 시 DB 조회 skip — 인증 검증 요청의 DB 부하 대폭 감소
  • Write Around 전략으로 쓰기 시 캐시 오염 없이 실제 조회 시점에만 캐시 세팅 — 메모리 효율 확보
  • 인증 전용 서비스 분리 덕에 캐시 전략 변경이 단 한 곳에서 가능 — MSA 독립성의 실질적 효과
상세 정리
  • 문제: 모든 서비스가 단일 Master DB 인증토큰 테이블에 직접 접근 — 트래픽 증가 시 전체 DB 과부하
  • Phase1: 쏘카 메인 서비스에서 Spring Boot + Kotlin 기반 인증토큰 전용 서비스 분리, HTTP 동기 방식으로 호출 구조 변경
  • LazyConnectionDataSourceProxy 선택 이유: Spring 기본 방식은 트랜잭션 시작 시 커넥션을 가져와 Read/Write 구분 불가 — 실행 시점으로 지연시켜 분기 가능하게 함
  • Phase2-1/2-2 완료 후 인증토큰 테이블 분석: 만료된 토큰 포함 2,800만 건 누적 — 실사용 데이터는 200만 건 수준
  • 만료 토큰 별도 아카이브 테이블로 이관 후 2,600만 건 제거 → 인덱스 크기 및 테이블 스캔 범위 대폭 감소
  • Phase3 Redis 도입: Look Aside 패턴으로 캐시 미스 시에만 DB 조회, 이후 캐시에 세팅
  • Write Around 채택 이유: 토큰 발급 즉시 캐싱하면 실제로 다시 조회되지 않을 데이터까지 메모리 낭비 발생
  • 캐시 TTL은 인증토큰 만료 시간 기반으로 설정 — stale 데이터 제공 위험 최소화
  • 결과: 성수기 실트래픽에서 Master DB 부하 정상 범위 유지, 캐시 적용 후 DB 조회 쿼리 수 대폭 감소
  • 데이터 최적화(만료 토큰 분리)와 캐시 전략이 시너지 — 캐시 히트율 향상 및 미스 시 조회 대상 레코드 수 감소
  • 단계별 배포 후 성능 테스트로 각 Phase 효과를 수치로 검증 — 점진적 개선의 가시적 성과 확인
왜 읽나Spring Boot + Kotlin 환경에서 LazyConnectionDataSourceProxy 기반 Read/Write 분리와 Redis 캐시 조합으로 실제 인증 서비스 DB 부하를 해결한 구현 경험을 담았다. 만료 데이터 누적으로 인한 숨겨진 성능 저하와 Write Around 전략 선택 이유까지 상세히 다뤄, MSA 전환이나 인증 서비스 분리를 고민하는 팀에 바로 적용 가능한 실전 레퍼런스다.
쏘카
쏘카 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 백엔드·github-engGitHub Engineering·

    조기 종료를 없애야 벡터화된다 — 메모리 속도 소스 코드 케이스 폴딩

    GitHub의 코드 검색 엔진 Blackbird는 480TB 이상의 소스 코드를 인덱싱하기 전 모든 바이트에 case folding을 적용한다. 이 글은 Rust로 구현한 case folding을 메모리 대역폭 한계(45+ GiB/s)까지 끌어올린 두 가지 반직관적 최적화를 상세히 다룬다. 핵심은 루프 조기 종료(break) 제거로 LLVM 벡터화를 유도하고, UTF-8을 디코딩하지 않고 바이트 공간 산술만으로 fold를 수행하는 것이다.

    #rust#unicode#simd+2