Kafka를 파헤치기 전, 메시징 시스템에 대해 알아보자.
Kafka
, RabbitMQ
, Active MQ
, AWS SQS
, Java JMS
등Pub
/Sub
구조MOM
기반 구축Message Broker
와 MOM
을 구현한 소프트웨어 (RabbitMQ, Active Mq, Kafka 등)MOM
은 메시지 전송을 보장 해야하므로 AMQP
를 구현한다.MQ
는 "AMQP를 구현한 MOM 시스템이다." 물론, 각 소프트웨어 마다 장단점이 있다.로그 데이터
, 이벤트 메시지
등 API로 호출할 때 보내는 데이터들을 처리하는 시스템MemberService
OrderService
MailService
MemberService
에서 회원가입, OrderService
에서 주문완료 이벤트 발생Messaging Client
로 메일 전송에 필요한 데이터를 API로 호출Messaging Client
에서 MOM
을 구현한 소프트웨어(ex) Kafka)로 메시지 생산MailService
에서 메시지가 존재하는지 구독하고 있다가 메시지가 존재하면 메시지 소비MailService
에서 API 정보들을 통해 User에게 메일 발송Message Broker
에게 위임Message Client
를 통해 메시지를 보내고 받기만 함Message Broker
에서 순서 보장 + 메시지 전송 보장Message Broker
구축Broker
에 분산 천리된 메시지 큐의 정보들을 관리Zookeeper
는 클러스터를 관리하기 때문에 Zookeeper
가 없다면 Kafka
구동 불가Kafka
서버를 가동하기 위해서 Zookeeper
를 먼저 가동해야 한다.Kafka
의 서버Broker
를 띄울 수 있다.Topic
내, 메시지가 분산되어 저장되는 단위Topic
에 Partition
이 3개 있다면, 3개의 Partition
에 대해 메시지가 분산 저장 되어있음을 의미한다. Queue
로 저장, Partition
내 순서는 보장되지만, Partition
끼리는 메시지 순서를 보장하지 않는다.Partition
의 한 칸key
, value
, timestamp
로 구성Partition
의 메시지 식별값(unique)Consumer
가 읽을 차례를 의미. -> Partition
마다 별도로 관리0
시작, 1
씩 증가메시지 생산/소비
Producer
Producer
는 정해진 Topic
으로 메시지를 기록Partition
이 여러 개일 경우, 기록될 Partition
의 선택은 기본적으로 Round-Robin 스케줄링 알고리즘 방식을 채택Partition
은 병렬 처리라는 장점이 있지만, 갯수는 주의해서 설정해야한다.Partition
내에서는 마지막 offset
뒤에 신규 메시지가 저장되므로, Partition
내에서는 순서가 보장되고 기록된다.Consumer Group
Consumer Group
은 하나의 Topic
을 담당Topic
은 여러 Consumer Group
에 접근 가능Consumer Group
은 한 Topic
에 접근 가능Consumer Group
)이 perter-topic(Topic
) 데이터를 가지고 있을 때, 서버 1개(server1
- Consumer Instance
)가 장애가 발생해도 나머지 서버들을 통해 계속해서 작업을 이어갈 수 있다.A
, B
가 있고, 두 사용자가 동일한 topic
에 대한 데이터를 가져가고 싶다. Consumer Group
은 없다.A
가 1, 2, 3의 데이터를 가져갔고 next(offset
)를 4로 설정Consumer Group
이 없기 때문에 Kafka
는 Consumer
가 연결됐을 뿐, 구분을 하지 못한다.B
가 데이터를 가져올 때, A
가 저장한 offset
정보부터 데이터를 가져온다.A
가 다음으로 가져오기를 희망한 데이터는 4지만 offset
이 그 다음으로 설정되었기 때문에 문제가 발생한다.Kafka
에서 Consumer Group
마다 이름을 지정하여 구분하고, 그룹별로 offset
을 관리Consumer Group
이 Topic
에 있는 데이터를 가져올 때, 하나의 Topic
이지만 그룹별로 각 다른 데이터를 가져오고, offset
을 설정한다.Partition(P)과 Consumer(C)의 관계
Kafka
의 Consumer Instance 제약사항ordering
(순서) 보장하기 위함 (=> Partition
갯수 < Consumer Instance
, 불가능)Consumer Instance
)를 늘리자!Consumer Instance
를 늘렸지만, 1개의 파티션은 1개의 컨슈머 인스턴스만 접근 가능하다. => 소용이 없다.Consumer Instance
가 죽었지만 Consumer Group
에서 offset
이 공유되기 때문에 이상이 없다.Partition
3개로 줄이고자 했지만 Partition
은 늘리면 줄일 수 없다.RabbitMQ
와 Kafka
비교)Kafka
는 Multi Consumer를 염두에 두고 설계됐다.Message Broker
가 Consumer
에게 pushConsumer
에게 부하RabbitMQ
는 DRAM
(buffer)를 사용하지만, DRAM
을 다 사용하면 디스크
에 저장 => batch
같은 큰 작업에서 디스크
로 메시지를 읽어올 경우 지연된다.Consumer
가 Message Broker
에게 pullConsumer
가 처리할 수 있을 때! 메시지를 가져온다. => 자원의 효율적 사용Kafka
는 메시지를 애초 디스크
에 저장하고 이미 처리한 과거의 offset
으로 자유롭게 움직이므로 batch
와 같은 큰 작업에서 낭비와 지연이 없다.long poll 대기
가 가능한 parameter
지원Topic
을 생성할 때, 옵션(--replication-factor
)을 부여하면 복제본을 생성할 수 있다.Replication
: Zookeeper
가 leader
가 되는 Partition
을 정하고, 해당 Partition
을 다른 Broker
로 복제하는 것. 이 때, leader
를 복제하는 Partition
을 follower
라고 한다.leader
: 메시지를 생산하고 소비하는 작업은 모두 leader
에서 이뤄짐follower
: leader
를 복제만 함.leader
가 죽으면 follower
중 하나가 leader
가 되어야 한다. (follower
는 leader
와 싱크를 맞추고 있다. (= In-Sync Replica, ISR))Broker
, 1개의 Topic
, 4개의 Partition
--replication-factor=2
로 설정, => 각 Partition
들이 factor
값만큼 Broker
에 분배됨leader
가 존재하는 브로커 2에서 메시지가 생산된다. 브로커 3에 있는 follower
가 leader
를 복제 (ISR)leader
가 다운되면, follower
가 새로운 leader
로 선출된다.follower
가 여러 개일 경우에는 Zookeeper가 leader를 알아서 선출log.retention.hours
를 통해 설정, default
는 7일Consumer
가 메시지를 소비한다고 메시지가 없어지는 것이 아니라, 메시지 보존 기간이 끝나야 사라진다.Consumer
가 과거의 offset
에 대한 접근 가능의 이유