https://www.youtube.com/watch?v=0Ssx7jJJADI
해당 영상을 참고 하였다.
Kafka Cluster
- 메시지 저장하는 저장소
- 여러 개의 브로커로 구성
- 브로커가 각각의 서버 ( 메시지 나눠서 저장 , 이중화 , 장애 대처 등 수행 )
Zoo keeper
- Kafka Cluster 를 관리
- Kafka cluster 와 관련된 정보 포함
Producer
- Kafka cluster 에 Message 를 보냄
- Round Robin 이나 Key 를 통해 Partition 선택
- key 선택 시 , key 값을 통해 Hasing 하여 선정 ( 같은 key 는 순서 유지 보장 )
Consumer
- Kafka 에서 Message 를 읽어오는 역활
- Consumer 는 Consumer Group 에 속함
한 개 Partition 에는 한 개 Consumer 만 연결 가능 ⭐️
- 같은 Consumer Group 에 속한 Consumer 들은 같은 Partition 을 공유 불가능
( 다른 Consumer Group 들은 같은 Partition 공유 가능 )
- 한 Consumer 기준으로 Partition 의 Message 는 순서대로 처리
Topic
- Message 를 저장하는 단위 ( Message 구분하기 위해 사용 )
- 파일 시스템의 폴더 느낌 ( 뉴스 용 토픽 , 주문용 토픽 등등 )
- 한 개 이상의 파티션으로 구성
Partition
- Message 를 저장하는 물리적인 파일
- 추가만 가능한 ( append-only ) 파일 ( 물론 Kafka 자체가 조종 하긴 함)
- Message 저장 위치를 offset 이라고 함
- Producer 가 넣은 Message 는 Partition 맨 뒤 추가
- Consumer 는 offset 기준으로 Message 순서대로 읽음
- Message 는 삭제되지 않음 - 설정 따라 일정 시간 지난 뒤 삭제
Producer -> 0 1 2 3 4 5 6 <- Consumer
3 부터 탐색하라 할 시 , 3456 만 가능 ( 순서대로 )
=> Producer 는 Message 를 Kafka 에 저장 할 때 , 어떤 Topic 에 저장 해달라고 요청
=> Consumer 는 어떤 Topic 에서 읽어 올래라고 요청
성능
- Partition File 을 OS 제공 Page Caching 사용
=> 파티션에 대한 파일 IO 를 Memory 에서 처리
( Server 에서 Page Cache 를 Kafka 만 사용해야 성능상 유리 )
= Redis 와 비슷한 원리
- Zero copy
=> Disk Buffer 단위에서 Network Buffer 로 바로 복사 ( 속도가 빨라짐 )
- Broker 가 하는일은 단순화
- Message Filter , Message Retransmission 같은 일들은 Broker 수행 X
- Broker 는 Consumer - Partition 간 Mapping 만 관리
=> Consumer 와 Producer 에게 역활 전달
- 묶어서 보내고 , 묶어서 받기 ( Batch Programming )
- Producer : 일정 크기만큼 Message 모아서 전송
- Consumer : 최소 크기만큼 Mesasge 모아서 조회
=> 낱개 보다 처리량 증가
- 처리량 증가 ( 확장) 이 쉬움
- 1개 장비의 용량 한계? => Broker , Partition 추가
- Consumer 느릴시? => Consumer 추가 ( Partition 추가 )
리플리카
- Partition 의 복제본
- 복제수 만큼 파티션의 복제본이 각 브로커에 생성
- 리더 - 팔로워 로 구성 ( DB 다중화와 동일 )
- 장애 대응 - 리더 속한 브로커가 장애 시 , 다른 팔로워가 리더 승격
in Docker
services:
zookeeper:
image: bitnami/zookeeper:latest
container_name: zookeeper
ports:
- 2181:2181
environment:
- ALLOW_ANONYMOUS_LOGIN=yes
kafka:
image: bitnami/kafka:latest
container_name: kafka
depends_on:
- zookeeper
ports:
- 9092:9092
- 9094:9094
environment:
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_ENABLE_KRAFT=no
- KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
- KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://localhost:9094
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
kafka-ui:
image: provectuslabs/kafka-ui:latest
container_name: kafka-ui
depends_on:
- kafka
ports:
- 8080:8080
environment:
- DYNAMIC_CONFIG_ENABLED=true
- KAFKA_CLUSTERS_0_NAME=dragonsu_kafka
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka:9092
- kafka 는 언제나 , kafka 와 zookeeper 가 같이 구동되어야 함.
- kafka-ui 는 기호사항
in Nest
app.connectMicroservice<MicroserviceOptions>({
transport:Transport.KAFKA,
options:{}
})
- transport 를 KAFKA 로 선언할 시 , options 가 KAFKA 에 맞게 자동 Mapping
options?: {
postfixId?: string;
client?: KafkaConfig;
consumer?: ConsumerConfig;
run?: Omit<ConsumerRunConfig, 'eachBatch' | 'eachMessage'>;
subscribe?: Omit<ConsumerSubscribeTopics, 'topics'>;
producer?: ProducerConfig;
send?: Omit<ProducerRecord, 'topic' | 'messages'>;
serializer?: Serializer;
deserializer?: Deserializer;
parser?: KafkaParserConfig;
producerOnlyMode?: boolean;
};
- postfixId : Kafka Client 가 생성하는 고유 ID 에 접미사 추가 ( 여러 Client Instance 구분 용 )
- consumer : Kafka Consumer 설정 - 차후 설명
- producer : Kafka Producer 설정 - 차후 설명
- subscribe : Consumer 가 구독할 토픽 설정 시 사용
=> 특이한 게 , ConsumerSubscribeTopics type 에서 topics 만 Omit 된 Type
( fromBeginning : true : Topic 구독시, 이전 메시지 처음부터 받음 , false : 현재부터 처리)
- run : Consumer 실행 구성 설정 시 사용 - 차후 consumer 와 함께 설명
- send : Producer 가 Message 보낼때 사용 - 차후 producer 와 함께 설명
- serializer : 메시지 직렬화 하는 직렬화기 custom 지정시 사용
- deserializer : 메시지 역직렬화 하는 역직렬화기 custom 지정시 사용
- parser : 메시지 파싱 처리하는 파서 custom 지정시 사용
- producerOnlyMode : true 시 , Producer 모드로만 작동 ( Consuemr mode 비활성화 )
다음은 Producer 에 대해서 탐구해볼 예정
Writed By Obisidan