Kafka란?
pub-sub모델의 메세지 큐이다. 분산환경이 특화되어있다.
구성요소
1. Event: kafka에서 producer와 consumer가 데이터를 주고받는 단위
2. Producer: kafka에 이벤트를 게시(post)하는 클라이언트 어플리케이션을 의미합니다.
3. Consumer: topic을 구독하고 이로부터 얻어낸 이벤트를 처리하는 클라이언트 어플리케이션입니다.
4. Topic: 이벤트가 쓰이는 곳입니다. Producer는 이 Topic에 이벤트를 게시합니다. 그리고 Consumer는 Topic으로부터 이벤트를 가져와 처리합니다. Topic은 파일시스템의 폴더, 이벤트는 폴더안의 파일과 유사합니다.
Partition
Topic은 여러 Broker에 분산되어 저장되며, 이렇게 분산된 Topic을 Partition이라고 합니다. 어떤 이벤트가 Partition에 저장될지는 이벤트의 key에 의해 정해지며, 같은 키를 가지는 이벤트는 항상 같은 Partition에 저장됩니다.
Kafka의 주요 개념
Producer와 Consumer의 분리
Kafka의 Producer와 Consermer는 완전 별개로 동작한다. Producer는 Broker의 Topic에 메시지를 게시하고, Consumer는 Broker의 특정 Topic에서 메시지를 가져와 처리한다. 이러한 특성으로 인해 높은 확장성을 가지게 된다. 필요에 따라 Producer또는 Consumer를 스케일아웃하기에 용이한 구조이다.
Push와 Pull모델
kafka의 Consumer는 pull모델을 기반으로 메시지 처리를 진행한다.즉, Consumer가 필요할 때 Broker에서 메시지를 가져와 처리하는 형태이다.
이러한 특성으로 다음과 같은 장점이 있다.
1. 다양한 소비자의 처리형태와 속도를 고려하지않아도 된다.
2. 불필요한 지연없이 일괄처리를 통해 성능향상을 도모한다.
소비된 메세지 추적(Commit과 Offset)
메세지는 지정된 Topic에 전달된다. Topic은 다시 여러 Partition으로 나뉠 수 있다. 위 그림에서 각 파티션의 한칸한칸은 로그라고 칭합니다. 또한 메시지는 로그에 순차적으로 append됩니다. 그리고 이 메시지의 상대적인 위치를 offset이라 합니다.
메시징 시스템은 Broker에게 소비된 메시지에 대한 메타 데이터를 유지합니다. 즉, 메시지가 Consumer에게 전달되면 Broker는 이를 로컬에 기록하거나 소비자의 승인을 기다립니다.
Commit과 Offset
Consumer의 poll()은 이전에 commit한 offset이 존재하면, 해당 offset 이후의 메시지를 읽어오게 됩니다. 또 읽어온 뒤, 마지막 offset을 commit합니다. 이어서 poll()이 실행되면 방금전 commit한 offset이후의 메시지를 읽어와 처리하게 됩니다.
발생 가능한 문제점
1. 소배된 메시지 기록시점
Broker가 메시지를 통해 Consumer에게 전달할때마다 즉시 소비한것으로 기록하면 Consumer가 메시지 처리를 실패할 경우 해당 메시지가 손실됩니다. 따라서 Broker는 메시지가 소비되었음을 기록하기 위해 Consumer의 승인을 기다립니다. 그러나 이로 인해 문제점이 또 발생합니다.
2. 중복 메시지와 멱등성
Consumer가 메시지를 성공적으로 처리하고 승인을 보내기 전에 Broker가 실패하였다고 판단하여 다시 메세지를 보내면 Consumer는 메세지를 중복처리하게됩니다.
따라서 Consumer는 멱등성을 고려하여야합니다. 즉, 메세지 중복 처리할 경우 한번 처리한것과 같은 결과를 가지도록 설계하여야 합니다.
Consumer Group
Consumer Group은 하나의 Topic을 구독하는 여러 Consumer들의 모음입니다. Topic을 구독하는 Consumer들을 Group화하는 이유는 가용성 때문입니다.
Consumer Group의 각 Consumer들은 하나의 Topic의 각기 다른 Partition 내용을 처리할 수 있고, 이를 통해 Kafka는 메시지 처리 순서를 보장한다고 합니다. 따라서 특정 Partition을 처리하던 Consumer가 처리 불가 상태가 된다면, 해당 Partition의 메시지를 처리할 수 없는 상태가 되어버립니다.
Rebalance
Partition을 담당하던 Consumer가 처리 불가 상태가 되어버리면, Partition과 Consumer를 재조정하여, 남은 Consumer Group내의 Consumer들이 Partition을 적절하게 나누어 처리하게 됩니다. 또한, Consumer Group내에서 Consumer들 간에 Offset정보를 공유하고 있기 때문에, 특정 Consumer가 처리불가 상태가 되었을때, 해당 Consumer가 처리한 마지막 Offset이후부터 처리를 이어서 할 수 있습니다.
이렇게 Partition을 나머지 Consumer들이 다시 나누어 처리하도록 하는 것을 Rebalance라고 하며, 이를 위해 Consumer Group이 필요합니다.
Consumer Group과 Partition
무조건, Consumer Group내의 Consumer들은 모두 각기 다른 Partition에 연결되어야 합니다. 이를 통해 Consumer의 메시지 처리 순서를 보장하게 됩니다.
Consumer의 확장
Consumer의 성능이 부족해 Consumer를 확장한다고 했을 때, Consumer Group내의 무조건 각기 다른 Partition에만 연결을 할 수 있다고 했습니다. 따라서 Consumer만 확장하여 Partition보다 Consumer의 수가 많으면 새 Consumer는 놀게 게됩니다. 따라서 Consumer를 확장할 때 Partition도 같이 늘려주어야 합니다.
메시지(이벤트) 전달 컨셉
1. at most once(최대 한번): 메세지가 손실될 수 있지만, 재전달은 하지 않습니다.
2. at least once(최소 한번): 메세지가 손실되지 않지만, 재전달이 일어납니다.
3. exactly once(정확히 한번): 메세지는 정확히 한번 전달이 됩니다.
[출처]https://galid1.tistory.com/793
'스프링' 카테고리의 다른 글
스프링, 스프링 부트 접미사 (0) | 2022.04.24 |
---|---|
Spring Annotation 정리 (0) | 2022.04.16 |
스프링 배치 프로세스 (0) | 2022.04.16 |
ORM과 JPA에 대하여 (0) | 2022.03.29 |
[스프링] IoC(Inversion of Control)와 DI(Dependency Injection) (0) | 2021.09.08 |