About Kafka Basic
Topics
데이터베이스에서 테이블과 비슷한 개념으로 특정한 stream of data 으로 구성된다.
원하는 만큼 생성할 수 있고, 이름으로 토픽을 식별한다.
모든 데이터 형식을 지원한다.
- json
- avro
- text
- binary
카프카 프로듀서가 데이터를생산하고, 카프카 컨슈머가 데이터 읽는다.
Partitions & Offsets
토픽은 여러개의 파티션으로 구성된다.
메세지는 파티션내에서 순서대로 저장된다. 토픽 레벨에서 메세지 순서를 보장하지 않는다.
각각 메세지는 파티션내에서 증분 id 를 가지고 이를 kafka partition offsets 이라 한다. 따라서 offset 은 특정 파티션내에서만 의미를 갖는다.
카프카 토픽은 immutable 이다. 한 번 파티션에 데이터가 쓰여지면 변경이 불가능하다.
데이터는 정해진 시간내에서만 존재한다. 기본값은 1주일이다.
프로듀서에서 데이터에 key 를 지정하지 않으면 랜덤으로 파티션에 할당된다.
파티션 개수는 원하는 만큼 지정할 수 있다.
Producer
데이터를 토픽에 쓰는 역할을한다.
프로듀서에서 어느 토픽에 어느 파티션에 데이터를 쓸 지 정할 수 있다.
Producer Message Key
프로듀서는 메세지를 key 와 함께 전송할 수 있다.
key 가 null 이면 라운드로빈 방식으로 파티션에 데이터가 전송된다.
해싱 전략(murmur2)으로 항상 동일한 파티션으로 할당할 수 있다.
- key - binary (can be null)
- value - binary (can be null)
- compression type (none, gzip, snappy, lz4, zstd)
- headers (optional)
- key value
- partition + offset
- timestamp (system or user set)
Kafka Message Serializer
카프카는 프로듀서로부터 그리고 컨슈머로 bytes 만 input 과 ouput 으로 취급한다.
objects 를 bytes 로 시리얼라이징 해야 한다.
- String
- Int, Float
- Avro
- Protobuf
Consumers
Pull Model 로 이름으로 식별하여 토픽으로 부터 데이터를 읽는다.
오름차순으로 데이터는 파티션내에서 순서대로 읽는다. 토픽내에서는 순서를 보장하지 않는다.
Consumer Desrializer
bytes 를 어떻게 objects 로 변환할지 역할을 맡는다.
- String
- Int, Float
- Avro
- Protobuf
serialization / deserialization type 은 topic 이 운영중에 바뀌면 안된다. 호환성이 변경이 필요한 경우 새로운 토픽을 생성해야한다.
Consumer Groups
각각 컨슈머는 그룹내에서 서로 배타적인 파티션을 점유하게 된다.
컨슈머 그룹에서 컨슈머가 파티션 수보다 많다면 특정 컨슈머는 비활성화 상태로 어떤 파티션도 점유하지 않는다.
하나의 토픽에 여러 컨슈머 그룹을 할당할 수 있다. group.id 프로퍼티를 사용해서 컨슈머 그룹을 식별할 수 있다.
Consumer Offsets
카프카는 각각의 컨슈머 그룹이 어디까지 읽었는지 오프셋을 저장한다.
오프셋은 __consumer_offsets 이라는 토픽에 커밋된다.
컨슈머가 카프카에서 데이터를 받고 처리 후, 정기적으로 오프셋을 커밋한다. 카프카 브로커가 __cosumer_offsets 토픽에 쓴다. 컨슈머 장애발생 시, 읽었던 곳부터 읽을 수 있게 해준다.
Delivery semantics for consumers
기본 설정으로, Java consumer 는 자동 커밋을 한다.(at least once)
At least once
- 메세지가 처리된 후 오프셋이 커밋된다.
- 처리가 실패한 경우, 메세지는 다시 읽을 수 있다.
- 중복 처리가 발생할 수 있다. 멱등성을 갖춘 컨슈머를 구비해야 한다.
At most once
- 오프셋은 메세지를 받자마자 커밋한다.
- 처리가 실패한 경우, 메시지를 다시 처리할 수 없다.
Exactly once
- Kafka Stream 의 Transaction API 를 통해서 메시지 전송이 정확히 한 번만 이루어지도록 할 수 있다. 프로듀서가 멱등성을 제공하여 중복 전송을 방지한다.
- 오프셋 관리는 정확히 한 번만 처리하도록 설계가 필요하다.
Kafka brokers
다수의 브로커로 구성되어 있는것을 카프카 클러스터라고한다.
각 브로커는 integer id 로 식별할 수 있다.
각 브로커는 특정 토픽의 파티션을 포함한다.
bootstrap broker 에 연결하면 kafka client 가 전체 클러스터에 연결할 수 있도록 해준다.
브로커의 개수는 3 ~ 100 개가 넘도록 다양하다.
Kafka Broker Discovery
모든 카프카 브로커는 "bootstrap server" 라고 부른다. 클러스터에서 하나의 브로커만으로 연결이 가능하다. kafka client 는 똑똑해서 이후에 전체 클러스터에 연결할 수 있도록 해준다.
Topic replication factor
토픽은 replication factor 를 가진다. 브로커가 다운되었을 때 다른 브로커가 살아있어서 여전히 운영이 가능하다.
A 토픽에 파티션이 2개고 브로커가 3개 일 때 replication factor 를 2로 설정하면, 아래와 같이 배치될 수 있다. 만약 브로커 102 가 다운되어도, 101, 103 이 계속해서 운영이 가능하다.
Concept of Leader for a Partition
항상 하나의 브로커가 파티션의 리더가 될 수 있다. 프로듀서는 파티션의 리더에만 데이터를 전송 수 있다. 리더가 아닌 브로커는 데이터를 복제한다. 각 파티션에서는 하나의 파티션 리더와 다수의 ISR (in-sync-replica) 로 구성된다.
Producer Acknowledgements (acks)
프로듀서는 쓰기가 성공적으로 이루어졌다는 확인을 브로커로부터 받을 수 있다.
acks=0 -> 프로듀서가 acknowledgement 를 기다리지 않는다. 이로 인해 브로커가 다운되어도 모를 수 있 data 손실이 발생할 수 있다.
acks=1 -> 프로듀서는 파티션 리더의 acknowledgement 를 기다린다. 데이터 손실이 적어진다.
acks=all -> 리더와 레플리케이션 모두 acknowledgment 를 기다린다. 데이터 손실이 없다.
Kafka Topic durability
replication factor 가 3 일 때, 토픽 내구성은 2개의 브로커가 다운되어도 운영할 수 있다.
replication factor 가 2 일 때, 토픽 내구성은 1개의 브로커가 다운되어도 운영할 수 있다.
replication factor 가 N 일 때, 토픽 내구성은 N-1 개의 브로커가 다운되어도 운영할 수 있다.
Zookeeper
주키퍼는 카프카 브로커를 관리한다.
주키퍼는 파티션의 리더 선정을 돕는다. 브로커가 다운될 때마다 새로운 파티션 리더 선출이 필요하다.
주키퍼는 새로운 토픽이 생성되거나, 브로커가 다운되거나 새로 생기거나 토픽이 삭제되었을 때 알림을 보낸다.
주키퍼는 kafka 2.x 버전까지는 필수다.
kafka 3.x 는 주키퍼 없이 Kafka Raft 를 사용해서 동작할 수 있다.
kafka 4.x 은 주키퍼가 아예 없다.
주키퍼는 홀수로 동작하도록 설계 되었다. 보통 7개를 사용한다.
주키퍼는 리더와 팔로워로 구성된다.
주키퍼는 컨슈머의 오프셋을 저장하지 않는다. 과거 kafka v.0.10 이하 버전에서는 주키퍼가 관리했다.
댓글
댓글 쓰기