구성
- 하나의 Broker는 여러 개의 Topic으로 구성되어 있습니다.
- 하나의 Topic은 여러 개의 Partition으로 구성되어 있습니다.
- 하나의 Partition은 여러 개의 Replica를 가질 수 있습니다.
- 읽기 및 쓰기 작업을 진행하는 Partition을 Leader Replica, Leader를 복사하는 작업만 하는 Partition을 Follower Replica라고 합니다.
- Leader의 동작이 멈출 경우 in-sync Replica중 하나가 Leader로 선출됩니다.
- 카프카는 Leader와 Replica를 다른 토픽에, Replica끼리도 다른 토픽에 분산하는 걸 권장합니다.
- 여러 브로커의 묶음을 Kafka cluster라고 합니다.
- Zookeeper는 각 브로커를 관리하는 소프트웨어입니다.
- 카프카3.0부터 주키퍼 대신 Raft를 사용할 수 있습니다. Raft를 사용하면 주키퍼를 별도로 실행시킬 필요가 없습니다.
- 특별한 역할을 하는 Broker를 Controller와 Coordinator라는 이름으로 부릅니다.
- Controller는 파티션 리더를 선출하는 역할을 합니다.
- Controller는 클러스터 내의 브로커가 사용할 수 없게 되었을 때, 해당 브로커의 토픽에 있는 리더 파티션의 리더 역할을 같은 클러스터 내에 정상 동작하는 다른 브로커 속 토픽의 다른 파티션에게 넘겨줍니다.
- Coordinator는 Consumer Group의 리밸런싱을 돕습니다.
- Coordinator는 컨슈머 그룹의 상태를 체크하여 컨슈머 그룹 내 컨슈머에 장애가 발생해 매칭된 파티션의 데이터를 consume할 수 없게 되었을 때, 장애가 발생한 컨슈머에게 매칭된 파티션을 정상 작동하는 다른 컨슈머에게 매칭해 줍니다.
프로듀서
- 카프카에 메시지를 쓰기 위해서는 ProducerRecord객체를 생성해야 합니다. ProducerRecord는 자신이 저장될 위치인 Topic, 저장할 값인 Value는 필수로 입력해야 합니다. key와 partition은 필수로 작성하지 않아도 됩니다.
- ProducerRecord를 전송하기 위한 send()를 호출했을 때 프로듀서는 Serializer를 통해 key와 value가 네트워크 상에서 전송될 수 있도록
직렬화해서 바이트 배열로 변환
하는 과정을 거칩니다.
- ProducerRecord가 파티션을 명시적으로 지정하지 않았다면 프로듀서는 해당 데이터를 Partitioner에게 전달합니다. Partitioner는 ProducerRecord의 Key값을 가지고 해당 데이터가 저장될 파티션을 결정합니다.
- 메시지가 전송될 토픽과 파티션이 확정되면 프로듀서는 이 레코드를 같은 토픽 파티션으로 전송될 레코드들을 모아둔
레코드 배치
라는 곳에 추가시킵니다.
- 추후 별도의 스레드가 이 레코드 배치를 적절한 카프카 브로커에게 전송하게 됩니다.
- 브로커는 메시지를 받으면 응답을 돌려주게 됩니다.
- 메시지가 성공적으로 저장되었을 경우 브로커는 토픽, 파티션, 해당 파티션 안에서의 레코드 오프셋을 담은 RecordMetadata를 리턴해 줍니다.
- 메시지 저장에 실패했을 경우 에러가 리턴됩니다.
컨슈머
- 컨슈머는 보통 컨슈머 그룹의 일부로 동작하게 됩니다. 컨슈머 그룹이 토픽을 구독하게 되면, 동일한 컨슈머 그룹에 속한 여러 개의 컨슈머는
서로 다른 파티션의 메시지
를 읽게 됩니다.
- 가장 먼저 그룹에 참여한 컨슈머는 해당 그룹의 리더가 됩니다. 리더는 그룹 코디네이터로부터 해당 그룹 안에 있는 모든 컨슈머의 목록을 받아 각 컨슈머에게 파티션들을 할당해 줍니다.
- 프로듀서가 보낸 메시지가 모든 인-싱크 레플리카에 쓰여지기 전까지는 컨슈머들이 메시지를 읽을 수 없습니다.
- 모든 인-싱크 레플리카에 값이 쓰여지기 전에 데이터를 요청하면
에러가 아닌 빈 응답
을 반환받게 됩니다.
- 이렇게 동작하는 이유는 충분한 수의 레플리카에 복제가 완료되지 않은 메시지를 '불안전한' 메시지로 간주하기 때문입니다. 충분한 복제가 일어나지 않은 데이터를 소비했다가 해당 리더 파티션에 크래시가 발생하면 일관성이 결여될 수 있습니다.
References