Apache Kafka 의 주요 요소
- Topic, Producer, Consumer
Producer : 메시지를 생산해서 Kafka의 Topic으로 메시지를 보내는 애플리케이션
Consumer : Topic의 메시지를 가져와서 소비하는 애플리케이션
Consumer Group : Topic의 메시지를 사용하기 위해 협력하는 Consumer들의 집합
하나의 Consumer는 하나의 Consumer Group에 포함되며, Consumer Group내의 Consumer들은 협력하여 Topic의 메시지를 분산 병렬 처리한다.
Producer 와 Consumer 의 기본 동작 방식
Producer와 Consumer는 서로 알지 못하며, Producer와 Consumer는 각각 고유의 속도로 Commit Log에 Write, Read를 수행
다른 Consumer Group에 속한 Consumer들은 서로 관련이 없으며, Commit Log에 있는 Event를 동시에 다른 위치에서 Read할 수 있다.
Kafka Commit Log
Commit Log : 추가만 가능하고 변경 불가능한 데이터 스트럭처, 데이터(Event)는 항상 로그 끝에 추가되고 변경되지 않는다.
Offset : Commit Log에서 Event의 위치, 아래 그림에서는 0부터 10까지의 Offset을 볼 수 있다.
Producer가 Write하는 LOG-END-OFFSET 과 Consumer Group의 Consumer가 Read하고 처리한 후에 Commit한 CURRENT-OFFSET 과의 차이(Consumer Lag )가 발생할 수 있다.
Topic, Partition, Segment
Topic : Kafka안에서 메시지가 저장되는 장소. 논리적인 공간
Partition : Commit Log . 하나의 Topic은 하나 이상의 Partition으로 구성. 보통은 병렬 처리를 위해 다수의 Partition 사용.
Segment : 메시지(데이터)가 저장되는 실제 물리 File. Segment File이 지정된 크기보다 크거나 지정된 기간보다 오래되면 새 파일이 열리고 메시지는 새 파일에 추가된다.
조금 더 구체적으로 들여다보면,
Topic 생성 시 Partition의 개수를 지정 하고, 각 Partition은 Broker들에 분산되며 Segment File들로 구성된다.
Rolling Strategy : log.segment.bytes(default 1GB), log.roll.hours(default 168 hours)
Active Segment
Partition당 하나의 Active Segment가 존재하는데, 이게 무슨 말이냐면,
특정 Partition에는 Segment가 있고, 이 파일이 실제 데이터가 저장되는 파일인데 크기 또는 시간이 지정한 값보다 더 커지면 새로운 파일을 만들어 그 파일에 저장한다고 했다. 그리고 현재 저장되는 파일을 Active Segment 파일이라고 부른다.
Partition당 오직 하나의 Segment가 활성화(Active)되어 있다.
Active된 Segment가 아닌 파일에는 변경이 불가능하다.
정리를 하자면
Topic 생성 시, Partition 개수를 지정한다. 개수 변경은 이후에도 가능하나 운영시에는 변경 권장하지 않는다. 그 이유는 이후에 설명한다.
Partition의 번호는 0부터 시작하고 오름차순
Topic 내 Partition 들은 서로 독립적
Event(Message)의 위치를 나타내는 Offset이 존재
Offset은 하나의 Partition에서만 의미를 가진다. 즉, Partition 0번의 Offset 1 은 Partition 1의 Offset 1과 아무런 관련이 없다.
Offset 값은 계속 증가하고 0으로 돌아가지 않는다.
Event(Message)의 순서는 동일한 Partition 내에서만 보장
Partition에 저장된 데이터(Message)는 변경이 불가능(Immutable)
Partition에 Write되는 데이터는 맨 끝에 추가되어 저장
Partition은 Segment File들로 구성되고, Rolling 정책은 log.segment.bytes(default 1GB), log.roll.hours(default 168 hours)