Kafka 11

best-effort니까 괜찮지 않나? Kafka 랭킹 파이프라인에 afterCommit 대신 배치 구조를 선택한 이유

best-effort니까 괜찮지 않나? Kafka 랭킹 파이프라인에 afterCommit 대신 배치 구조를 선택한 이유TL;DR:MySQL과 Redis에 동시에 쓰는 dual-write 문제에서, 이 랭킹 시나리오에서는 "가짜 인기를 만드는 것"보다 "인기를 살짝 놓치는 것"이 낫다고 판단해 at-most-once를 선택했다. afterCommit 패턴을 검토했지만 배치 최적화를 막는 구조적 한계를 발견하고, Consumer를 분리해 배치 수집 + Pipeline flush 구조를 설계했다. 정합성 모델은 유지하면서 Redis 네트워크 왕복을 건별 호출에서 배치 2회로 줄인 과정.시작: 기존 파이프라인에 ZINCRBY 적용이전에 Kafka 기반 이벤트 파이프라인을 구축해둔 상태였다. 상품 조회·좋아요·주..

운영/Kafka & MQ 2026.04.10 2

WIL - 7주차 (이론값과 실측값 사이에서 자기 생각을 만드는 법)

이번 주에 새로 배운 것"교과서대로 했는데 안 됐다"가 가장 많이 가르쳐줬다이번 주 루퍼스 과제는 EDA + Kafka Outbox Pipeline이었다. 핵심 트랜잭션과 부가 로직을 분리하고, Outbox Pattern으로 시스템 간 이벤트를 신뢰성 있게 전달하는 것.교과서적 답은 알고 있었다. @TransactionalEventListener(AFTER_COMMIT)으로 TX 커밋 후 이벤트를 발행하면 된다. 그래서 AFTER_COMMIT에서 Outbox에 저장했다. 실행되지 않았다. TransactionTemplate.execute() 반환 시점에 TX가 이미 끝나서, 리스너가 바인딩할 TX 컨텍스트가 없었다.그래서 BEFORE_COMMIT으로 바꿨다. 동작했다. 하지만 "주문 확정 이벤트"가 확정..

스터디/루퍼스 2026.03.29

Outbox Pipeline 성능 테스트 이론값 500건초의 실체를 파헤치다

Outbox Pipeline 성능 테스트 — 이론값 "500건/초"의 실체를 파헤치다PR에 적은 이론값과 실측값의 격차는 부끄러운 게 아니라, 시스템을 이해한 증거다.도입: 왜 성능 테스트를 해야 하는가PR에 이런 수치를 적었다:PR 주장 값발행 지연평균 0.5초 (최대 1초)최대 처리량500건/초Phase 1 + Phase 21초 안에 끝남이 수치를 측정 없이 "이론값"으로만 두면, 멘토가 "진짜야?"라고 물었을 때 답할 수 없다."이론상 이만큼 나와야 합니다"와 "실측해봤더니 이만큼 나왔습니다. 격차의 원인은 이것입니다"는 신뢰도가 완전히 다르다.Outbox Pattern이란 — 왜 필요한가Dual Write Problem주문이 확정되면 Kafka에 이벤트를 발행해야 한다. 가장 자연스러운 구현:@T..

운영/Kafka & MQ 2026.03.29

Kafka Streams로 실시간 집계하면 Consumer보다 뭐가 좋은가

Kafka Streams로 실시간 집계하면 Consumer보다 뭐가 좋은가현재 상품 메트릭을 Consumer에서 건건이 DB UPDATE하고 있다. Kafka Streams의 KTable aggregation으로 바꾸면 뭐가 달라지는가? 실제 코드를 비교하고 트레이드오프를 분석한다.현재 구현: Consumer에서 건건이 DB UPDATE// CatalogMetricsProcessor.java (현재)@Transactionalpublic boolean process(String eventType, String outboxId, String payload) { if (eventHandledRepository.existsByEventId(outboxId)) return false; switch (e..

운영/Kafka & MQ 2026.03.29

멱등성에 DB를 쓰면 느리지 않나? event_handled의 10.9ms가 의미하는 것

"멱등성 체크에 왜 Redis가 아니라 DB를 쓰나요?" 이 질문에 답하려면 10.9ms의 의미와, Redis SET NX가 숨기고 있는 함정을 알아야 한다.왜 멱등성이 필요한가Kafka Consumer는 at-least-once 전달을 기본으로 한다. 네트워크 장애, 리밸런싱, Consumer 재시작 시 같은 메시지를 두 번 이상 받을 수 있다.Broker → Consumer: 메시지 전달Consumer: 처리 완료, ACK 전송 시도네트워크 끊김: ACK 미도달Broker: "ACK 안 왔네, 다시 보내자"Consumer: 같은 메시지를 또 받음멱등성이 없으면:좋아요 수가 이중으로 증가 (비멱등 연산)쿠폰이 이중으로 발급포인트가 이중으로 적립현재 구현: DB event_handled 테이블@Trans..

운영/Kafka & MQ 2026.03.29

Consumer에서 self-invocation을 발견하기까지 @Transactional이 무시되는 구조

Kafka Consumer 안에서 @Transactional 메서드를 호출했는데, 트랜잭션이 안 걸렸다. 원인은 Spring AOP의 가장 유명한 함정 — self-invocation이었다.발단: 쿠폰 발급은 됐는데 event_handled가 안 남았다선착순 쿠폰 Consumer를 테스트하던 중 이상한 현상을 발견했다:쿠폰은 정상 발급됨하지만 event_handled 테이블에 기록이 남지 않음같은 이벤트가 다시 오면 중복 발급@Transactional로 감싸서 쿠폰 발급 + event_handled 저장을 원자적으로 처리했는데, 왜 event_handled만 빠졌는가?원인: self-invocation — 같은 클래스 내부 호출은 프록시를 우회한다문제가 된 코드 (리팩토링 전)@Componentpubli..

