전체 글 180

Loopers, Loop:Pak VOP.3 백엔드 후기

커리큘럼, FAQ, 무조건 좋아요~ 같은 뻔한 내용은 홈페이지나 다른 후기를 참고하자. https://www.loopers.im/education 교육 과정 | Loop:PakLoop:Pak 부트캠프 교육 과정 상세 정보. NextNode Backend Edition을 포함한 전문 개발자 양성 커리큘럼과 현업 멘토링 프로그램을 만나보세요.www.loopers.im 이 글에서는 공식 홈페이지에 없는, 실제 경험자만 답해줄 수 있는 얘기를 해보려고 한다.들어가기 앞서, 내 글에서 사짜 냄새가 좀 날 수도 있는데 신뢰도를 올리기 위해 인증을 먼저 하겠다. 나름 열심히 해서 S등급도 받았으니, 루프팩에 대한 궁금한게 있는 사람들은 잘 읽어보길 바란다. 1. 당신이 달성할 수 있는 것아마 루프팩을 ..

회고록 2026.04.26

[WIL] - Round10. 집계 단위 설계와 Read Model 안전 갱신

배치 집계 시스템은 보통 두 가지 문제에서 깨진다.하나는 원천 데이터의 단위가 처음부터 잘못 설계되어 있는 경우고,다른 하나는 집계 결과를 조회 전용 모델로 교체하는 과정에서 장애 격리가 안 되는 경우다.이 두 축을 분리해서 이해하면 배치 설계의 판단 기준이 훨씬 명확해진다.1. 집계 원천의 단위 설계1-1. 누적 스냅샷은 기간 분리 집계에 답을 낼 수 없다원천 데이터를 단일 레코드에 누적하는 구조는 가장 단순한 방식이다.하나의 식별자에 대한 전체 합계를 한 레코드에 계속 더해 나간다.이 구조에서는 '전체까지의 합산'은 바로 읽힌다.그러나 '이번 주에만 해당하는 수치'를 꺼내는 순간 답이 없어진다.누적값에서 특정 기간의 기여분을 분리하려면, 과거 특정 시점의 스냅샷과 현재 값을 비교해야 한다.그 스냅샷이..

[WIL] - Round9. Redis ZSET 랭킹과 재계산 가능한 집계 구조

랭킹 시스템의 핵심은 Redis ZSET 자체보다 '언제부터 언제까지의 점수인가', '여러 행동을 하나의 점수로 어떻게 합칠 것인가', '저장소나 점수 모델이 바뀌어도 다시 만들 수 있는가'에 있다.Redis ZSET은 정렬된 결과를 빠르게 제공하는 데 적합하다.하지만 랭킹의 기준 원본까지 Redis에만 두면, 시간이 지나거나 점수 모델이 바뀌었을 때 과거 랭킹을 다시 만들기 어렵다.1. 집계 단위랭킹은 먼저 기간을 정해야 한다.점수 계산식이나 조회 API보다 먼저 정해야 하는 것은 이 점수가 어느 시간 구간의 인기도를 의미하는가다.1-1. 누적 랭킹은 오래된 인기를 과하게 보존한다하나의 랭킹판에 점수를 계속 누적하면 처음에는 단순하다.하지만 시간이 지날수록 오래전부터 점수를 쌓은 대상이 계속 유리해진다..

[Ranking] 당신은 지금 점수식에 얽매여 있다

TL;DR랭킹에서 중요한 것은 정답 같은 점수식을 찾는 일이 아니다.점수식은 언제든 바뀌는 정책이고, 개발자가 설계해야 하는 것은 그 정책이 바뀌어도 버티는 구조다. 랭킹 시스템을 만들 때 가장 먼저 떠올리는 것은 보통 점수식이다.조회는 몇 점으로 볼지, 좋아요는 얼마나 반영할지, 주문은 몇 배로 가중할지부터 고민하게 된다. 나도 처음엔 그랬다. 그런데 구현이 깊어질수록 결론은 조금 달라졌다.점수식이 중요하지 않다는 뜻은 아니다. 다만 점수식은 대부분 정책이고, 정책은 생각보다 쉽게 바뀐다. 오늘은 종합 인기도를 보고 싶다가도, 내일은 전환율이 높은 상품을 더 끌어올리고 싶을 수 있다.어제는 주문을 가장 강하게 봤지만, 특정 캠페인 기간에는 좋아요나 조회 반응을 더 보고 싶을 수도 있다. 그렇다면 개발..

[WIL] - Round8. 대기열 유입 제어, 순서 보장, 상태 전이

대기열은 트래픽을 줄이기 위한 도구가 아니라, 시스템이 감당할 수 있는 속도로 요청을 흘려보내는 도구다.그래서 대기열은 기능이 아니라 '유입 제어', '순서 보장', '상태 전이'의 세 축으로 보는 편이 안전하다.1. 유입 제어유입 제어의 핵심은 시스템이 감당할 수 있는 처리량을 먼저 정하고, 그 속도에 맞춰 요청을 흘려보내는 일이다.1-1. 처리량 상한은 병목 자원에서 정한다유입 제어를 설계할 때 가장 먼저 할 일은 아래다.시스템에서 가장 먼저 한계에 도달하는 자원이 무엇인가그 자원의 이론적 최대 처리량은 얼마인가안전 마진을 빼면 실제 목표 처리량은 얼마인가보통 병목은 커넥션 풀, 외부 API 호출, 디스크 쓰기 중 하나다.예시 코드// 병목: 커넥션 풀 50개, 건당 처리 시간 200msint max..

