Redis 4

Redis 키 설계 전략이 중요한 이유 시간의 양자화와 롱테일

TL;DR: 랭킹 ZSET의 키 하나가 "무엇을 측정하는가"를 결정한다. 누적 키는 롱테일을 만들고, 일간 키는 콜드 스타트를 만든다. 키를 자르는 순간 정보가 손실되고, 그 손실을 carry-over와 fallback으로 메운다. 키 설계는 네이밍이 아니라 데이터 모델링이다.랭킹 키 하나의 무게이커머스 인기 상품 랭킹을 만들면서 가장 먼저 마주친 질문은 이거였다.ranking:{productId} → score 이 ZSET의 키 이름을 어떻게 지을 것인가.처음에는 네이밍 문제라고 생각했다. ranking:all이든 ranking:daily든, 어차피 ZINCRBY로 점수를 올리는 건 같으니까. 키 이름은 규칙만 맞추면 되는 거 아닌가?이 생각이 틀렸다. 키 이름이 결정하는 건 "어디에 저장하는가"가 아..

운영 2026.04.10

토큰 TTL 하나로는 부족하다. Access, Activity, Hard Limit 3계층 설계

TTL 180초의 딜레마대기열을 통과한 사용자에게 토큰을 발급할 때, TTL을 몇 초로 설정할지가 생각보다 어려운 문제였다.처음에는 단순하게 180초(3분)로 잡았다. "결제까지 3분이면 되지 않나?" 그런데 실제 이커머스 사용자의 행동 패턴을 떠올려보니, 이게 단순하지 않았다.TTL = 60초? → 쿠폰을 고르다가 90초째에 토큰이 만료. 처음부터 다시 대기열.TTL = 300초? → 결제를 포기하고 탭을 닫은 사용자가 5분 동안 자리를 차지.TTL = 180초? → 둘 다 완벽히 해결하지 못하는 절충안. 핵심 테제: 단일 TTL은 "활발한 사용자"와 "이탈한 사용자"를 구분할 수 없다. 이 두 가지를 동시에 다루려면 TTL을 계층화해야 한다.이커머스 사용자 행동 스펙트럼토큰 TTL을 설계하려면, 먼..

대기열 배치 크기를 방정식으로 산정하기까지

대기열 스케줄러의 배치 크기를 "감"이 아닌 "방정식"으로 산정하기까지TL;DR대기열 스케줄러가 1초마다 몇 명을 활성화할지를 정하는 건 감이 아니라 역산이다. DB 커넥션 풀에서 출발해서 TPS를 구하고, 안전 마진을 적용하면 "왜 이 값인지"를 설명할 수 있는 숫자가 나온다. 그리고 이 숫자가 방정식에서 나왔다는 사실이, 설계 판단을 설명 가능하게 만드는 핵심 근거가 된다.대기열이 보호하는 것쇼핑몰에서 블랙프라이데이를 한다고 가정해보자. 평소에 초당 100명 정도가 접속하던 사이트에 갑자기 10만 명이 동시에 몰린다. 전원이 "주문하기" 버튼을 누른다.서버가 요청을 받는 것 자체는 가능하다. Tomcat은 수천 개의 동시 연결을 처리할 수 있다. 문제는 주문을 처리하는 과정에서 생긴다. 주문을 처리하..

운영 2026.04.03

캐시 삭제했는데 stale data가 살아 돌아왔다

afterCommit DELETE면 충분하지 않나? — Cache-Aside 레이스 컨디션을 발견하고, 근본 원인을 찾기까지 TL;DRCache-Aside + afterCommit DELETE면 캐시 무효화는 끝이라고 생각했습니다. 그런데 "DB 읽기와 캐시 SET 사이의 시간 간격"이라는 구조적 허점을 발견했고, 처음에는 캐시 레이어에서 사후 패치하려 했습니다. 한 발 물러서 보니, 이 문제의 근본 원인은 캐시가 아니라 DB 쓰기 프로세스의 동시성 제어였습니다. 쓰기 쪽을 비관적 락과 원자적 UPDATE로 잠근 뒤에는, afterCommit DELETE + TTL 안전망만으로 충분했습니다.캐시가 필요한 이유: 속도가 아니라 DB 보호인덱스 최적화 + Cursor 페이지네이션까지 적용하고 나니, 상품 목..

데이터베이스 2026.03.12