운영/Kafka & MQ 2026.03.29

Outbox Relay 최적화, 10건에서 155건으로

Outbox Relay 최적화: 10건/초에서 155건/초까지TL;DROutbox Relay의 초기 구현은 10건/초였다. PROCESSING 상태 추가 + FOR UPDATE SKIP LOCKED + parallelStream으로 155건/초까지 개선했다. 부하 테스트로 병목이 Phase 2(Kafka 동기 발행)임을 확인했고, 5분 PROCESSING 복구 threshold가 충분히 안전한 것을 수치로 증명했다.1. 초기 구현의 한계 — 왜 10건/초인가[이전 글](커밋 후 발행 vs 발행 후 커밋)에서 Outbox Pattern을 "왜" 선택했는지 다뤘다.이 글은 그 다음 질문에 답한다. Outbox를 선택했으면, 처리량은 어떻게 끌어올리는가?초기 구현은 단순했다.5초 간격 폴링 × 50건 배치 =..

운영/Kafka & MQ 2026.03.28

트래픽이 몰려도 데이터를 잃지 않는 Kafka 파이프라인 설계

트래픽이 몰려도 데이터를 잃지 않는 Kafka 파이프라인 설계TL;DR100명이 동시에 선착순 쿠폰을 요청하면, 10장만 정확히 발급되어야 한다. 11장도 안 되고, 9장도 안 된다. 이 글에서는 이커머스 프로젝트에서 Kafka 파이프라인을 설계하고 구현하면서 마주한 실제 문제들 — Topic 설계, Producer/Consumer 전략, 장애 시나리오와 방어 메커니즘 — 을 다룬다. 이론이 아니라 직접 깨지고 고친 경험이다.1. 5개 토픽, 각각 다른 이유로 존재한다토픽은 "메시지를 담는 곳"이 아니라 "도메인 경계"다토픽을 하나로 합치고 eventType 헤더로 구분하면 안 되나? 기술적으로는 가능하다. 하지만 Consumer Group이 토픽 단위로 묶이기 때문에, 하나의 토픽에 서로 다른 도메인의..

운영/Kafka & MQ 2026.03.28

[소프트웨어 아키텍처] Ch.15 이벤트 주도 아키텍처 스타일 (Event-Driven Architecture) 완벽 가이드

목차이벤트 주도 아키텍처란?요청 기반 모델 vs 이벤트 기반 모델토폴로지 개요이벤트 vs 메시지파생 이벤트와 확장 능력비동기 역량브로드캐스팅과 이벤트 페이로드오류 처리데이터 손실 방지요청-응답 처리중재자 토폴로지데이터 토폴로지아키텍처 특성 평가예시와 용례1. 이벤트 주도 아키텍처란?이벤트 주도 아키텍처(Event-Driven Architecture, EDA)는 인기 있는 분산 비동기 아키텍처 스타일로, 고확장성·고성능 애플리케이션을 만드는 데 흔히 사용됩니다.1.1 핵심 특징적응성이 매우 높음: 소규모 애플리케이션부터 대규모 복합 애플리케이션까지 다양한 규모에 적용 가능분리된 컴포넌트: 결합이 느슨한(decoupled) 이벤트 처리 컴포넌트들로 구성비동기 처리: 컴포넌트들이 비동기적으로 이벤트를 발생하고..

도서 2026.02.01

Apache Kafka 설치와 Client(Producer/Consumer) 간 Message 송수신 가이드

목차Kafka 4.x 소개 및 KRaft 모드로컬 환경 설치 (macOS)Kafka 서버 실행토픽 생성 및 관리Producer/Consumer 메시지 송수신 테스트Java Client 예제 (실전 코드)트러블슈팅1. Kafka 4.x 소개 및 KRaft 모드Apache Kafka 4.0부터는 ZooKeeper가 완전히 제거되고 KRaft(Kafka Raft) 모드가 기본이 되었습니다. KRaft는 Kafka 자체의 합의 프로토콜을 사용하여 메타데이터를 관리하므로, 별도의 ZooKeeper 클러스터 없이도 Kafka를 운영할 수 있습니다.주요 특징ZooKeeper 의존성 제거: 아키텍처 단순화Java 17 필수: Brokers/Connect/Tools는 Java 17 이상 필요Combined 모드: 로컬 ..

운영/Kafka & MQ 2025.09.17

[Apache Kafka] 주요 개념과 구성 요소 Deep Dive

오늘날 기업 시스템은 더 이상 단일 데이터베이스와 단일 애플리케이션에 의존하지 않습니다.실시간 데이터 스트리밍과 분산 처리가 기본이 되었고, 사용자 이벤트, 주문, 결제, 로그 데이터는 밀리초 단위로 쏟아져 들어옵니다. 이러한 데이터 흐름을 안정적이고 확장 가능하게 처리하기 위해 많은 기업이 선택하는 기술이 바로 Apache Kafka입니다. Kafka는 단순한 메시지 브로커를 넘어서, 이벤트 스트리밍 플랫폼이라는 새로운 패러다임을 제시합니다. 이번 포스팅에서는 Kafka를 처음 접하거나 기본 개념을 다시 정리하려는 분들을 위해, 다음 세 가지 주제를 중심으로 Kafka를 살펴보겠습니다.Kafka의 주요 특징 – Kafka가 다른 메시지 큐와 차별화되는 이유Kafka의 핵심 구성 요소 – Cluster,..

운영/Kafka & MQ 2025.09.17