TL;DR

  • Kafka 사용 패턴 - K8s 내부 통신의 핵심 개념과 사용 범위를 한눈에 정리
  • 등장 배경과 필요한 이유를 짚고 실무 적용 포인트를 연결
  • 주요 특징과 체크리스트를 빠르게 확인

1. 개념

┌─────────────────────────────────────────────────────────┐ │ K8s 내부 통신 패턴 │ │ │ │ ❌ 틀린 생각: │ │ "모든 서비스 간 통신에 Kafka 사용" │ │ │ │ ✅ 실제 패턴: │ │ "필요한 곳에만 Kafka, 나머지는 직접 통신" │ │ │ │ 경험적 비율: │ │ ├── 동기 (gRPC/HTTP): 70-80% │ │ └── 비동기 (Kafka): 20-30% │ │ │ └─────────────────────────────────────────────────────────┘

2. 배경

Kafka 사용 패턴 - K8s 내부 통신이(가) 등장한 배경과 기존 한계를 정리한다.

3. 이유

이 주제를 이해하고 적용해야 하는 이유를 정리한다.

4. 특징

  • 1 동기 vs 비동기
  • 2 결정 트리
  • 왜 3번만 Kafka?
  • gRPC vs HTTP/REST 선택
  • 관련 키워드

5. 상세 내용

작성일: 2026-01-29 카테고리: Infra / Messaging / Architecture 포함 내용: Kafka, gRPC, 동기/비동기 통신, 이벤트 드리븐, 마이크로서비스 통신 패턴


1. 핵심 질문: 모든 곳에 Kafka?

┌─────────────────────────────────────────────────────────┐
│              K8s 내부 통신 패턴                          │
│                                                         │
│  ❌ 틀린 생각:                                          │
│  "모든 서비스 간 통신에 Kafka 사용"                     │
│                                                         │
│  ✅ 실제 패턴:                                          │
│  "필요한 곳에만 Kafka, 나머지는 직접 통신"              │
│                                                         │
│  경험적 비율:                                           │
│  ├── 동기 (gRPC/HTTP): 70-80%                           │
│  └── 비동기 (Kafka): 20-30%                             │
│                                                         │
└─────────────────────────────────────────────────────────┘

2. 일반적인 아키텍처

┌─────────────────────────────────────────────────────────────────────────┐
│                                                                         │
│   외부                      K8s 클러스터                                │
│                                                                         │
│  ┌──────┐    ┌─────────┐    ┌──────────────────────────────────────┐   │
│  │ User │───►│ Ingress │───►│  API Gateway / BFF                   │   │
│  └──────┘    └─────────┘    └───────────────┬──────────────────────┘   │
│                                             │                           │
│                     ┌───────────────────────┼───────────────────────┐  │
│                     │                       │                       │  │
│                     ▼                       ▼                       ▼  │
│              ┌────────────┐         ┌────────────┐         ┌──────────┐│
│              │ User       │◄───────►│ Order      │◄───────►│ Payment  ││
│              │ Service    │  gRPC   │ Service    │  gRPC   │ Service  ││
│              └────────────┘  HTTP   └─────┬──────┘         └────┬─────┘│
│                                           │                     │      │
│                                           │      Kafka          │      │
│                                           ▼     (비동기만!)     ▼      │
│                                    ┌──────────────────────────────┐    │
│                                    │         Kafka                │    │
│                                    └──────────────────────────────┘    │
│                                           │                     │      │
│                     ┌─────────────────────┼─────────────────────┤      │
│                     ▼                     ▼                     ▼      │
│              ┌────────────┐       ┌────────────┐       ┌────────────┐  │
│              │ Inventory  │       │ Notification│       │ Analytics  │  │
│              │ Service    │       │ Service     │       │ Service    │  │
│              └────────────┘       └────────────┘       └────────────┘  │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

3. 통신 방식 선택 기준

3.1 동기 vs 비동기

┌─────────────────────────────────────────────────────────┐
│                                                         │
│  동기 통신 (gRPC, HTTP/REST):                           │
│  ├── 즉시 응답이 필요할 때                              │
│  ├── 요청-응답 패턴                                     │
│  ├── 트랜잭션 처리                                      │
│  └── 예: 결제 확인, 사용자 인증, 재고 확인              │
│                                                         │
│  비동기 통신 (Kafka):                                   │
│  ├── 응답을 기다릴 필요 없을 때                         │
│  ├── 이벤트 발행 패턴                                   │
│  ├── 여러 서비스가 같은 이벤트 구독                     │
│  ├── 처리 속도가 달라도 되는 경우                       │
│  └── 예: 알림 발송, 로그 수집, 분석 데이터              │
│                                                         │
└─────────────────────────────────────────────────────────┘

