codingstairs
노트에듀라이프연락
⌕검색⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

연락하기

로그인 없이도 보낼 수 있어요. 답변이 필요하면 이메일을 함께 적어 주세요.

  • 익명 폼으로 의견 남기기 →
  • ✉ warragon112@gmail.com
  • 카카오톡 오픈채팅 ↗

© 2026 codingstairs

  • 노트
  • 에듀
  • 검색
  • 라이프
  • 연락
  • 약관
  • RSS
  • GitHub
에듀›PostgreSQL 깊게 다루기 + Redis · Kafka›6단계

6단계

Kafka — 언제 · 언제 아닌지

0회 조회

Kafka — 언제 · 언제 아닌지

Kafka 는 강력하지만 운영 비용도 큽니다. 도입 전에 "진짜 필요한가?" 를 점검.

1. Kafka 가 진짜 해결하는 문제

  • 이벤트 로그 영구 보관 — 소비자가 언제든 과거부터 재생
  • 여러 소비자가 같은 스트림 소비 — fan-out
  • 초고속 쓰기 · 순서 보장 (partition 단위)
  • 서비스 간 decoupling — producer 가 consumer 를 몰라도 됨

2. Kafka 가 아닌 경우

  • 작업 큐 (한 소비자) — BullMQ · Redis Streams · RabbitMQ 가 가볍고 충분
  • Pub/Sub (메시지 휘발 OK) — Redis Pub/Sub
  • 단순 DB 비동기 쓰기 — outbox 패턴 + 단일 worker
  • 트래픽 < 100 msg/s — Kafka 운영 부담이 이득 초과

3. 토픽 · 파티션 · 오프셋

Topic: user-events
├── Partition 0 ── offset 0, 1, 2, 3, 4 ...
├── Partition 1 ── offset 0, 1, 2, 3, 4 ...
└── Partition 2 ── offset 0, 1, 2, 3, 4 ...
  • Topic — 이벤트 채널
  • Partition — 순서 보장 단위 · 병렬성 단위
  • Offset — 파티션 내 위치

파티션 수 = 최대 병렬 소비자 수.

4. Producer

import { Kafka } from "kafkajs";
const kafka = new Kafka({ clientId: "app", brokers: ["kafka:9092"] });
const producer = kafka.producer();

await producer.connect();
await producer.send({
  topic: "user-events",
  messages: [
    { key: String(userId), value: JSON.stringify({ type: "signup", userId, at: Date.now() }) },
  ],
});

key 가 같으면 같은 partition 으로 라우팅 (순서 보장 필요 시).

5. Consumer

const consumer = kafka.consumer({ groupId: "notifier" });
await consumer.connect();
await consumer.subscribe({ topic: "user-events", fromBeginning: false });

await consumer.run({
  eachMessage: async ({ topic, partition, message }) => {
    const payload = JSON.parse(message.value!.toString());
    await handleEvent(payload);
  },
});
  • groupId — 같은 그룹은 파티션 분배, 다른 그룹은 모두 수신
  • fromBeginning: true — 처음부터 재생
  • 커밋 — 기본 auto-commit, 실패 시 재처리 원하면 수동

6. 토픽 네이밍

<domain>.<entity>.<action>

user.signed-up
order.placed
payment.succeeded

혼재 금지. 다른 언어 · 다른 팀과 합의 필수.

7. 이벤트 스키마

JSON vs Avro · Protobuf.

  • JSON — 시작하기 쉬움 · 스키마 강제 없음
  • Avro (Confluent Schema Registry) — 스키마 버전 관리
  • Protobuf — 타입 · 언어 크로스

MVP JSON → 운영 안정화 후 Schema Registry 도입이 자연스러움.

8. 백프레셔

소비자가 producer 를 못 따라가면 lag 증가.

Topic lag = producer offset - consumer offset

대응:

  • 소비자 인스턴스 추가 (파티션 수 내에서)
  • 무거운 작업은 별도 워커로 위임
  • dead-letter topic 으로 문제 메시지 격리

9. 운영 비용

  • Confluent Cloud — 관리형 · 최소 $50 ~ 200/월
  • Self-hosted — ZooKeeper 또는 KRaft + Kafka 3 노드 권장 · 운영 복잡
  • AWS MSK — 관리형 · 시간당 과금

작은 팀은 관리형 추천.

10. 자주 걸리는 자리

  • 파티션 수 나중에 늘릴 때 순서 보장 깨짐 — 처음부터 넉넉히 (배수로 늘리기 쉽게)
  • key 없이 producer.send — 라운드 로빈. 순서 보장 없음
  • consumer 그룹 ID 공유 실수 — 두 앱이 같은 ID 면 메시지 분배됨
  • 커밋 타이밍 — 처리 성공 후 커밋. 실패 시 재처리 로직

하고픈 말

첫 메시징 시스템은 BullMQ · Redis Streams 로 시작하고, 진짜 fan-out · replay 가 필요해지는 시점에 Kafka 도입이 자연스럽습니다.

Next

  • 07-pipeline-idempotency

← 5단계

3-layer 캐시 전략

7단계 →

데이터 파이프라인 — 재시도 · 멱등