Files
llm-wiki/raw/official-docs/outbox-debezium-official-docs.md

123 lines
10 KiB
Markdown

---
title: Debezium Outbox Event Router (공식 문서)
source_type: official-doc
url: https://debezium.io/documentation/reference/stable/transformations/outbox-event-router.html
archive_url:
status: raw
confidence: medium
tags: [ca-outbox-pattern, debezium, cdc, outbox-event-router, kafka-connect, official-doc]
related_projects: [ca-skeleton-operational-contract]
related_branches: [feature-domain-event-outbox-contract, feature-background-job-async-contract]
created: 2026-05-22
last_reviewed: 2026-05-27
---
# Debezium Outbox Event Router (공식 문서)
> Layer: `raw/official-docs/` — Debezium 공식 documentation "Outbox Event Router" SMT (Single Message Transform) 의 **원문 발췌·출처 기록**.
> ca-tmpl 의 SKIP LOCKED outbox 결정에 대한 **대안 1: CDC 기반 outbox 발행**. Debezium 이 outbox 테이블의 INSERT log 를 읽어 Kafka 로 보내는 모델.
## Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-domain-event-outbox-contract]] | Topic 3 — Outbox Pattern 대안 비교 (대안 1: Debezium CDC) 의 1차 근거 — polling 부하 없는 outbox 발행 모델 |
| [[raw/branch-notes/feature-background-job-async-contract]] | Background job / async event 발행 인프라 선택 시 polling 대비 CDC 의 trade-off 비교 근거 |
| [[raw/project-notes/ca-skeleton-operational-contract]] | §18 (Control Plane Contract) / §19 (Domain Application Readiness Contract) 의 outbox 발행 대안 매트릭스에서 baseline (SKIP LOCKED polling) 의 대조점 |
## 컨텍스트
ca-tmpl 이 채택한 SKIP LOCKED polling 방식의 직접 대안. Debezium 은 DB transaction log (Postgres WAL / MySQL binlog) 를 읽어 outbox 테이블의 INSERT 를 Kafka topic 으로 routing. polling 인스턴스 자체가 사라지고 Kafka Connect cluster 가 그 역할을 대체.
## 출처 / Source
- 원본 URL: https://debezium.io/documentation/reference/stable/transformations/outbox-event-router.html
- 보조 URL (Debezium 블로그 — Gunnar Morling): https://debezium.io/blog/2019/02/19/reliable-microservices-data-exchange-with-the-outbox-pattern/
- 아카이브 URL: (미수집)
- 저자 / 조직: Debezium project / Red Hat
- 발행일: rolling docs (페이지 자체에 명시 없음)
- 마지막 확인일 (capture): 2026-05-22
- 마지막 재검증 시도: 2026-05-27
- **[2026-05-25 capture]**: user 가 2026-05-22 수집한 인용 원형 유지 (재검증 보류 마커는 2026-05-25 부여된 상태).
- **재검증 결과 [2026-05-27 verified attempt]**: 1차 URL (`https://debezium.io/documentation/reference/stable/transformations/outbox-event-router.html`) WebFetch HTTP 403 Forbidden. 버전 핀(`/3.3/`) 및 보조 URL (Debezium 블로그 2019-02-19) 도 403 — debezium.io 가 WebFetch UA 를 일괄 차단하는 것으로 보임. verbatim 재확인 불가.
- **재검증 한계**: 2026-05-27 다중 채널 WebFetch 차단 — 본 인용은 user 가 2026-05-22 수집한 원본 발췌 원형 보존, verbatim 재확인 보류. 본 문서 인용은 모두 `needs-confirmation` Strength 유지 (Strength 상향 없음).
## 핵심 인용 / Key quotes (verbatim, user 수집본 [2026-05-25 capture] — [2026-05-27 verified attempt] WebFetch 403 차단으로 verbatim 재확인 보류)
> [§Outbox Event Router SMT] "The outbox event router is a single message transformation (SMT) that takes the events captured from an outbox table and routes them to topics named after the event aggregate type."
> [§CDC vs polling] "Capturing changes via the database's transaction log (CDC) avoids the cost of polling the outbox table."
> [§Immediate DELETE] "Since Debezium reads the transaction log, the outbox row only needs to exist long enough for the log to be captured; you can immediately DELETE the row in the same transaction."
> [§Delivery semantics] "The pattern provides at-least-once delivery semantics. Consumers must therefore be idempotent."
## Claims Extracted / 추출된 주장
> 이 자료가 직접 말하는 것만 claim 으로 분리. 본 raw 의 모든 quote 는 2026-05-22 user 수집본이며 2026-05-27 WebFetch 차단으로 verbatim 재확인 보류 → 전체 `needs-confirmation`.
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| OUTBOX-DBZ-C1 | Outbox Event Router 는 outbox 테이블에서 캡처된 이벤트를 event aggregate type 이름의 Kafka topic 으로 routing 하는 SMT (Single Message Transformation) | [§Outbox Event Router SMT] "The outbox event router is a single message transformation (SMT) that takes the events captured from an outbox table and routes them to topics named after the event aggregate type." | `needs-confirmation` | Debezium connector + Kafka Connect 환경 | aggregate type 외 partition key / header / payload schema 등 모든 라우팅 정책의 default 동작을 본 인용으로 확정할 수 없음 |
| OUTBOX-DBZ-C2 | CDC (DB transaction log 기반 캡처) 는 outbox 테이블을 polling 하는 비용을 회피한다 | [§CDC vs polling] "Capturing changes via the database's transaction log (CDC) avoids the cost of polling the outbox table." | `needs-confirmation` | Postgres logical replication / MySQL row-based binlog 가 활성화된 DB | polling 자체가 모든 DB 부하 시나리오에서 더 비싸다는 일반 명제는 아님 — interval, table size, index, vacuum 조건에 따라 다름 |
| OUTBOX-DBZ-C3 | CDC 가 transaction log 를 읽기 때문에 outbox row 는 log capture 가 완료될 만큼만 존재하면 되며, 동일 트랜잭션에서 즉시 DELETE 가능 | [§Immediate DELETE] "Since Debezium reads the transaction log, the outbox row only needs to exist long enough for the log to be captured; you can immediately DELETE the row in the same transaction." | `needs-confirmation` | Debezium + Postgres/MySQL logical/row-based replication | DELETE 직후 connector 장애 시 손실 없음을 보장한다는 뜻은 아님 — connector offset/HA 설계와 결합 필요 |
| OUTBOX-DBZ-C4 | Debezium Outbox 패턴은 at-least-once delivery 를 제공하며 consumer 는 idempotent 해야 한다 | [§Delivery semantics] "The pattern provides at-least-once delivery semantics. Consumers must therefore be idempotent." | `needs-confirmation` | Debezium outbox SMT 를 사용하는 end-to-end pipeline | exactly-once 가 일부 Kafka Connect 모드에서 부분적으로 가능하나, outbox SMT 조합의 end-to-end EOS 는 본 인용으로 보장 안 됨 |
### Strength 정책
본 문서의 모든 claim 은 `needs-confirmation`. 이유: 2026-05-27 재검증 시점에 WebFetch 가 차단되어 user 수집본 (2026-05-22) 의 verbatim 일치 여부를 공식 페이지 대조로 확인 못함. wiki 승급 전 재확인 필수.
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것** (재확인 시):
- `OUTBOX-DBZ-C1`: Debezium Outbox Event Router SMT 의 정의와 routing 기준 (aggregate type)
- `OUTBOX-DBZ-C2`: CDC 가 polling 비용을 회피한다는 공식 입장
- `OUTBOX-DBZ-C3`: outbox row 즉시 DELETE 가능 (table hot 방지)
- `OUTBOX-DBZ-C4`: at-least-once 보장 + consumer idempotency 필수
- **이 자료가 증명하지 않는 것**:
- Kafka Connect cluster HA / offset 관리 / schema evolution 의 실제 운영 비용
- Debezium connector 장애 시 복구 절차의 정확한 SLA
- CDC lag 의 정확한 수치 (claim 은 "polling 비용 회피"이지 "ms 단위 lag" 보장이 아님)
- end-to-end exactly-once (consumer 측 + Kafka Connect EOS mode 조합 필요, 본 인용으로 미보장)
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- ca-tmpl 이 운영하는 Postgres 의 `wal_level=logical` 활성화 여부 + 운영 DBA 정책
- Kafka + Kafka Connect 클러스터 도입 비용 (인력 / 인프라)
- aggregate type 기반 routing 이 ca-tmpl 의 domain event taxonomy 와 호환되는지
## 메모 / Notes (내 프로젝트 해석 — 직접 인용 아님)
- 적용 시나리오: 이미 Kafka + Kafka Connect 를 운영 중이거나 도입 가능한 조직. write throughput 이 높아 polling 부하/lag 이 문제가 되는 케이스.
- 장점:
- **polling 없음** → DB 부하 거의 없음, lag 이 ms 단위
- outbox row 를 즉시 DELETE 가능 (transaction log 에 흔적이 남음) → 테이블이 hot 하지 않음
- aggregate type 기반 자동 라우팅 (`outbox.event.router`)
- 순서가 partition 내에서 자연 보장
- 단점:
- **Kafka + Kafka Connect + Debezium connector** 인프라 운영 필요
- DB 의 logical replication / binlog 활성화 (Postgres `wal_level=logical`, MySQL row-based binlog) 필요 → DBA 협조 + 운영 부담
- Debezium connector 자체의 HA · offset 관리 · schema evolution 대응 필요
- connector 장애 시 lag 발생, 복구 절차가 polling 보다 복잡
- ca-tmpl (SKIP LOCKED polling) 과의 차이:
- polling 인스턴스 자체가 사라지고 Kafka Connect cluster 가 그 역할을 대체
- lag 특성이 "interval 기반"에서 "WAL 따라잡기 기반"으로 바뀜
- 인프라 의존성이 DB-only 에서 **DB + Kafka + Kafka Connect** 로 증가
- 운영 복잡도: 중상. Kafka Connect 운영 경험 필요.
- exactly-once / at-least-once 보장 수준: **at-least-once** (`OUTBOX-DBZ-C4`).
- 외부 의존성 추가 여부: **Kafka, Kafka Connect, Debezium**. 큼.
- 대안 그룹 (Topic 3 — Outbox Pattern, 대안 6종): SKIP LOCKED polling / **Debezium CDC** / Kafka Connect SMT / Dual-write [금지] / Event sourcing / Spring @TransactionalEventListener
- 본 source 의 위치: 대안 1 — Debezium CDC
## Related / 관련
- 같은 주제 다른 official-doc:
- [[raw/official-docs/outbox-skip-locked-microservices-io]] (baseline: SKIP LOCKED polling)
- [[raw/official-docs/skip-locked-postgres-docs]] (Postgres 공식 — SKIP LOCKED 메커니즘)
- [[raw/official-docs/dual-write-antipattern-microservices-io]] (negative reference)
- 같은 주제 company-tech-blog:
- [[raw/company-tech-blogs/outbox-woowahan-techblog-pattern]]
- 인용하는 branch / project:
- [[raw/branch-notes/feature-domain-event-outbox-contract]]
- [[raw/branch-notes/feature-background-job-async-contract]]
- [[raw/project-notes/ca-skeleton-operational-contract]]
- 인용한 wiki 요약: (미작성)