3.2 결정 트리

┌─────────────────────────────────────────────────────────┐
│                    선택 결정 트리                        │
│                                                         │
│  "이 통신에서..."                                       │
│                                                         │
│  즉시 응답 필요? ─────────────────► Yes → gRPC/HTTP     │
│        │                                                │
│       No                                                │
│        ▼                                                │
│  여러 소비자가 같은 메시지 필요? ──► Yes → Kafka        │
│        │                                                │
│       No                                                │
│        ▼                                                │
│  메시지 유실되면 안 됨? ──────────► Yes → Kafka         │
│        │                                                │
│       No                                                │
│        ▼                                                │
│  처리량 스파이크 대응 필요? ──────► Yes → Kafka         │
│        │                                                │
│       No                                                │
│        ▼                                                │
│  단순 fire-and-forget? ─────────► 그냥 HTTP async 가능  │
│                                                         │
└─────────────────────────────────────────────────────────┘

4. 실제 사례: 주문 처리 시나리오

┌─────────────────────────────────────────────────────────┐
│                                                         │
│  사용자: "주문하기" 버튼 클릭                           │
│                                                         │
│  1. [동기 - gRPC] 재고 확인                             │
│     Order Service ──► Inventory Service                 │
│     "재고 있어?" → "있어!" (즉시 응답 필요)             │
│                                                         │
│  2. [동기 - gRPC] 결제 처리                             │
│     Order Service ──► Payment Service                   │
│     "결제해줘" → "성공!" (트랜잭션, 즉시 필요)          │
│                                                         │
│  3. [비동기 - Kafka] 주문 완료 이벤트 발행              │
│     Order Service ──► Kafka ──┬──► Notification Service │
│                               ├──► Analytics Service    │
│                               ├──► Inventory Service    │
│                               └──► Shipping Service     │
│     "주문 완료됐어~" (응답 안 기다림)                   │
│                                                         │
│  사용자에게 응답: "주문 완료!" (1,2번만 기다림)         │
│                                                         │
└─────────────────────────────────────────────────────────┘

왜 3번만 Kafka?

┌─────────────────────────────────────────────────────────┐
│                                                         │
│  Kafka 쓰는 이유:                                       │
│  ├── 여러 서비스가 동시에 "주문 완료" 알아야 함         │
│  ├── 알림 실패해도 주문은 유효                          │
│  ├── 분석 서비스가 느려도 주문 응답엔 영향 없음         │
│  └── 나중에 새 서비스 추가해도 Order 수정 없이 구독만   │
│                                                         │
│  gRPC 쓰는 이유 (1,2번):                                │
│  ├── 재고 없으면 주문 안 됨 → 즉시 확인 필요            │
│  ├── 결제 실패하면 주문 취소 → 트랜잭션                 │
│  └── 사용자가 결과 기다리는 중                          │
│                                                         │
└─────────────────────────────────────────────────────────┘

5. Kafka 오버헤드 vs 장점

┌─────────────────────────────────────────────────────────┐
│                                                         │
│  Kafka 오버헤드:                                        │
│  ├── 레이턴시 증가 (직접 호출 대비 수~수십 ms 추가)     │
│  ├── 운영 복잡도 (Zookeeper, Broker 관리)               │
│  ├── 디버깅 어려움 (비동기 추적)                        │
│  ├── 메시지 순서 보장 복잡                              │
│  └── 리소스 사용 (별도 클러스터 필요)                   │
│                                                         │
│  Kafka 장점:                                            │
│  ├── 디커플링 (서비스 간 의존성 감소)                   │
│  ├── 내구성 (메시지 영구 저장)                          │
│  ├── 확장성 (Consumer 추가 쉬움)                        │
│  ├── 버퍼링 (트래픽 스파이크 흡수)                      │
│  └── 리플레이 (과거 이벤트 재처리 가능)                 │
│                                                         │
└─────────────────────────────────────────────────────────┘

6. 실무에서 흔한 패턴

┌─────────────────────────────────────────────────────────┐
│                                                         │
│  1. API Gateway 패턴                                    │
│     외부 ──HTTP──► Gateway ──gRPC──► 내부 서비스들      │
│                                                         │
│  2. 내부 동기 통신                                      │
│     Service A ◄──gRPC──► Service B                      │
│     (빠르고, 타입 안전, 스트리밍 지원)                  │
│                                                         │
│  3. 이벤트 드리븐 (필요한 곳만)                         │
│     Service A ──Kafka──► [이벤트] ──► 여러 Consumer     │
│                                                         │
│  4. Sidecar 패턴 (Istio 등)                             │
│     서비스 간 통신은 Envoy Proxy가 처리                 │
│     (mTLS, 로드밸런싱, 관측성)                          │
│                                                         │
└─────────────────────────────────────────────────────────┘

