티스토리 뷰

*본 포스팅은 인프런 [데브원영]님의 아파치 카프카 for beginners 강의 세션 0을 수강하고 이를 참고해 작성했습니다. 

 

Apache Kafka


LinkedIn에서 최초로 만들고 opensource화 한 확장성이 뛰어난 분산 메시지 큐(FIFO : First In First Out)

→ 분산 아키텍처 구성, Fault-tolerance 한 architecture(with zookeeper), 데이터 유실 방지를 위한 구성이 잘되어 있음

→ AMQP, JMS API를 사용하지 않은 TCP기반 프로토콜 사용

→ Pub / Sub 메시징 모델을 채용

→ 읽기 / 쓰기 성능을 중시

→ Producer가 Batch형태로 broker로 메시지 전송이 가능하여 속도 개선

→ 파일 시스템에 메시지를 저장하므로, 데이터의 영속성 보장

→ Consume 된 메시지를 곧바로 삭제하지 않고 offset을 통한 consumer-group별 개별 consume가능

 

LinkedIn, Netflix, Twitter 뿐만 아니라 국내 카카오와 네이버도 사용하는 주요 기술이다.

Kafka Architecture


 

Broker : Kafka를 구성하는 각 서버 1대 = 1 broker

Topic : Data가 저장되는 곳

Producer : Broker에 data를 write 하는 역할

Consumer : Broker에서 data를 read 하는 역할

Consumer-Group : 메시지 소비자 묶음 단위(n consumers)

Zookeeper : Kafka를 운용하기 위한 Coordination service

Partition : topic이 복사(replicated)되어 나뉘는 단위

Topic 토픽


- 데이터가 저장되는 곳으로 데이터베이스의 데이블, 파일 시스템의 폴더와 유사한 성질을 가지고 있다. 

- 이름을 가질 수 있다. 목적에 따라 click_log, send_sms, location_log와 같이 무슨 목적을 가지는지 명확히 드러나는 이름을 붙이면 추후 유지보수에서 편리하다.

- 여러 개의 파티션(Partition)으로 구분할 수 있다(0부터 시작).

- 큐 같이 내부 데이터가 붙으면 오래된 순으로 가져간다.

- 더 이상 데이터가 들어오지 않으면 다른 데이터가 들어올 때까지 기다린다.

- 컨슈머가 데이터 가져가더라도 파티션의 데이터는 삭제되지 않고 그대로 남아있다. -> 남은 데이터는 새로운 컨슈머가 가져갈 수 있음! 단, 서로 컨슈머 그룹이 달라야 하고, auto.offset.reset = earlist여야 한다. 

 

이렇게 동일 데이터에 대해 두 번 이상 처리가 가능한 것이 카프카 사용의 주요 이유 중 하나!

- 클릭 로그를 분석하고 시각화하기 위해 elastic search에 저장하기도 하고, 백업하기 위해 하둡에 저장할 수도 있다.

 

파티션이 두 개 이상인 경우 데이터를 파티션에 보내는 방법 -> 아래에 '파티셔너'에서 자세히 다룬다!

[1] 키가 null, 기본 파티셔너 사용 시: 라운드 로빈으로 할당 

* 라운드 로빈: 프로세스에 우선순위를 두지 않고, 순서대로 시간 단위로 CPU 할당

[2] 키가 있고, 기본 파티셔너 사용할 경우: 키의 해시값을 구하고, 특정 파티션에 할당한다. 

 

⚠️ 파티션을 늘릴 때 주의점: 늘리는 것은 가능한데, 다시 줄일 수 없다

 ✅ 파티션 늘리는 것의 장점: 컨슈머 개수를 늘려서 데이터 처리를 분산시킬 수 있다.

 

❓그럼 파티션 데이터는 언제 삭제될까? -> 옵션으로 지정 가능

- log.retention.ms: 최대 record 보존 시간

- log.retention.byte: 최대 record 보존 크기(바이트)

 

Broker 브로커 


- 브로커란? 카프카가 설치돼 있는 서버 단위. 3개 이상의 브로커로 구성하는 것을 권장함.

- Replication: 카프카의 핵심 기능 -> 클러스터에서 서버가 장애가 생길 때 가용성을 보장하는 가장 좋은 방법

예시: 브로커 3대에 파티션 1개, 레플리케이션 1개라면

브로커 한대에 해당 토픽 정보가 저장된다.

이때, Replication은 복제 정보를 뜻하는데, 1이라면 파티션 한 개만 존재, 2라면 원본 한 개와 복제본 1개, 3이라면 원본 1개와 복제본 2개 이렇게 구성된다. 다만 브로커 개수에 따라 레플리케이션의 개수는 제한된다. 

 

