플랫폼 스레드와 가상 스레드 I/O 지연 비교

자바 플랫폼 vs 가상 스레드 - 언제, 왜 성능 차이가 나는가?

요약 가상 스레드는 CPU성능을 높이는 기술이 아닌, 대기 중인 스레드의 점유 비용을 낮추는 동시성 모델이다. 스파이크 트래픽 환경에서 I/O-bound 작업은 가상 스레드로 인해 큐 대기와 p95 지연이 크게 줄어들었다. CPU-bound 작업에서는 스레드 모델 변경만으로 유의미한 성능 차이가 나타나지 않았다. 가상 스레드는 병목을 제거하기보다, 병목의 위치를 스레드에서 다른 계층(DB, 외부 API 등)으로 이동시킨다. 따라서 가상 스레드 도입은 성능 최적화 문제가 아니라, 백프레셔/타임아웃/제한 등의 설계를 포함한 시스템 설계 문제로 여겨야한다. 문제 ...

January 11, 2026 · 6 min · 1180 words · Gukin Han
쿼리 수정 전후의 실행시간 비교 그래프

상관 서브쿼리로 인한 읽기 병목 개선

요약 문제 운영 환경에서 조회 API 응답 지연(1초 이상) 이슈 발생 상관 서브쿼리로 인한 N+1 패턴이 DB 레벨에서 발생 과정 실행 계획 분석을 통해 Nested Loop 반복 실행과 옵티마이저 통계 오류를 확인 상관 서브쿼리를 CTE + Hash Join 구조로 리팩토링 성과 서브쿼리 실행 92회에서 1회로 감소 총 실행 비용 246.0에서 40.6로 감소 (약 83% 개선, 6배 성능 향상) 운영 데이터 기준으로 실행 계획 변화와 성능 개선을 수치로 검증 문제 배경 운영 중인 서비스에서 특정 테넌트 기준 조회 API의 응답지연이 보고되었다. 슬로우 쿼리 분석 결과, 직원을 그룹화하는 테이블의 조회 쿼리 내부에 상관 서브쿼리(Correleated Subquery)가 포함되어있었다. 그 영향으로 메인 쿼리 결과 행 수만큼 서브쿼리가 반복 실행되는 문제가 발생했다. ...

December 13, 2025 · 6 min · 1243 words · Gukin Han
REDIS_SCHED 모드 아키텍처

트랜잭션에서 이벤트로 - Sync / Async / Redis 성능 비교와 TTV 분석

문제 @Transactional public void like(String loginId, Long productId) { // 1. 유저 조회 User user = userService.getByLoginId(loginId); // 2. 상품-좋아요 Insert boolean isInserted = productLikeRepository .insertIgnoreDuplicateKey(user.getUserId(), productId); if (!isInserted) return; // 3. 좋아요 수 집계 Update productRepository.incrementLikeCount(productId); } 좋아요 기능에서 처음엔 모든 로직을 하나의 트랜잭션 안에서 동기적(Sync)으로 처리 안정적이지만 트랜잭션 크기가 커지고, 상품 핫키에 경합으로 인한 병목이 발생 그래서, 이벤트 기반 설계를 통해 결합도를 낮추고(loosely coupled), 책임을 분리하려는 시도 Github PR : https://github.com/gukin-han/commercial-service/pull/7 ...

August 29, 2025 · 4 min · 743 words · Gukin Han
OFFSET 임계점에서 플랜 전환이 발생하는 그래프

정규화부터 캐싱까지 - 상품 목록 페이지네이션 최적화 과정

요약 정규화 쿼리(집계 + 정렬) → 풀스캔 + filesort로 ~17초 소요. 역정규화 + 정렬 포함 인덱스 → ~227ms (약 76배 향상). OFFSET 페이지네이션 → 인덱스 순차 스캔 시작 → 임계점에서 Table Scan + Filesort로 전환 → 이후 응답시간 급등. 전환 전 일정한 속도는 InnoDB 버퍼 풀/캐시 히트율 덕분. Keyset(Seek) 페이지네이션 → 깊은 페이지에서도 일정 성능 (421ms → 31ms, 92.6% 단축). 인덱스 설계는 핫 트래픽 패턴(브랜드 + 인기순/최신순/최저가순)에 맞춘 3개의 복합 인덱스 유지가 가성비 최적. 설계 원칙: 필터 선두 → 정렬키 → tie-breaker(id) 캐시(Cache-Aside) 적용 시 200RPS에서도 DB I/O 부하 없이 ms 단위 응답 가능. 단, TTL·Evict 정책·실시간성 요구사항·정합성 유지·스탬피드 방지 등 고려 필수. 결론: 정규화/역정규화 → 인덱스 설계 → 페이지네이션 전략 → 캐싱이 단계적으로 맞물려 성능을 좌우함. 문제 정의와 가설 웹 서비스에서는 쓰기 보다 읽기 트래픽이 압도적으로 많다는 글을 읽거나 실제로 경험해봤을 것이다. ...

August 15, 2025 · 16 min · 3283 words · Gukin Han