[Waiting Queue] 당신의 대기열은 안녕하신가?

TL;DR대기열에서는 실시간 순번, 부하 분산, 중복 진입 등의 문제가 발생한다. 각각의 문제를 해결하기 위한 보편적인 방법으로 SSE, Jitter, NX와 같은 방법이 있지만, 데이터 특성과 흐름을 생각해보면 예상외의 결과가 발생한다.- 순번은 1:N fan-out이라 SSE보다 Polling이 자연스럽다.- 대기열을 통과한 유저를 거부하는 Jitter/Rate Limit은 대기열의 약속을 깨뜨린다.- ZADD NX를 끄면 코드 한 줄 없이 트래픽을 1/5로 줄일 수 있다.- 순번 정밀도를 한 단계 낮추면 Redis 장애에도 서비스가 유지된다.즉, '좁은 범위의 특정 문제'만을 바라보지 말고, 전체적인 서비스의 흐름과 유저 행동을 먼저 봐야 한다. 티켓팅을 해본적이 있는가?아주 한정적인 짧은 시간동..

[WIL] - Round7 (3/3). 선착순 쿠폰 발급

수량 제한이 있는 자원을 대량 요청에서 정확하게 분배하는 문제는 동시성 제어의 대표적인 시나리오다. 선착순 쿠폰 발급은 이 문제를 Kafka 파이프라인 위에서 해결하는 사례다.동시성 제어 방식 선택즉시 판정 vs 비동기 처리수량 제한이 있는 발급에서 동시성을 제어하는 방식은 크게 두 가지로 나뉜다.즉시 판정 방식은 아래 특성을 가진다.요청 시점에 발급 가능 여부를 즉시 응답한다Redis 같은 인메모리 저장소로 원자적 카운터를 구현한다사용자 경험이 좋다. 요청 즉시 성공/실패를 알 수 있다동시성 제어가 복잡하다. 분산 환경에서 원자적 연산을 보장해야 한다적합한 상황: 재고 차감처럼 즉시 결과가 필요한 경우비동기 처리 방식은 아래 특성을 가진다.요청 접수만 보장하고, 실제 처리는 나중에 한다메시지 큐의 순차..

[WIL] - Round7 (2/3). Kafka 파이프라인

in-process 이벤트는 같은 애플리케이션 내에서만 동작한다. 시스템 간 이벤트 전파가 필요하면 메시지 브로커를 도입해야 한다. 이때 가장 큰 문제는 '도메인 변경은 저장됐는데 이벤트 발행은 실패하는 상황'과 '같은 이벤트가 두 번 처리되는 상황'이다.발행 보장 — Transactional Outbox 패턴문제 구조도메인 변경과 이벤트 발행이 별개의 시스템에서 이루어지면 원자성을 보장할 수 없다. 데이터베이스에 주문은 저장됐는데 Kafka 발행이 실패하면 소비자는 주문이 생성된 사실을 알 수 없다.두 가지 접근이 가능하다.이벤트를 먼저 발행하고 도메인 변경을 나중에 한다 → 발행은 됐는데 저장이 실패하면 존재하지 않는 주문에 대한 이벤트가 돌아다닌다도메인 변경을 먼저 하고 이벤트를 나중에 발행한다 →..

[WIL] - Round7 (1/3). 이벤트 분리 기준

[WIL] - Round7 (1/3). 이벤트 분리 기준이벤트 기반 아키텍처는 세 축으로 나눠 정리한다.1편 — 이벤트 분리 기준: 어떤 로직을 이벤트로 분리할지, 리스너와 트랜잭션 경계를 어떻게 설계할지2편 — Kafka 파이프라인: Outbox 패턴으로 발행을 보장하고, Consumer에서 멱등 처리·순서 보장·배치·DLQ·2단 구조를 구현하는 방법 (https://kdh0518.tistory.com/186)3편 — 선착순 쿠폰 발급: 비동기 처리 기반 동시성 제어, 단일 파티션 순차 처리, polling 결과 확인 구조 (https://kdh0518.tistory.com/187)단일 트랜잭션에 모든 로직을 묶는 구조는 단순하지만, 부수효과 하나의 실패가 핵심 로직까지 롤백시키는 문제를 만든다. 이벤..

[Event] 머리 박으면서 배운 '이벤트'에 대한 4가지 깨달음

TL;DR이벤트는 silver bullet이 아니다.결합도를 낮추는 데는 분명 유용하지만, 경계를 자동으로 지켜주지도 않고, 정합성을 저절로 보장해주지도 않는다. 결국 중요한 것은 이벤트를 얼마나 많이 썼는지가 아니라, 어떤 기준으로 남기고 버릴지를 정하는 일이다. 나는 이벤트를 접하기 전, 아키텍처에 대해 많은 고민을 해왔었다.BC 간 강결합을 줄이고 싶었고, 주요 비즈니스 로직과 부가 로직을 분리하고 싶었다. 장애가 한 곳에서 나더라도 다른 곳으로 쉽게 번지지 않는 구조를 만들고 싶기도 했다. 그리고 Event를 알고 난 뒤에는 이벤트가 모든 문제를 해결해줄 수 있는 것 처럼 보였고, 적극적으로 사용하려했다. 그런데 정말로 이벤트가 이 모든 문제들을 해결해주었을까? 물론 언급했던 문제들을 말끔하게 ..