
카프카(Kafka)란?
(Before 카프카)

- 데이터를 전송하는 소스 애플리케이션과 데이터를 받는 타겟 애플리케이션으로 구성되어있음(스샷에서 Apps and Service가 소스 애플리케이션, Relational Data Warehouse가 타겟 애플리케이션)
- 엔드투엔드(end-to-end) 연결 방식의 아키텍쳐
- 데이터 연동의 복잡성 증가(하드웨어, 운영체제, 장애 등)
- 하드웨어, 운영체제가 달라서 생기는 문제
- 즉, 복잡성이 높아져 간단한 수정사항에도 에러가 발생할 확률이 높아짐
- 각기 다른 데이터 파이프라인 연결 구조
- 확장에 엄청난 노력 필요
- 이로인해, 모든 시스템으로 데이터를 전송 및 실시간 처리도 가능하며, 데이터가 갑자기 많아지더라도 확장이 용이한 시스템이 필요해짐 ⇒ 이러한 필요성에 의해서 링크드인에서 자체개발한게 카프카
(After 카프카)

- 카프카가 개발되고 나서는 중추신경처럼 한군데 모였다가 퍼지게됨
- 프로듀서/컨슈머 분리
- 메세지 데이터를 여러 컨슈머에게 허용
- 어떤 데이터가 카프카에 들어간 이후에는 여러 컨슈머들이 각각 가져갈 수 있게 즉, 여러번 가져갈 수 있게 만듦
- 높은 처리량을 위한 메세지 최적화
- (쉽게) 스케일 아웃 가능
- 관련 생태계(eco system) 제공
카프카 브로커(broker) & 클러스터(Cluster)

- 스샷에서 카프카 클러스터 부분 = 여러개의 카프카 브로커가 1개의 클러스터 이룸
- 카프카 클라이언트 => 카프카 프로듀서/컨슈머 뜻함
- 브로커는 중추신경 부분이라고 생각하자
- 브러커는 실행된 카프카 애플리케이션 서버 중 1대
- 브로커 = 서버 1대에 애플리케이션 1개가 띄워져 있다는 뜻
- (참고) 이론상으로 애플리케이션은 JVM이기 때문에 서버 1대에 2개 이상의 애플리케이션을 띄울 수 있지만, 대부분의 경우 서버 1대에 애플리케이션 1개를 띄움
- 보통 3대 이상의 브로커(=서버)로 클러스터 구성
- 보통은 카프카와 주키퍼를 연동해서 사용하지만, 카프카 2.8.0부터는 주키퍼 연동없이도 사용가능하지만 아직까지는 주키퍼와 연동해서 사용하는 경우가 많음
- 주키퍼
- 현재 주키퍼의 역할은 메타데이터를 저장함 ⇒ 브로커id 혹은 컨트롤러id를 저장함
- 추후에는 이러한 메타데이터를 카프카 클러스터 즉 브로커 안에 저장한다고 함
- n개(=여러개) 브로커 중 1대는 컨트롤러(Controller) 기능 수행
- 컨트롤러
- 각 브로커에게 담당파티션 할당 수행
- 브로커가 정상적으로 동작하는지 모니터링 하는데 사용
- 누가 컨트롤러인지는 주키퍼에 저장됨
레코드(Record, 프로듀서 레코드/ 컨슈머 레코드)