여기서 원본 파티션은 리더 파티션 Leader Partition, 복제본은 Follower Partition이라고 한다. 그리고 이 두 개를 합쳐서 ISR: InSync Replication이라고 한다. 이때 프로듀서가 토픽의 파티션에 데이터를 전달할 때 전달받는 주체는 리더 파티션이다.

 

그럼 ISR을 왜 사용할까? -> 파티션의 고가용성을 보장하기 위해!

만약 브로커 3개인 파티션에서 레플 1 파티션 1인 토픽이 존재한다고 가정하자. 갑자기 어떤 이유로 브로커 사용 불가시 파티션 복구 불가

레플이 두 개라면, 한 개 죽어도 복제본이 존재하므로 복구가 가능하다. 이 경우 팔로워 파티션이 리더 파티션으로 역할이 승계된다.

 

❓무조건 레플 수가 많은 게 좋은 걸까? 아니다! 브로커 리소스 사용량이 늘어나기 때문

그러므로 카프카에 들어오는 데이터양과 Retention Data 저장시간을 잘 생각해서 레플 개수를 정하는 것이 좋다. 3개 이상 브로커면 레플은 3개 추천 

 

ACK : 고가용성을 유지하기 위한 옵션

종류는 0, 1, all 세 가지이다.

 

[1] ACK = 0

프로듀서는 리더 파티션에 데이터를 전송하고 응답값을 받지 않는다 -> 데이터 정상적으로 전송 완료 했는지, 나머지 파티션에 제대로 복제했는지 알 수 없음. 하지만 속도는 가장 빠르다.

 

[2] ACK = 1

 

리더 파티션에 데이터 전송하고, 제대로 받았는지 응답까지 받는다 -> 나머지 파티션에 제대로 복제됐는지 알 수 없음.

+ 만약 리더 파티션이 데이터를 받은 즉시 브로커에 장애가 일어나면, 나머지 파티션에 데이터 전송되지 못한 상태이므로 0 옵션과 동일한 데이터 유실 가능성이 있다. 

 

[3] ACK = ALL

1에 추가로 팔로워 파티션에 복제가 제대로 일어났는지 확인하는 절차가 추가된다. 데이터 유실은 없지만 확인하는 부분이 많아 속도가 현저히 느리다.

Partitioner 파티셔너


프로듀서가 데이터를 보내면 무조건 파티셔너를 통해서 브로커로 데이터가 전송된다. 여기서 파티셔너는 데이터를 토픽의 어떤 파티션에 넣을지 결정하는 역할을 한다. 이는 레코드에 포함된 메시지 키, 값에 따라 결정된다. 파티셔너를 설정하지 않으면 UniformStickyPartitioner로 설정된다.

 

파티셔너는 메시지 키가 있나 없냐에 따라 다르게 작동한다. 

[1] 키를 가지는 경우: 파티셔너에 의해 해쉬값이 생성되고 해당하는 파티션 번호로 배정된다 -> 파티션이 두 개면 동일한 메시지 키를 가진 레코드는 동일한 해쉬값을 생성해 동일한 파티션에 쌓인다. 즉, 파티션 한 개 내부에서 큐처럼 동작해 순서에 따라 데이터 처리가 가능한 것.

 

 

[2] 키가 없는 경우: 라운드 로빈으로 파티션에 들어감. 이때 일반적인 라운드로빈이 아니라 UniformStickyPartioner이다.

프로듀서에서 배치로 모을 수 있는 최대한의 레코드를 모아 파티션으로 데이터를 보낸다. 배치 단위로 보낼 때 파티션에 라운드로빈 방식으로 돌아가면서 데이터를 넣고 메시지 키가 없는 레코드는 파티션에 적절히 분배된다. 

 

그럼 기본 파티셔너만 사용할 수 있나? -> 직접 개발한 커스텀 파티셔너도 사용할 수 있다. 

Partitioner 인터페이스를 사용해서 커스텀하면 메시지 키, 값, 토픽 이름에 따라서 어떤 파티션에 보낼지 정할 수 있음. 예를 들어 VIP 고객의 데이터를 더 빨리 처리하고 싶다면 -> 파티셔너를 통해 데이터 처리량을 다르게 설정할 수 있다.

 

 

Consumer Lag 컨슈머 랙

컨슈머 랙이란 운영에 있어서 아주 중요한 모니터링 지표이다.

