카프카(Kafka)란 무엇인가?
1. 분산 이벤트 스트리밍 플랫폼
- 카프카는 분산 환경에서 이벤트 스트리밍을 처리하기 위한 플랫폼이다.
- 이벤트 스트리밍이란, 데이터(메시지)를 실시간으로 지속해서 전송하고 처리하는 것을 의미한다.
2. 어디서 많이 쓰이나?
- 데이터(메시지)를 빠르고 안정적으로 전송하고 저장해야 하는 "실시간 데이터 파이프라인"이나 "분산 로그 시스템"이 필요한 곳에 많이 쓰인다.
카프카의 기본 구조
1-1. 카프카 클러스터(Kafka Cluster)
- 메시지를 저장하는 '저장소'(Broker들의 집합)라고 볼 수 있다.
- 고가용성과 확장성을 제공하며, 데이터를 여러 브로커에 분산시켜 저장한다.
1-2. 브로커
- 카프카 브로커는 카프카 시스템을 구성하는 개별 서버이다.
- 카프카 클러스터를 형성하여 전체 시스템의 일부로 작동한다.
- Controller: 브로커 중 한 노드가 장애 발생 시 리더 파티션 재분배를 담당한다.
- Coordinator: 컨슈머 그룹을 관리하며, 장애 발생 또는 신규 컨슈머 추가 시
Rebalance
를 수행한다.
2. 프로듀서(Producer)
- 카프카로 메시지를 전송(생성)하는 주체이다.
- 예) 애플리케이션, 서버 등에서 발생한 데이터를 카프카에 "넣어" 주는 역할을 한다.
- 메시지를 보낼 때 키(key)를 지정하면, 해당 키의 해시 값을 기반으로 특정 파티션에 할당되어 메시지 순서가 보장된다.
3. 컨슈머(Consumer)
- 카프카에서 메시지를 읽어가는(소비) 주체이다.
- 예) 카프카에 쌓인 데이터를 가져와서 처리하거나 다른 시스템에 전달하는 역할을 한다.
- 메시지를 읽을 때 각 메시지의 Offset을 유지해 처리 상태를 관리하며,
-reset-offsets
옵션을 사용해 특정 지점으로 복원할 수 있다.
전체 구조를 종합하면, 프로듀서가 메시지를 카프카 클러스터에 전송(저장)하고, 컨슈머가 필요할 때마다 그 메시지를 카프카 클러스터에서 읽어가는 형태이다.
토픽(Topic)과 파티션(Partition)
1. 토픽(Topic)
- 메시지를 구분하는 논리적 단위이다.
- 예) "주문 메시지용 토픽", "뉴스 기사 메시지용 토픽" 등으로 데이터의 종류별로 구분해서 저장할 수 있다.
- 파일 시스템 관점에서 폴더나 메일함처럼, 메시지를 종류별로 분류하는 용도로 이해하면 된다.
2. 파티션(Partition)
- 실제로 메시지가 저장되는 물리적 파일이다.
- 하나의 토픽은 내부적으로 여러 파티션으로 구성될 수 있다.
- 예) "주문 메시지"라는 토픽의 경우, 내부에 파티션 0, 1, 2 등 다수의 파티션이 있을 수 있다.
- 파티션을 여러 개 두면 메시지를 병렬로 처리할 수 있어 처리량을 높이기가 쉽다.
파티션과 오프셋(Offset), 메시지 순서
1. 어펜드 온리(append-only) 파일
- 카프카의 각 파티션은 어펜드 온리(append-only) 파일로 구현되어 있다.
- 새로운 메시지는 항상 파일 끝에 순서대로 저장된다.
- 중간에 메시지가 삽입되는 일은 없다.
- 메시지를 생성하면, 카프카는 해당 메시지를 특정 파티션의 가장 끝(Offset) 위치에 추가한다.
2. 오프셋(Offset)
- 파티션 파일에서 메시지가 저장된 위치를 식별하는 번호이다.
- 예) 파티션 0번 파일 내 메시지가 순서대로 있으면, 첫 번째 메시지는 오프셋 0, 두 번째 메시지는 오프셋 1, 세 번째 메시지는 오프셋 2 … 이런 식으로 증가한다.
3. 메시지 순서 보장
- 컨슈머는 특정 파티션 내에서 메시지를 오프셋 순서대로 읽어간다.
- 만약 컨슈머가 "오프셋 3부터 읽겠다"고 하면, 해당 파티션 내 3번, 4번, 5번 … 순서대로 읽게 된다.
- 파티션 단위로만 순서가 보장되며, 여러 파티션 간의 전역 순서는 보장되지 않는다.
4. 데이터 보존
- 카프카는 기본적으로 "어펜드 온리" 파일이므로, 한 번 기록된 메시지는 retention 기간이나 특정 정책에 의해 삭제될 때까지 계속 보존된다.
- 컨슈머가 메시지를 읽었더라도 해당 메시지는 파티션 파일에 남아 있어, 다른 컨슈머가 재처리하거나 장애 발생 후 복구에 활용할 수 있다.
파티션 분배: 프로듀서 측
1. 어떤 파티션으로 메시지를 보낼까?
- 라운드 로빈(Round Robin) 방식: 파티션이 여러 개이면, 순차적으로 (0 → 1 → 2 → 0 → ...) 메시지를 분산 전송한다.
- 키(Key) 사용: 메시지에 키를 지정하면, 키의 해시(hash) 값을 이용해 특정 파티션에 할당한다.
- 같은 키를 가진 메시지는 항상 같은 파티션에 저장되어, 해당 키의 메시지 순서가 보장된다.
파티션 분배: 컨슈머와 컨슈머 그룹
1. 컨슈머 그룹(Consumer Group)
- 컨슈머들은 반드시 어떤 '그룹'에 속한다고 선언한 후 카프카에 접속한다.
- 예)
ConsumeGroupA
라는 그룹 아래 컨슈머 3개가 실행된다면, 카프카는 이 3개 컨슈머에게 파티션을 자동 할당(리밸런싱)한다.
2. 1 파티션 = 1 컨슈머 (within the same group)
- 한 파티션은 같은 컨슈머 그룹 내에서 단 한 개의 컨슈머에게만 할당된다.
- 예)
ConsumeGroupA
에 컨슈머 2명이 있다면, 파티션 0은 컨슈머1, 파티션 1은 컨슈머2 등으로 분산된다. - 같은 그룹 내에서는 두 컨슈머가 동일 파티션을 공유하지 않는다.
- 예)
- 단, 서로 다른 컨슈머 그룹은 같은 파티션을 독립적으로 읽을 수 있다.
카프카는 왜 성능이 좋을까?
1. 페이지 캐시(Page Cache) 활용
- 카프카는 운영체제가 제공하는 페이지 캐시를 적극 활용하여, 디스크 I/O보다 훨씬 빠른 메모리 접근으로 데이터를 읽고 쓸 수 있다.
2. 제로 카피(Zero Copy)
- 디스크에서 읽어온 데이터를 별도의 유저 레벨 복사 과정 없이 바로 소켓(네트워크)으로 전달하는 기술이다.
- 불필요한 CPU/메모리 복사를 줄여 데이터 전송 속도를 향상시킨다.
3. 브로커 역할 최소화
- 카프카 브로커는 메시지의 저장, 복제 등 최소한의 작업만 수행하고, 필터링이나 재처리 같은 작업은 프로듀서와 컨슈머가 담당한다.
- 이로 인해 브로커가 병목되지 않고 고성능을 유지할 수 있다.
4. 배칭(Batching) 기능
- 프로듀서: 일정량의 메시지를 모아 한 번에 전송할 수 있다.
- 컨슈머: 여러 메시지를 묶어 한 번에 가져올 수 있다.
- 한 번에 묶어서 전송함으로써 대량 전송 시 처리량이 크게 향상된다.
5. 수평 확장(Scale-out) 구조
- 브로커(서버)를 추가하거나 파티션 수를 늘리면, 저장 및 처리량을 쉽게 확장할 수 있다.
- 컨슈머 측도 필요한 만큼 추가하여, 각 파티션을 분산 처리함으로써 소비 속도를 향상시킬 수 있다.
- 이러한 확장성 덕분에 대규모 트래픽을 안정적으로 감당할 수 있다.
장애 대응: 리플리케이션(Replication)
1. Replication이란?
- 높은 가용성을 보장하기 위한 기능으로, 각 토픽의 파티션을 카프카 클러스터 내 다른 브로커에 복제하는 것을 말한다.
- 토픽 생성 시 리플리케이션 수를 지정하여 복제본 수를 설정할 수 있다.
- 복제된 파티션은 Leader와 Follower로 나뉘며, ISR(동기화된 복제 그룹) 내에서 관리된다.
2. Leader & Follower
- 각 파티션은 1개의 Leader Replica와 0개 이상의 Follower Replica로 구성된다.
- Leader는 모든 프로듀서와 컨슈머의 요청을 처리하며, Follower는 리더의 데이터를 복제한다.
3. 장애 발생 시
- 만약 리더가 속한 브로커에 장애가 발생하면, 남아있는 팔로워 중 하나가 새로운 리더로 승격된다.
- 프로듀서와 컨슈머는 새로운 리더와 연결되어 메시지 전송 및 소비를 계속할 수 있다.
- 이를 통해 브로커 장애 발생 시에도 서비스 중단 없이 고가용성을 유지한다.
Kafka 활용: 비동기 메시지 통신 & 책임 분리
- 기존 방식: 주문 결제 후 외부 API 호출 실패 시 재처리 책임이 애플리케이션에 집중됨.
- Kafka 적용 후:
- 주문 정보가 Kafka에 저장되고, 데이터 수집 플랫폼이나 다른 시스템이 정상 복구되면 자동으로 데이터를 수집.
- 비동기 메시징을 통해 외부 시스템 장애와 애플리케이션 책임이 분리되어, 시스템의 견고성과 확장성이 향상된다.
Transactional Messaging & 데이터 정합성 유지
1. Eventual Consistency (결과적 일관성)
- 시스템 간 데이터 정합성이 시간이 지나면서 맞춰지는 패턴이다.
- 대량 트래픽을 효율적으로 처리하기 위해, 데이터 변경을 작은 트랜잭션 단위로 비동기 처리하는 방식이다.
2. Transactional Messaging 패턴
Transactional Outbox Pattern
- 비즈니스 로직과 Kafka 메시지 발행을 하나의 트랜잭션 내에서 처리한다.
- 비즈니스 데이터와 함께 Outbox 테이블에 메시지를 저장하고, 별도의 프로세스가 이 메시지를 Kafka로 발행한다.
- 이를 통해 메시지 발행 실패를 방지하고, 데이터 정합성을 보장할 수 있다.
Dead Letter Queue (DLQ)
- 개념: 처리 실패 또는 오류가 발생한 메시지를 별도의 큐로 이동시켜 저장하는 패턴이다.
- 메시지 포맷 오류, 처리 로직 실패 등으로 인해 정상 처리되지 못한 메시지를 모아 재처리하거나 분석할 수 있다.
- 시스템의 안정성을 높이고, 문제 원인을 추적하는 데 유용하다.
요약
- 카프카는 고성능 분산 이벤트 스트리밍 플랫폼으로, Producer가 메시지를 전송하고, Consumer가 메시지를 읽어가며, Broker가 메시지를 저장 및 전송 관리한다.
- 토픽과 파티션을 통해 데이터가 논리적·물리적으로 분류되고, 오프셋을 통해 메시지 순서가 보장된다.
- 컨슈머 그룹과 리밸런싱 메커니즘, Replication을 통한 고가용성, 그리고 페이지 캐시, 제로 카피, 배칭, 수평 확장 등의 기능으로 카프카는 높은 성능을 제공한다.
- 추가로, 비동기 메시징과 Transactional Outbox Pattern 등 고급 활용 패턴을 통해 데이터 정합성 유지 및 시스템 책임 분리를 효과적으로 구현할 수 있다.
'지식저장소' 카테고리의 다른 글
엔티티 매니저에 대하여 (0) | 2025.03.28 |
---|---|
Spring Data JPA에서 새로운 Entity인지 판단하는 방법은? (0) | 2025.03.26 |
정적 팩토리 메서드란? (0) | 2024.11.19 |
OAuth 2.0 이란 무엇일까.2 (0) | 2022.03.25 |
OAuth 2.0 이란 무엇일까.1 (0) | 2022.03.25 |