
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로 호출할 때 보내는 데이터들을 처리하는 시스템MemberServiceOrderServiceMailServiceMemberService에서 회원가입, 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에 대한 접근 가능의 이유