파티션에 데이터가 들어가면 각 데이터는 0부터 차례로 오프셋 숫자가 붙는다. 프로듀서는 계속 넣고, 컨슈머는 계속 가져가는데 만약 프로듀서가 넣는 속도가 컨슈머가 읽는 속도보다 훨씬 빠르다면, 다시 말해 프로듀서가 넣은 데이터 오프셋과 컨슈머가 가져간 데이터 오프셋 간의 차이가 발생하면, 이것이 컨슈머 랙 Consumer Lag이다.

이를 통해 현재 해당 토픽에 대한 파이프라인으로 연결돼 있는 컨슈머와 프로듀서의 상태를 유추할 수 있다(주로 컨슈머 상태 유추 가능)

 

- 토픽에 여러 파티션이 존재할 경우 랙은 여러 개 존재할 수 있다.

- 한 개의 토픽과 컨슈머 그룹에 대한 랙이 여러 개 존재할 수 있을 때 높은 숫자의 랙을 records-lag-max라고 한다. 

- 컨슈머가 성능이 안 나오거나 비정상적으로 동작시 랙이 필연적으로 발생하므로 주의 깊게 봐야 한다.

Burrow 버로우


Kafka - client 라이브러리를 사용해서 자바, scala 언어를 통해 카프카 컨슈머 객체를 통해 현재 랙 정보를 가져올 수 있다. 하지만 실시간으로 보고 싶다면 elastic search / influxDB 같은 저장소에 넣은 뒤 grafana 대시보드를 통해 확인할 수 있다.

 

하지만 컨슈머 단위에서 랙을 모니터링하는 것은 아주 위험한 운영요소가 많이 들어간다. 컨슈머 로직에서 랙을 수집하는 것은 컨슈머 상태에 디펜던시가 걸리기 때문. 예: 비정상 종료 시 더 이상 컨슈머는 랙 정보를 특정 저장소에 저장할 수 있도록 로직 개발이 필요함 

-> LinkedIn + 아파치 카프카 : 카프카의 컨슈머 랙을 효과적으로 모니터링할 수 있도록 오픈 소스인 버로우를 개발함!

 

 

GitHub - linkedin/Burrow: Kafka Consumer Lag Checking

Kafka Consumer Lag Checking. Contribute to linkedin/Burrow development by creating an account on GitHub.

github.com

 

특징

- 멀티 카프카 클러스터 지원: 기업들 대부분 2개 이상의 클러스터로 운영해서 버로우 앱 하나만 실행해 연동하면 카프카 클러스터에 붙은 랙 모두 확인할 수 있다.

- Sliding Window 통해 consumer status 확인 가능: error, warning, OK 세 가지 

( 예: 데이터 양이 일시적으로 많아져서 컨슈머 오프셋이 증가하면 Warning / 데이터 양이 많아지는데 컨슈머가 데이터를 가져가지 않으면 Error 문제 여부 확인할 수 있음 )

- Http API 제공: 정보들을 http api로 조회할 수 있다.

 

 

카프카, 레빗엠큐, 레디스 큐의 차이점


메시징 플랫폼의 두 가지 종류: 메시지 브로커, 이벤트 브로커

-> 메시지 브로커는 이벤트 브로커의 역할을 할 수 없지만  이벤트는 메시지 브로커의 기능을 할 수 있다.

 

- 메시지 브로커: 많은 기업들의 대규모 메시지 기반 미들웨어 아키텍처에서 사용됨. 큐에 데이터를 보내고 받는 프로듀서와 컨슈머를 통해 메시지를 통신하고 네트워크를 맺는 용도로 사용된다. 이때 메시지를 받아서 처리하면 즉시 짧은 시간 내에 삭제한다.

예: 레딧, 레딧엠큐

- 미들웨어: 서비스하는 앱들을 보다 효율적인 아키텍처로 연결하는 소프트웨어 예) 메시징 플랫폼, 인증 플랫폼, DB

 

- 이벤트 브로커: 이벤트, 메시지라고 불리는 레코드를 하나만 보관하고 인덱스를 통해 개별 액세스를 관리한다. 업무상 필요한 시간 동안 이벤트를 보존할 수 있다. -> 서비스에서 나오는 이벤트를 디비에 저장하듯 이벤트 브로커의 큐에 저장해 둔다.

예: 카프카, AWS 키네시스

 

이벤트 브로커의 장점

[1] 딱 한 번 일어난 이벤트 데이터를 브로커에 저장함으로써 단일 진실 공급원으로 사용할 수 있다.

[2] 장애 발생 시 장애 발생 지점부터 재처리가 가능하다. 

[3] 많은 양의 실시간 스트림 데이터를 효과적으로 처리할 수 있다. 

[4] 이벤트 기반 마이크로 서비스 아키텍처로 발전하는데 중요한 역할 + 메시지 브로커로 사용할 수도 있다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함