- 카프카에서 데이터를 주고받는 기본 단위
- 객체를 프로듀서에서 컨슈머로 전달하기 위해 Kafka 내부에 byte형태로 저 장할 수 있도록 직렬화/역직렬화하여 사용
- 기본 제공 직렬화 class : StringSerializer, ShortSerializer 등
- 커스텀 직렬화 class를 통해 Custom Object 직렬화/역직렬화 가능
- 간단하게 프로듀서 <> 브로커 <> 컨슈머는 레코드들을 주고 받는다고 생각하면됨
- 프로듀서는 레코드를 생성하여 ⇒ 카프카 브로커로 전송
- 컨슈머는 레코드를 카프카 브로커에서 pooling하는 애플리케이션
- 프로듀서/컨슈머 동일한 종류의 직렬화/역질렬화 맞춰줘야함
토픽(Topic) ⊃ 파티션(Partition) ⊃ 오프셋(Offset)
- 토픽은 메시지 분류 단위이며, n개의 파티션 할당 가능
- 토픽을 비유적으로 테이블이라고 생각하면 쉽게 이해됨
- 토픽안에 파티션은 반드시 1개이상 존재해야함 (토픽 ⊃ 파티션)
- 각 파티션마다 고유한 오프셋(Offset)을 가짐 = 각 파티션마다 오프셋이라는 번호가 붙는다
- 오프셋 0번 ~ n번 까지 있을때 0번이 가장 오래된거, n번이 가장 최신거
- 각 메시지 처리순서는 파티션 별로 유지 관리됨
- 파티션이 만약 1개라면 자료구조 큐에서 FIFO처럼 데이터를 가져가게됨 = 즉, 메세지 처리 순서가 들어간 순서대로 보장됨
- But, 파티션이 여러개이면 파티션 별로 관리되기때문에 메세지 처리 순서가 들어간 순서대로 보장되진 않음
카프카 클라이언트 - 프로듀서(Producer)와 컨슈머(Consumer)

- 프로듀서는 레코드를 새성하여 브로커로 전송
- 프로듀서가 레코드를 브로커에 전송하면 => 레코드는 특정 파티션의 특정 오프셋에 저장됨
- 즉, 전송된 레코드는 파티션에 신규 오프셋과 함께 기록됨
- 컨슈머는 브로커로부터 레코드를 요청하여 가져감 = 이를 풀링(polling)이라고 함
- 절대 브로커가 컨슈머로 보내는게 아님. 컨슈머가 브로커를 바라보면서 가져오는 것
- 브로커에 있는 동일 데이터(=같은 파티션에서 같은 오프셋인 데이터)를 특정 컨슈머가 한번 가져가면 끝인게 아니라, 여러 컨슈머가 브로커에서 한번씩 혹은 그이상(다시 가져와서 덮어쓰기 하는 경우)으로도 가져올 수 있음.
- 위 스샷에서 컨슈머 A와 컨슈머 B는 각각 다른 기능을 갖은 컨슈머인데(예를 들어 컨슈머 A 하둡에 넣어주는 역할, 컨슈머 B는 MySql에 넣어주는 역할) 각각 0번~12번의 데이터를 몇번이고 가져올 수 있음 => 예제5 참고
- 그리고 위 스샷에서처럼 컨슈머가 오프셋 11번을 가져갔다는 뜻은 이미 오프셋 0~10번 까지는 가져갔다는 것을 의미
카프카 로그 & 세그먼트(Kafka log & segment)

- 따라서, 카프카에 들어간 데이터는 (옵션으로 준) 일정기간, 일정용량에 따라서 언젠간 사라진다는 것을 알아둬야함
(예제1) 프로듀서 1개 <> 파티션이 3개인 토픽 <> 컨슈머가 1대인 경우

(예제2) 프로듀서 1개 <> 파티션이 3개인 토픽 <> 컨슈머가 3대인 경우

- 파티션이 3개이고 컨슈머가 3개인 경우 파티션과 컨슈머가 1대1 매칭됨
- 예제 1보다 예제 2의 경우 특정 토픽을 병렬처리하여 더 빠르게 처리할 수 있음
(예제3) 프로듀서 1개 <> 파티션이 3개인 토픽 <> 컨슈머가 4대인 경우 => 1대의 컨슈머가 놀게된다!!!
- (중요) 파티션갯수 >= 컨슈머갯수
- 즉, 파티션갯수보다 많은 컨슈머를 만들면 안된다.

(예제4) 컨슈머 3대 중 1대가 장애가 났을 경우

(예제5) 2개 이상의 컨슈머 그룹이 있는 경우

- 컨슈머 그룹 A에서 파티션 0번의 12번 데이터를 처리한 이후에도 컨슈머 그룹 B에서도 파티션 0번의 12번 데이터를 처리할 수 있음 <- 이게 카프카가 중추신경과 같은 역할을 할 수 있는 핵심적인 기능
- 장애에 대응하기 위해 재입수(또는 재처리) 목적으로 임시 신규 컨슈머 그룹을 생성하여 사용하기도 함
브로커 파티션 레플리케이션(Broker Partition Replication)

