123 lines
10 KiB
Markdown
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 요약: (미작성)
|