카프카는 이벤트 스트리밍 플랫폼으로
이벤트 소스 즉 DB와 같은 곳에서 데이터를 실시간으로 전달하는 역할을 한다.
이 수집한 데이터를 처리, 저장, 조회가 가능하다.
1 이벤트 스트림을 발행하고 구독하여 다른 시스템에 있는 데이터를 내보내거나 가져온다.
2 데이터를 원하는 기간동안 저장이 가능하다.
3 이벤트 발생시 실시간으로 처리
카프카는 카프카 클러스터와 카프카를 이용하는 클라이언트로 구성된다.
이때 클러스터는 카프카가 단일로 구동될 수 있는 구성 집합을 말한다.
구성 요소로는
브로커
주키퍼(kraft)
프로듀서
컨슈머
토픽
등 위와 같은 요소들이 하나의 집합 클러스터라고 한다.
위 카프카 클러스터는 클라이언트와 TCP 프로토콜 통신을 한다.
카프카는 또 다른 카프카 클러스터와 kafka connect를 통해 동기화 및 사용이 가능한다.
각각 다른 언어들의 서버들마다 라이브러리를 통해 이벤트 스트림을 생성, 이용이 가능하다.
컨슈머들과 프로듀셔들은 이 브로커와 연결하여 데이터를 저장하고 전송한다.
이 브로커는 하나의 카프카 클러스터에 여러 개가 존재할 수 있다.
브로커가 여러 개면 한 브로커에 장애가 나도 다른 브로커가 나머지 데이터를 제공해 가용성을 높일 수 있다.
이 브로커들은 프로듀서들의 요청에 의해 토픽에 데이터를 저장 하거나 메세지를 컨슈머들에게 전송할 수 있다.
카프카 클러스터에서는 메타데이터를 관리하는 컨트롤러가 있다.
예전에는 Zookeeper가 이 역할을 했고, 최근에는 KRaft 기반 컨트롤러 쿼럼이 Zookeeper를 대체하고 있다.
컨트롤러는 어떤 토픽/파티션이 어떤 브로커에 할당되는지,
각 파티션의 리더를 어떤 브로커가 맡을지를 결정하고,
브로커가 추가되거나 장애가 발생했을 때 리더를 다른 브로커로 옮기는 등 메타데이터를 재조정해서 클러스터를 관리한다.
하나의 토픽에 대해 여러 파티션으로 나뉜 이유는
하나의 토픽을 여러 파티션으로 나누는 이유는 확장성과 병렬 처리 때문이다.
쪼개진 파티션 단위로 프로듀서/컨슈머가 병렬로 쓰고 읽을 수 있어서, 스루풋을 수평 확장할 수 있고,
하나의 파티션 내부에서는 순서가 보장되기 때문에, 키 단위로 순서를 유지하면서도 전체적으로는 병렬 처리가 가능합니다.
각 파티션은 여러 브로커에 복제본이 존재하고, 그 중 하나가 리더, 나머지가 팔로워를 맡습니다.
프로듀서와 컨슈머는 항상 리더가 있는 브로커와 통신해서 해당 파티션에 데이터를 쓰거나 읽고,
팔로워들은 리더의 로그를 따라가면서 자기 로컬 디스크로 데이터를 복제합니다.
메타데이터 관리와 리더 선출은 예전에는 Zookeeper, 최근에는 KRaft 기반 컨트롤러가 담당한다.
카프카는 분산 로그 기반의 메시지 브로커라서, 대규모 트래픽 환경에서 데이터를 안정적으로 저장하면서도 고성능으로 전송할 수 있다는 게 장점이다.
파티션 단위 수평 확장으로 프로듀서/컨슈머를 늘려서 처리량을 쉽게 올릴 수 있고,
디스크에 데이터를 지속적으로 보관(retention)하면서, 필요한 시점에 다시 읽어오는 리플레이가 가능하다.
또, 여러 마이크로서비스들이 카프카를 기준으로 느슨하게 결합된 이벤트 기반 아키텍처를 구성할 수 있어서, 직접 서로를 동기 호출하는 것보다 변경에 강한 구조를 만들 수 있습니다.
카프카는 분산 로그 시스템이다.
각 토픽은 여러 파티션으로 나뉘고, 파티션은 디스크에 append-only(stack의 append와 같음) 로그로 저장됩니다. 새 메시지는 항상 로그의 끝에만 붙고, 각 메시지는 offset이라는 순서 번호를 가진다.
컨슈머 그룹은 각 파티션에 대해 “내가 마지막으로 처리한 offset”을 저장해 두었다가, 재시작 시 그 다음 offset부터 읽어 나갑니다. 읽는다고 해서 메시지가 바로 삭제되지는 않고, 토픽의 retention 설정에 따라 일정 시간이 지나거나 용량이 넘으면 오래된 로그 세그먼트가 삭제됩니다.
하나의 토픽은 여러 파티션으로 나뉘고, 각 파티션의 복제본은 여러 브로커에 분산되어 저장되기 때문에, 용량·처리량을 수평 확장할 수 있고, 브로커 장애가 나도 다른 replica를 통해 계속 서비스를 유지할 수 있다.
rabitMQ같은 메세지 브로커는 전형적인 queue형식의 데이터 저장 방식으로 소비되면 큐에서 사라진다