-
Apache Kafka 개념 정리데엔 공부 2024. 11. 25. 15:10
패스트캠퍼스에서 인강을 들으면서 공부한 Apache Kafka의 개념을 줄줄줄 써보려고 한다.
읽기 편하게 정리하면 좋겠지만 우선은 보면서 적은 메모를 붙여 넣고, 이후에 틈틈히 재정리할 예정이다.
Apache Kafka
Event Streaming Platform
- 이벤트 스트림을 전송
- 이벤트 스트림을 디스크에 저장
- 이벤트 스트림을 분석 및 처리
Topic: kafka 안에서 메시지가 저장되는 장소. 논리적인 표현.
Partition: Commit Log, 하나의 토픽은 하나 이상의 파티션으로 구성. 병렬처리를 위해 다수의 파티션 사용(Troughput 향상) 서로 독립적.
Segment: 메시지(데이터)가 저장되는 실제 물리 File.
Topic 생성 시 Partition 개수 지정, 각 Partition은 브로커들에 분산되고 Segment File들로 구성됨. 파티션 개수 변경 가능하지만 운영 시에는 권장 안함
Partition 당 오직 하나의 Segment만 활성화됨. 데이터가 계속 쓰여지는 중.
Rolling Strategy: log.segment.bytes(default 1GB), log.roll.hours(default 168 hours)
- 최대 1GB, 7일까지 저장 이후 새로운 Segment 만들어서 사용
Producer: 메시지를 만들어서 topic으로 전송
Consumer: topic의 메시지를 가져가서 비즈니스에 활용
Consumer Group: topic의 메시지 사용하기 위해 협력하는 Consumer의 집합
하나의 Consumer는 하나의 Consumer Group에 포함
Producer와 Consumer는 분리되어있음 서로 알지 못함. 각각의 고유의 속도로 커밋로그를 쓰고 읽기 수행
Commit Log: 추가만 가능하고 변경 불가능한 데이터 구조. 데이터(이벤트)는 항상 로그 끝에 추가되고 변경되지 않음.
Offset: 커밋 로그에서 이벤트의 위치. 0부터 쭉 증가. 0으로 돌아가지는 않음
Event(Message)의 순서는 하나의 Partition 내에서만 보장
Partition에 저장된 데이터는 변경 불가
Partiton에 Write되는 데이터는 맨 끝에 추가저장됨
Consumer는 각각 고유의 속도로 Commit log로부터 순서대로 read(poll)수행
데이터 읽은 위치에서 Commit하여 다시 읽음 방지
4개 파티션, 1개 컨슈머인 경우, 각 파티션에서의 오프셋 기록유지
파티션은 컨슈머 그룹 중 단 하나의 컨슈머에 의해 동작
동일한 group.id로 구성된 컨슈머들은 하나의 컨슈머 그룹
Partition = Hash(Key) % Number of Partitions
파티션이 두개 이상인 경우, 모든 메시지에 대한 전체 순서 보장 불가
> 컨슈머가 각각 파티션으로 동작하기 때문.
파티션이 한개면 모든 메시지 전체 순서 보장 가능하나, 처리량 저하됨
카프카는 병렬처리를 위한 시스템
대부분의 경우는 key로 구분되는 메시지들의 순서보장이 필요함
동일한 key를 가진 메시지는 동일한 파티션에 전달되어 key레벨 별 순서 보장 가능
> 멀티 파티션 사용 = 처리량 증가
운영 중에 파티션 개수 변경 시, 순서 보장 불가 . .
> 파티션 번호가 뒤섞이기 때문
Cardinality : 특정 데이터 집합에서의 유니크한 값의 개수
Kery Cardinality는 컨슈머 그룹의 개별 컨슈머가 수행하는 작업량에 영향
Key는 Avro, JSON 등 여러 필드가 있는 복잡한 객체일 수 있음
파티션 전체에 Record를 고르게 배포하는 Key를 만들어야 함!
장애가 난 컨슈머가 있으면, 다른 컨슈머가 Consume 할 수 있도록 가져감 (리밸런싱)
컨슈머는 주어진 토픽에서 0개 이상의 많은 파티션 사용 가능
1-6. Replication
Broker 장애 발생 시, 장애가 발생한 Broker의 파티션 사용 불가
> Consumer lag 발생 가능
LOG-END-OFFSET: Producer가 write한 오프셋 (leader의 맨 끝)
CURRENT-OFFSET: Consumer가 Read하고 처리한 후 Commit한 오프셋
Consumer Lag: Log-end-offset과 current-offset의 차이
Replication: Partition을 복제하여 다른 Broker상에서 Replicas를 만들어 장애 대비
> Producer가 write할 때 Replicas에도 같이 read하여 추가함
원본: Leader Partition
복제: Follower Partition
Replication Factor = 3
> 원본+Replica 모두 합계가 3개라는 것
Producer와 Consumer는 leader partition에서만 Write, Read함
Follower는 Leader의 Commit Log에서 데이터 가져오기 요청(Fetch Request)으로 복제
Apache Kafka 2.4부터 Follower Fetching(Read)가능
Leader 장애 발생 시 Follower 중 하나를 Leader로 선출하고 Producer, Consumer는 자동으로 새 Leader 전환됨
하나의 Broker에만 Leader Partition이 몰리게 되면 해당 Broker에만 CPU와 Producer, Consumer가 몰리게 되어 부하집중됨(Hot Spot)
auto.leader.rebalance.enable: default enable
leader.imbalance.check.interval.seconds : default 300
> 300초 마다 Leader 체크
leader.imbalance.per.broker.percentage: defualt 10
> 다른 broker보다 10% 이상 leader를 많이 가져가지 않게 확인
Rack name: 동일 rack 또는 Available Zone 상의 Broker들에 동일 rack name 지정
> AZ 자체가 장애나면 해당 브로커 모두 죽기 때문에 AZ별 분산하여 사용
> Replica-Leader/Follower는 최대한 Rack간 균형 유지하여 Rack 장애 대비
> Topic 생성 또는 Auto Data Balancer/Self Balancing Cluster 동작 때 실행
1-7. In-Sync Replicas (ISR)
ISR: High Water Mark라고 하는 지점까지 동일한 Replicas(leader, follower)의 목록
ISR: Leader와 High water mark까지 복제를 잘 한 replica
> 장애 시 ISR 중 leader 선출
Out-of-sync Follower(OSR): ISR만큼 복제를 못한 Replica
Fully-Replicated Committed: Follower에서 복제한 마지막 offset > 여기를 high water mark라고 함
replica.lag.max.messages = 4
> 메시지가 항상 일정한 비율로 들어오면 지연 없이 정상 작동
> 메시지 유입량이 갑자기 늘어나게 되면 지연으로 판단하고 ISR을 OSR로 상태 변경
> 잠깐 지연으로 OSR로 판단하게 되므로 불필요한 에러 및 retry 유발되는 문제
—> 이 옵션말고 밑의 옵션 사용하는게 좋음
replica.lag.time.max.ms
> Follower가 leader로 Fetch 요청 보내는 interval 체크
> ex) 10000 이라면, Follower가 leader로 fetch요청을 10000ms 내에만 요청하면 정상으로 판단
Zookeeper에 ISR 업데이트, Controller가 Zookeeper로부터 수신
Follower가 너무 느리면 leader는 ISR에서 follower 제거 후 Zookeeper에 ISR 유지
Controller: Kafka cluster의 Broker 중 하나
> Zookeeper를 통해 Broker Liveness 모니터링
> Leader와 replica 정보를 cluster 내 다른 Broker에 전달
> Zookeeper에 Replicas 정보 복사본 유지하고 더 빠른 액세스를 위해 모든 Broker에게 동일 정보 캐시
> Leader 장애 시 Leader Election 수행
> Controller 장애 시 다른 Active Broker 중 재선출
Consumer 포지션
Last Committed Offset(Current Offset): 최종 Commit한 Offset
Current Position: Consumer가 읽어간 위치(처리 중, Commit 전)
High water mark: ISR간에 복제된 Offset
Log end offset: Producer가 메세지 보내서 저장된 로그 맨 끝 offset
“Committed”란
ISR 목록의 모든 Replicas가 메시지를 성공적으로 가져오면 Committed
Consumer는 Committed 메시지만 읽기 가능
Leader는 메시지를 Commit할 시기 결정
Committed 메시지는 모든 Follower에서 동일한 Offset 갖도록 보장
어떤 Replica가 Leader인지에 관계없이 모든 Consumer는 해당 offset에서 같은 데이터 읽기 가능
Broker가 다시 시작할 때 Committed 메시지 목록 유지위해 Broker의 모든 Partition에 대한 마지막 Committed Offset은 replication-offset-checkpoint라는 파일에 기록
(High water mark)
Consumer는 Committed 메시지만 읽기 가능
Leader Epoch
> 새 leader가 선출된 시점을 Offset으로 표시
> Broker 복구 중 메시지를 체크포인트로 자른 다음 현재 leader를 따르기 위해 사용
> Controller가 새 leader 선택하면 leader epoch 업데이트 후 해당 정보를 ISR에 보냄
> leader-epoch-checkpoint에 기록
Message Commit 과정
각 Broker의 Fetcher Thread 있음
leader에서 메시지 추가되면 Follower에서 fetch하여 데이터 받고, Leader는 High water mark 기록 및 Follower에게도 전송
'데엔 공부' 카테고리의 다른 글
Kafka 심화 개념 - 4 (2) 2024.12.15 Kafka 심화 개념 - 3 (2) 2024.12.14 Kafka 심화 개념 - 2 (0) 2024.12.13 Kafka 심화개념 - 1 (2) 2024.11.27