Lettuce 분산 락의 오해와 진실 (feat. RedisLockRegistry)
·
Redis
이전 글인 "좋아요 기능으로 알아보는 비관적 락"에서 이어지는 글이다. "Lettuce는 SpinLock만 지원한다"는 잘못된 정보를 바로잡고, Spring RedisLockRegistry의 PubSub Lock 설정으로 Redisson 없이도 효율적인 분산 락을 구현하는 방법을 소개한다. Lettuce에 대한 오해, 당신도 믿고 있는가?구글에 "Redis 분산 락"를 검색하면 수십 개의 블로그가 같은 내용을 반복한다:"Lettuce는 SpinLock 방식이라 Redis에 부하를 준다""그래서 Redisson을 써야 한다""Lettuce로는 PubSub 방식을 구현할 수 없다"이런 주장들이 마치 정설처럼 반복되고 있다. 그리고 이러한 논리를 바탕으로 Redisson 구현체를 추천한다. 하지만, 이는 ..
좋아요 기능으로 알아보는 비관적 락
·
Spring
이 글에서는 좋아요 기능을 구현하면서 발생하는 동시성 문제를 DB 락으로 해결하는 과정을 다룬다. 비관적 락의 동작 원리와 함께, 넥스트 키 락(Next-Key Lock)으로 인한 성능 저하 문제까지 살펴본다. 좋아요 기능 요구사항 정리다중 서버 환경에서 서버 간 동시성 제어 필요기능 명세1) 좋아요 추가사용자는 리뷰에 좋아요를 누를 수 있다한 사용자는 하나의 리뷰에 한 번만 좋아요 가능 (중복 방지)동시다발적인 요청도 안전하게 처리해야 한다2) 좋아요 취소물리적 삭제가 아닌 논리적 삭제(Soft Delete) 방식 사용취소 후 다시 좋아요를 누를 수 있다3) 좋아요 조회좋아요를 누르지 않은 상태: 비활성화 표시좋아요를 누른 상태: 활성화 표시좋아요를 취소한 상태: 비활성화 표시 엔티티 설계리뷰에 좋아요..
처음부터 다시 배우는 Java 동시성 제어
·
Java
이 글에서는 synchronized 키워드의 JVM 모니터 락이 실제로 어떻게 동작하는지 살펴보고, ReentrantLock이 제공하는 동시성 처리 기능을 알아본 뒤, 동시성 프로그래밍을 할 때 발생할 수 있는 생산자-소비자 문제를 해결해본다. 그리고 사용자별 키 값을 활용한 락 분리 전략으로 성능을 개선하는 방법을 다룰 예정이다. synchronized만으로 충분할까'synchronized를 쓰면 동시성 문제가 해결된다'라고만 이해하고 있을 수도 있다. 실제로 동시성 문제를 해결하기 위해 단순히 코드 블록에 synchronized만 붙이면 문제는 해결되지만 성능이 급격히 떨어지는 경우를 자주 볼 수 있다. 예를 들어, 모든 사용자의 포인트 처리가 하나의 공유된 락으로 처리하면, 사용자 A의 포인트 적립..
외부 API가 서비스를 마비시킬 뻔한 이야기: 가상스레드 도입기
·
Spring
이 글은 Network I/O로 인한 스레드 블로킹 문제를 진단하고, JDK 21의 가상 스레드(Virtual Thread)를 활용해 근본적인 해결책을 찾아가는 과정을 담고 있다. 단순히 문제를 해결하는 것을 넘어, 가상 스레드 도입 과정에서 마주친 Thread Pinning과 Overwhelming 같은 예상치 못한 도전들과 그 해결책까지 상세히 다룬다. 스레드 풀이 왜 고갈되었을까?월요일 오전 10시, 커피를 마시며 한 주를 시작하려는 순간 슬랙에서 지연시간 알림이 오기 시작한다.급하게 모니터링 대시보드를 확인해본다.잔여 스레드 수: 0왜 스레드 풀이 고갈되었을까?마케팅 팀과 협업해 만든 서버 사이드 이벤트 추적(Meta Conversion API 연동)의 영향이었다.데이터를 수집하기 위해 사용자의..
UPDATE 한 줄로 끝내는 동시성 문제
·
Spring
선착순 이벤트 시스템을 설계한다고 가정해보자. 요구사항은 아래와 같다.요구사항:매일 제한된 수량의 무료 체험 제공선착순 N명 정확히 선정1명만 1개만 주문 가능동시 요청 처리 필수일별 재고 수량 기록 필요단일 데이터베이스 시스템, 여러 개의 서버 컨테이너가장 중요한 것은 동시성 제어이다.100개의 재고가 있을 때 동시에 1,000명이 요청하면 어떻게 정확히 100명에게만 제공할 수 있을까? 이때 일반적으로 제시되는 해결책들은 아래와 같다.비관적 락(SELECT FOR UPDATE)낙관적 락(JPA @Version)데이터베이스 네임드 락Redis 분산 락하지만 단일 데이터베이스 환경에서 분산 락은 오버엔지니어링일 수 있고, 낙관적 락은 재시도 로직이 복잡하며, 비관적 락은 대기 시간이 길어질 수 있다.이 ..
분산 캐시 동기화 문제, Redis Pub/Sub으로 해결하기
·
Redis
너무 느린 외부 API우리 팀은 외부 시스템과의 연동 프로젝트를 진행하게 되었다. 요구사항은 간단해 보였다. "해당 일자에 주문이 가능한지 외부 API를 통해 확인할 수 있어야 한다." 하지만 실제로 구현해보니, 고객에게 정확한 정보를 전달하기 위해선 한 화면에서 40~60건의 날짜별 배송 계획을 한 번에 조회해야 했다. 병렬 처리를 적용했음에도 불구하고 API 응답 시간은 500ms에서 1초, 심지어 요청이 여러 번 겹치면 그 이상 소요되었다. 연동사에서 제공해준 bulk API를 사용했는데 오히려 더 느려졌다.사용자가 주문 가능 일자를 확인할 때마다 1초 이상을 기다려야 한다니, 이건 명백히 사용성에 심각한 문제였다. 우리는 데이터가 일자 단위로 예측 가능하고 실시간이 덜 중요하다는 점을 주목했다.캐..