- 스샷의 명령어는 토픽을 생성하는 명령어인데, 이 명령어를 입력하면 스샷처럼 파티션 3개가 생김
bootstrap-server localhost:9092
=> localhost:9092에 내리는 명령이라는 뜻
- (참고 : 링크)

(상황) 카프카 브로커 이슈에 대응하기 위해 사용할 수 있는 방법은??
- 파티션을 다른 브로커에 복제하여 이슈에 대응가능
- 1번 브로커에 이슈가 생기면 다른 브로커에 복제된 데이터를 사용한다.


리더 파티션, 팔로워 파티션
- 기존에 사용하던 파티션을 "리더 파티션" 이라고 하고, 복제해서 사용하는 복제된 파티션을 "팔로워 파티션" 이라고 함
- 리더 파티션의 동작이 불가능할 경우 나머지 팔로워 중 1개가 리더 파티션이 됨


- 위에서 말하는 Kafka 클라이언트는 카프카 프로듀서/컨슈머 를 뜻함
ISR(In-Sync Replica), 리더와 팔로워의 싱크
- ISR : 리더 파티션의 오프셋이 만약에 0~100번까지 있다고했을때, 나머지 팔로우 파티션도 오프셋 0~100번까지 모두 완벽하게 복제되어 있을때 ISR 상태라고 한다. = 모두 싱크가 되어있다는 뜻
unclean.leader.election.enable값이 False인 경우
=> 예를 들어 3번 파티션의 리더 파티션이 있는 브로커 3번이 장애가 났고 0~100번 오프셋 까지 지니고있음 & 브로커1,2번에 복제된 파티션3번이 ISR상태가 아니면(0~90번 오프셋까지 가지고있음) 브로커 3번 복구될때까지 기다리라는 뜻
True
인 경우는 못가져온 91번~100번 오프셋까지 유실시키더라도 처리하라는 의미
- 실제로 프로듀서/컨슈머가 작동안할때 이부분을 살펴봐야함
- 보통은
False
로 둬서 브로커 3번이 복구될떄까지 기다리다가 작동안되는 경우가 많음
Kafka rack-awareness
- 서버 렉(Rack)과 서버
- 서버 렉이 내려가면 여러개의 서버가 한번에 내려감
- 이걸 방지하기위해서 Kafka rack-awareness 기능이 있음

- Kafka rack-awareness

주요개념 및 용어 정리
- 브로커(Broker) : 카프카 애플리케이션 서버 단위
- 프로듀서(Producer) : 레코드를 브로커로 전송하는 애플리케이션
- 컨슈머(Consumer) : 레코드를 polling하는 애플리케이션
- Consumer group: 다수 컨슈머 묶음
- Consumer offset: 특정 컨슈머가 가져간 레코드의 번호
- 토픽(Topic) ⊃ 파티션(Partition) ⊃ 오프셋(Offset)
- 파티션갯수보다 많은 컨슈머를 만들면 안된다.(파티션갯수 >= 컨슈머갯수)
- 토픽(Topic)
- 데이터가 보내지는 저장소 = 쉽게 생각하면 테이블과 유사하다고 생각하면 됨
- 토픽을 정하고 key를 적고 message를 보냄
- 데이터 분리 단위(파티션 하나생성되면 DB에서의 테이블이 하나 생성된다고 생각하면 됨)
- 토픽은 다수 파티션 보유
- 파티션(Partition) : 레코드를 담고 있음. 컨슈머 요청시 레코드 전달
- 오프셋(Offset) : 각 레코드당 파티션에 할당된 고유 번호
- Replication: 파티션 복제 기능
- ISR: 리더+팔로워 파티션의 sync가 된 묶음
- Rack-awareness : Server rack 이슈에 대응
- [카프카 브로커 여러개가 하나의 카프카 클러스터 이룸] <> [카프카 클라이언트(프로듀서 컨슈머)]
References
질문
- 보통 브로커 1개당 파티션 1개인가??
- 중추신경 카프카 부분에 프로듀서/컨슈머가 있는건지??