개요
이번 포스팅에서는 Kafka를 도입해야 하는 이유와 함께 Kafka 관련 개념 설명과 모니터링 오픈소스에 대해 정리해보겠습니다.
이번에 알아볼 개념과 모니터링 툴은 아래와 같습니다.
- topic
- broker, replication, ISR
- partitioner
- consumer lag
- burrow (모니터링 오픈소스)
1. Kafka를 도입해야 하는 이유
- 데이터를 전송하는 소스 애플리케이션과 데이터를 받는 타깃 애플리케이션이 있고 초기에는 간단하게 단방향 구조라고 가정
- 시간이 지나 소스와 타겟 애플리케이션이 늘어나면서 라인이 복잡해짐
- 이에 따라 배포 및 장애 대응에 어려움이 느껴지고
- 데이터 전송할 때 프로토콜, 포맷 파편화가 심해져 유지보수가 힘들어짐
- 이런 복잡함을 해결하기 위해 Apache Kafka가 개발되었고 오픈소스로 제공이 되고 있음
- Apache Kafka는 소스 애플리케이션과 타깃 애플리케이션 간 커플링을 약화시키는 것이 주목적
- Kafka는 아주 유연한 큐 역할을 하고 있으며 producer는 데이터를 생성하여 kafka에 데이터를 전송하고 consumer는 kafka로부터 데이터를 가져오는 역할
- producer와 consumer는 kafka로부터 라이브러리 형태로 제공되며 애플리케이션 내에서 구현하면 됨
- 데이터 흐름에 있어 fault-tolerant 즉, 고가용성으로서 서버가 이슈가 생기거나 렉이 내려가더라도 데이터 손실 없이 복구가 가능
- 또한, json, tsv 등과 같이 다양한 포맷을 지원하여 포맷 파편화를 방지 가능
- 정리를 하자면, kafka는 낮은 지연과 높은 처리량을 통해 아주 효과적으로 데이터를 처리하며 빅데이터 분야에서 안 쓰이는 곳을 찾기 힘듦
- 특히, 애플리케이션이 많은 MSA 구조에서는 kafka 도입을 긍정적으로 검토해야 할 필요성이 있음
2. Kafka 관련 개념 정리
2.1 topic
- kafka에는 다양한 데이터가 들어갈 수 있는데 그 데이터가 들어갈 수 있는 공간은 topic이라고 함
- kafka topic은 여러 개 생성이 가능하며 topic은 DB의 테이블이나 파일 시스템의 폴더와 유사한 성질을 지님
- producer가 데이터를 넣고 consumer가 데이터를 가져감
- topic은 이름을 가질 수 있는데 목적에 따라 무슨 데이터를 담는지 명확하게 명시하면 추후 유지보수 시 편리하게 관리가 가능 ex) location_log
- 하나의 topic은 여러 개의 partition으로 구성될 수 있으며 첫 번째 partition 번호는 0번부터 부여
- 하나의 partition은 큐와 같이 내부에 데이터가 파티션 끝에서부터 차곡차곡 쌓임 (FIFO 구조)
- consumer는 partition 내 가장 오래된 로그부터 가져감
- 더 이상 데이터가 들어오지 않으면 consumer는 데이터가 들어올 때까지 대기를 하며
- consumer가 partition의 데이터를 가져가더라도 데이터는 파티션 내에서 삭제되지 않음
- 새로운 consumer가 붙을 경우 해당 partition에서 0번부터 새로 가져가는 구조
- 이를 위해서는 consumer group이 달라야 하며 설정 파일에서 auto.offset.reset = earliest로 설정해야 함
- 동일 데이터에 대해서 두 번 이상 처리 가능하며 이는 Kafka를 도입하는 주된 이유 중 하나
- ex) 분석 및 시각화를 위해서 하나의 consumer group에서는 elasticsearch에 저장하기도 하고 로그 백업을 위해 다른 consumer group에서는 Hadoop HDFS에 저장도 가능
- partition이 여러 개인 경우 데이터가 어느 topic에 들어가야 할까?
- producer는 데이터를 보낼 때 key를 지정 가능
- key가 null이고 기본 partitioner 사용할 경우 round robin 방식으로 할당
- key가 존재하고 기본 partitioner 사용 시 키에 대한 hash 값을 구하고 hash 값에 맞는 특정 partition에 할당
- partitioner에 대해서는 하단에 추가 설명할 예정
- producer는 데이터를 보낼 때 key를 지정 가능
- partition을 늘리면 consumer 개수를 늘려서 데이터 처리 분산이 가능
- 하지만, 파티션을 한번 늘리면 다시 줄일 수 없으므로 여러 상황을 고려하고 늘려야 함
- partition 내 데이터 삭제 주기는 아래의 옵션 설정에 따라 다름
- log.retention.ms: 최대 record 보존 시간
- log.retention.byte: 최대 record 보존 크기
- 위 옵션을 통해 적절한 시간/용량을 설정하여 데이터 삭제 가능
2.2 broker, replication, ISR
- replication은 kafka 아키텍처의 핵심이며 클러스터 내 장애 발생 시 가용성을 보장하는 가장 좋은 방법
- kafka broker는 kafka가 설치되어 있는 서버 단위
- 보통 3개 이상의 broker로 구성할 것을 권장
- 만약 partition이 1개이고 replication이 1인 topic이 존재하는 상태에서 broker가 3대라면 브로커 3대 중 1대에 해당 topic의 정보가 저장됨
- replication은 partition의 복제를 뜻함
- replication이 1이라면 partition은 1개만 존재
- replication이 2라면 partition은 원본 1개, 복제본 1개
- replication이 3이라면 partition은 원본 1개, 복제본 2개
- 브로커의 개수에 따라 replication 개수가 제한이 되는데 예를 들자면, broker 개수가 3이라면 replication은 최대 3까지 가능
- leader partition: 원본 파티션, follower partition: 복제 파티션
- leader partition과 follower partition을 합쳐서 ISR(In Sync Replica)라고 볼 수 있음
- 추후 ack 옵션을 통해 자세히 설명
- repication은 partition의 고가용성을 위해 사용됨
- 만약 broker가 3개인 kafka에서 replication이 1이고 partition이 1인 topic이 있다고 가정
- 갑자기 브로커 장애 시 더 이상 해당 파티션 복구 불가
- 위 예시에서 replication이 2라면?
- broker 1개가 죽더라도 follower parition이 존재하므로 복제본으로 복구 가능
- 나머지 1개 남은 follower partition이 leader partition으로 역할을 승계
- producer가 토픽의 파티션에 데이터를 전달할 때 전달받는 주체가 leader partition
- producer에는 ack라는 상세 옵션이 있고 ack를 통해 고가용성 유지 가능 (TCP 통신 내 SYNC/ACK를 생각하면 이해가 쉬움)
- ack는 partition의 replication과 관련 있음
- ack는 0, 1, all 옵션 중 하나를 선택 가능
- 0: producer는 leader partition에 데이터를 전송하고 응답 값을 받지 않음
- leader partition 내 데이터 전송 유무를 모르고 follower partition에 복제되었는지 모름
- 속도는 빠르지만 데이터 유실 가능
- 1: leader partition에 데이터 전송하고 응답 값을 받지만 follower partition에 복제되었는지 유무는 모름
- leader partition에서 데이터를 받는 즉시 broker 장애가 발생할 경우 나머지 follower partition에 데이터가 미처 전송되지 못한 상태이므로 데이터 유실 가능
- all: 1 옵션에 추가로 follower partition에 복제가 잘 이루어졌는지에 대한 응답 값도 받음
- 데이터 유실이 없는 것이 장점
- 하지만 0, 1 옵션에 비해 확인 절차가 많으므로 속도가 현저히 느림
- 데이터 유실이 없어야만 하는 중요 로그에 대해 쓰이는 옵션
- 0: producer는 leader partition에 데이터를 전송하고 응답 값을 받지 않음
- 이처럼 replication이 고가용성을 위해 중요한 역할을 하므로 무조건 많은 것이 정답이라고 생각할 수 있음
- 하지만 replication이 많아지면 broker의 리소스 사용량도 그만큼 증가
- 따라서, kafka에 들어오는 데이터 양과 데이터 보존 시간을 잘 고려해서 replication 개수를 정해야 함
- 3개 이상의 broker 사용 시 replication을 3으로 설정하는 것을 권장
2.3 partitioner
- partitioner는 kafka producer의 중요 개념 중 하나이며 partition을 효과적으로 사용 가능하도록 하는 역할
- producer가 데이터를 보내면 무조건 partitioner를 통해서 broker로 데이터 전송
- partitioner는 데이터를 토픽에 어떤 파티션에 넣을지 결정하는 역할
- 레코드에 포함된 메시지 키 또는 메시지 값에 따라서 해시 값이 정해지며 이를 통해 partition의 위치 결정
- producer를 구현할 때 partitioner를 별도로 설정 안 했을 경우 디폴트로 UniformStickyPartitioner로 설정
- 해당 파티션에는 메시지 키가 있을 때와 없을 때 다르게 동작
- 메시지 키가 있는 경우
- partitioner에 의해 특정 해쉬 값이 생성되며 해당 해쉬값을 기준으로 어느 partition에 들어갈지 정해짐
- topic에 partition이 2고 partitioner의 해쉬 로직에 의해 data1은 partition#0, data2는 partition#1, data3은 partition#1에 위치한다고 가정
- 위 예시를 통해 동일한 메시지 키를 가진 레코드는 동일한 해쉬값을 생성하므로 항상 같은 파티션에 위치함을 보장하며 순서가 보장된다는 것을 확인 가능
- 즉, partition 한 개 내부에서는 큐처럼 동작
- 메시지 키가 없는 경우
- 라운드 로빈 방식으로 partition에 들어감
- 전통적인 라운드 로빈 방식과는 살짝 다르게 동작
- UniformStickyPartitioner는 producer에서 배치로 모을 수 있는 최대한의 레코드들을 모아서 partition으로 데이터를 보냄 (round robin 방식으로 데이터를 넣음)
- 즉, 메시지 키가 없을 경우 partition들에 적절히 분배
- producer에 직접 개발한 partitioner를 적용하는 것도 가능
- kafka에는 custom partitioner를 적용할 수 있도록 partitioner 인터페이스 제공
- partitioner 인터페이스를 통해 custom partitioner 클래스를 만들면 메시지 키, 메시지 값 또는 topic명에 따라서 어느 partition에 데이터를 보낼지 정할 수 있음
- 직접 개발한 partitioner는 아래와 같은 사례에 적용 가능
- VIP 고객을 위해 데이터 처리를 조금 더 빠르게 하는 로직에서 적용 가능
- 10개의 partition이 있다고 가정했을 때 커스텀 partitioner를 개발하여 7개에는 VIP 고객의 데이터 그리고 나머지 3개의 partition에는 일반 고객의 데이터를 넣어 VIP 고객 데이터의 처리량을 늘릴 수 있음
- MRQP 메시징 시스템에서 우선순위 큐를 만드는 것과 비슷
2.4 Consumer Lag
- kafka를 운영함에 있어 가장 중요한 모니터링 지표
- kafka producer는 topic의 partition에 데이터를 차곡차곡 넣게 되고 각 데이터는 offset이라는 숫자가 붙음
- partition이 1개라고 가정
- partition이 1개인 topic에 producer가 데이터를 넣을 경우 0부터 숫자가 차례대로 매겨짐
- producer는 계속해서 데이터를 넣게 되고 consumer는 계속해서 데이터를 가져가는 상황
- 이때, producer가 데이터를 넣어주는 속도가 consumer가 데이터를 가져가는 속도보다 빠르다면?
- producer가 넣은 데이터의 offset과 consumer가 가져간 데이터의 offset 차이가 발생하며 이 것이 consumer lag
- lag의 숫자를 통해 현재 해당 topic에 대해 파이프라인으로 연계되어 있는 producer/consumer 상태 유추 가능하며 주로 consumer 상태를 체크하는 데 사용
- consumer lag는 각 partition의 offset을 기준으로 producer가 넣은 데이터의 offset과 consumer가 가져간 데이터의 offset의 차이를 기반으로 함
- topic에 여러 partition이 존재할 경우 lag 또한 여러 개 존재 가능
- consumer group이 1개이고 partition이 2개인 topic에서 데이터를 가져간다면 lag 2개 측정 가능
- 한 개의 topic과 consumer group에 대해 lag가 여러 개 존재할 수 있고 그중 가장 높은 숫자의 lag를 records-lag-max라고 부름
3. 카프카 모니터링 툴
3.1 Burrow
- kafka의 consumer lag를 모니터링하기 위해서는 오픈 소스인 burrow 사용해야 함
- kafka-client 라이브러리를 사용해서 Java 혹은 Scala와 같은 언어를 통해 kafka consumer 구현 가능
- 구현한 consumer 객체를 통해 현재 lag 정보를 가져올 수 있음
- lag를 실시간 모니터링하고 싶으면 데이터를 elasticsearch나 InfluxDB와 같은 저장소에 넣은 뒤 Grafana 대시보드를 통해 확인하는 방법도 있음
- 하지만, consumer 단위로 lag를 모니터링하는 것은 위험도가 크고 운영요소를 많이 고려해야 함
- consumer 로직단에서 lag를 수집하는 것은 consumer 상태에 dependency가 걸림
- consumer가 비정상적으로 종료되면 consumer가 더 이상 lag 측정 불가능
- 추가적으로 consumer가 개발될 때마다 해당 consumer에 lag 정보를 특정 저장소에 저장할 수 있도록 로직을 개발해야 하는 개발 공수도 들어감
- 또한, consumer lag를 수집할 수 없는 consumer가 있을 경우 lag 모니터링이 불가능하며 운영이 힘들어짐
- 따라서, LinkedIn에서는 Apache Kafka와 함께 consumer lag를 효과적으로 모니터링하도록 Burrow 내놓음
- Burrow는 golang으로 작성된 오픈소스이며 지속적으로 관리되는 깃헙 주소가 있음
- Burrow는 consumer lag 모니터링을 도와주는 독단적인 애플리케이션이며 아래의 3가지 특징을 가짐
- multi kafka cluster 지원
- 슬라이딩 윈도우를 통한 consumer status 확인 가능
- ERROR: 데이터가 많아지는데 consumer가 데이터를 안 가져오는 상태
- WARNING: 데이터양이 일시적으로 증가하여 consumer offset가 증가한 상태
- OK
- HTTP api 제공
- 다양한 추가 생태계 구축 가능
- HTTP api를 호출해서 response 받은 데이터를 시계열 DB와 같은 곳에 저장하는 애플리케이션으로 만들어 활용 가능
3.2 Kafka Manager (CMAK)
- kafka 클러스터를 모니터링하는 툴이며 아래의 기능을 제공
- Kafka Cluster 관리
- Consumer Lag 관리
- Partition Rebalancing (파티션 추가)
- Topic 관리: 리스트 조회, 생성, 삭제
- 공식 깃허브: https://github.com/yahoo/CMAK
참고
[데브원영] 아파치 카프카 for beginners
반응형
'면접 준비' 카테고리의 다른 글
[Java] 체크 예외 vs 언체크 예외 (0) | 2023.04.03 |
---|---|
클라우드 컴퓨팅 간단 정리 (0) | 2023.02.14 |
타임리프 간단 정리 (Thymeleaf) (0) | 2021.06.26 |
도커 생명주기 (Docker Life Cycle) (0) | 2021.06.17 |
도커와 마이크로 서비스 아키텍처 개요 (Docker & MSA) (0) | 2021.06.16 |