gRPC vs HTTP/REST 선택

┌─────────────────────────────────────────────────────────┐
│                                                         │
│  gRPC 선택:                                             │
│  ├── 내부 서비스 간 통신 (K8s 내부)                     │
│  ├── 성능이 중요한 경우                                 │
│  ├── 양방향 스트리밍 필요                               │
│  └── 강타입 계약 필요 (Proto)                           │
│                                                         │
│  HTTP/REST 선택:                                        │
│  ├── 외부 API (브라우저, 모바일)                        │
│  ├── 간단한 CRUD                                        │
│  ├── 디버깅 용이성 필요                                 │
│  └── 다양한 클라이언트 지원                             │
│                                                         │
└─────────────────────────────────────────────────────────┘

7. Kafka가 적합한/불필요한 곳

┌─────────────────────────────────────────────────────────┐
│                                                         │
│  Kafka가 적합한 곳:                                     │
│  ├── 주문/결제 완료 이벤트 → 여러 후속 처리             │
│  ├── 로그/메트릭 수집 → 분석 시스템                     │
│  ├── 사용자 활동 추적 → 추천/개인화                     │
│  ├── CDC (Change Data Capture) → DB 동기화             │
│  ├── 외부 시스템 연동 → 버퍼링 필요                     │
│  └── 비동기 작업 큐 → 이메일, 알림, 리포트 생성         │
│                                                         │
│  Kafka 불필요한 곳:                                     │
│  ├── 사용자 인증/인가                                   │
│  ├── 재고 조회                                          │
│  ├── 상품 상세 정보                                     │
│  ├── 즉각적인 CRUD 작업                                 │
│  ├── 동기적 트랜잭션 처리                               │
│  └── 단순 요청-응답 패턴                                │
│                                                         │
└─────────────────────────────────────────────────────────┘

8. 대안 기술들

┌─────────────────────────────────────────────────────────┐
│                                                         │
│  메시지 브로커 선택:                                    │
│                                                         │
│  ┌──────────┬───────────────────────────────────────┐  │
│  │ 기술     │ 특징                                  │  │
│  ├──────────┼───────────────────────────────────────┤  │
│  │ Kafka    │ 대용량, 영속성, 스트리밍, 복잡        │  │
│  │ RabbitMQ │ 경량, 유연한 라우팅, 전통적 MQ       │  │
│  │ Redis    │ 초경량, 임시 큐, Pub/Sub             │  │
│  │ NATS     │ 클라우드 네이티브, 경량, 빠름        │  │
│  │ Pulsar   │ Kafka 대안, 멀티테넌시, 티어드 스토리지 │  │
│  └──────────┴───────────────────────────────────────┘  │
│                                                         │
│  선택 기준:                                             │
│  ├── 단순 작업 큐 → RabbitMQ, Redis                     │
│  ├── 이벤트 스트리밍 → Kafka, Pulsar                    │
│  ├── 경량 Pub/Sub → Redis, NATS                         │
│  └── 대용량 로그 → Kafka                                │
│                                                         │
└─────────────────────────────────────────────────────────┘

9. 정리

┌─────────────────────────────────────────────────────────┐
│                                                         │
│  "모든 곳에 Kafka" = ❌ 안티패턴                        │
│                                                         │
│  올바른 접근:                                           │
│  ├── 동기 (gRPC/HTTP): 70-80% (대부분의 통신)           │
│  │   └── 요청-응답, 트랜잭션, 즉시 필요                 │
│  │                                                      │
│  └── 비동기 (Kafka): 20-30% (선별적 사용)               │
│      └── 이벤트 발행, 다수 구독자, 디커플링 필요        │
│                                                         │
│  핵심 원칙:                                             │
│  ├── "즉시 응답 필요?" → 동기                           │
│  ├── "여러 소비자?" → Kafka                             │
│  ├── "실패해도 괜찮아?" → Kafka                         │
│  └── "버퍼링 필요?" → Kafka                             │
│                                                         │
│  비유:                                                  │
│  ├── 동기 = 전화 (즉시 대화, 상대방 필수)               │
│  └── 비동기 = 우체통 (보내고 끝, 나중에 확인)           │
│                                                         │
└─────────────────────────────────────────────────────────┘

관련 키워드

Kafka, gRPC, 마이크로서비스, 이벤트 드리븐, 동기/비동기, 메시지 브로커, K8s, 서비스 간 통신