본문 바로가기

IT/서버

Apache Kafka 완전 정복 : 클러스터 구축부터 MSA 환경 활용 - 기본 개념

반응형

Event란 

비즈니스에서 일어나는 모든 일 (데이터)을 의미한다.

 

예를 들어 은행은 고객이 월요일 오전 10시 33분에 고객 b에게 300달러를 송금하는것, A 택시가 현재 위치한 GPS좌표, 상점 B의 상품이 오후 3시 33분에 배송을 시작하는 것 이 모든 행위를 이벤트로 볼 수 있다.

 

이처럼 비즈니스 모든 영역에서 광범위하게 발생함으로 이벤트는 빅데이터 특징을 갖고 있다 그래서 이런 연속적인 많은 이벤트들의 흐름을 Event Stream이라 칭한다.

 

대표적인 이벤트 스트리밍 플랫폼으로 아파치 카프카가 존재하며 아파치 카프카는 크게 3가지 특징을 갖고 있다. 

1. 이벤트 스트림을 안전하게 전송한다. (Pub & Sub 기능)

2. 이벤트 스트림을 디스트에 저장한다. (다른 이벤트 스트림과의 차별점)

3. 대용량의 실시간 이벤트 스트림을 분석 및 처리 기반으로 사용한다. (대용량 처리가 가능함으로 이 데이터를 추출해서 분석 및 처리가 가능)

 

아파치 카프카는 이벤트가 사용되는 모든 곳에서 사용할 수 있는데 대표적인 예로 메세지 시스템, IOT 디바이스 데이터 수집, 애플리케이션에서 발생하는 로그 수집, 리얼 이벤트 스트림 프로세싱으로 이상 거래 감지, 중복 거래 탐지 등과 같은 시스템, DB 동기화 (MSA 기반 분리된 DB간 동기화)에 사용한다.

 

카프카 기본 개념 

토픽 : 카프카 안에 메시지가 저장되는 장소

프로듀서 : 메세지를 생성해서 토픽으로 보내는 애플리케이션

컨슈머 : 토픽의 메세지를 가져와서 활용하는 애플리케이션 

- 컨슈머는 그룹으로 묶이며 한 그룹의 컨슈머들은 동일한 동작을 병렬로 수행하게 된다.

 

프로듀서랑 컨슈머는 서로의 동작을 모르고 각각 다른 속도로 커밋로그의 Write와 Read를 수행한다. 

그리고 다른 컨슈머 그룹에 속한 컨슈머들은 서로 관련 없이 커밋로그에 있는 메세지를 동시에 다른 위치에서 Read한다. 

※ 커밋로그 : 추가만 가느하고 변경 불가능한 데이터 스트럭처, 이벤트는 항상 로그 끝에 추가되고 변경되지 않음.

- 프로듀서의 Write OFFSET은 LOG-END-OFFSET이고, 컨슈머의 Read OFFSET은 CURRENT-OFFSET이라고 부르며 둘 OFFSET의 차이를 Consumer Lag이라고 부른다.

 

토픽 생성 시 파티션 개수를 지정하고 각 파티션은 브로커들에 분산되어 여러 세그먼트로 구성된다. 

세그먼트는 반복을 통해 분리 및 생성되는데 그 전략은 Rolling Strategy로 파일 사이즈 또는 시간으로 제한할 수 있다.

 

카프카는 크게 프로듀서, 카프카 클러스터(+브로커), 주키퍼, 컨슈머로 구성되어있다.

 

카프카 브로커는 파티션에 대한 Read, Write를 관리하는 소프트웨어이며 카프카 서버라고 부르기도 하며 하나의 클러스터는 최소 4대이상의 브로커로 구성되길 권장한다.

 

주키퍼는 브로커를 관리(브로커들의 목록/설정)하는 소프트웨어다. 하지만 현재 카프카 3부터는 주피커 대신 KRaft로 카프카 클러스터 내부에 브로커 관련 메타 데이터를 관리하도록 설정할 수 있다.

 

프로듀서는 메세지(=Record)를 생성하는 객체인데 메세지는 아래 구성으로 생성할 수 있다.

이때 Key와 Value는 Avro 또는 JSON등 다양한 형태로 만들 수 있다.

카프카는 오직 바이트 배열로만 데이터를 저장하고 각 직렬화, 역직렬화를 통해 데이터를 쓰고 읽는다.

아래 그림은 카프카 라이브러리 내에서 프로듀서로 데이터를 Send한 뒤에 수행되는 흐름도이다.

※ partioner은 key 값을 통해 데이터를 보낼 파티션을 판단해주는 객체이다.

 

컨슈머는 커밋로그인 파티션에서 고유의 속도로 데이터를 읽어서 활용하는 애플리케이션이다.

 

카프카는 병렬처리 시스템으로 파티션이 1개가 아닌 이상 모든 메세지에 대한 전체 순서를 보장하기 어렵다.

왜냐하면 파티셔널을 통해 key에 의해 분산되어 들어가기 때문이다.

하지만 실제 시스템에서 모든 데이터에 대한 순서를 보장할 필요가 없다 특정 고객 또는 특정 키의 데이터의 순서만 보장받으면 되기 때문이다. 즉 키에 대한 순서보장됨으로 이 부분에 대한 문제는 멀티 파티션을 이용하는데 이슈가 되지 않는다.

단, 운영 중에 파티션 개수를 변경하게 되면 순서를 보장받기 어렵다. 이점을 반드시 기억하고 있어야 한다.

만약에 한개의 컨슈머에서 장애가 발생할 경우 리밸러싱을 통해 다른 컨슈머가 해당 파티션을 함께 처리하도록 자동 처리된다.

레플리케이션(복제)는 파티션을 복제하여 다른 브로커상에서 복제물을 만들어 장애를 대비할 수 있다.

오직 프로듀서랑 컨슈머는 오직 리더를 통해서만 Read, Write를 한다.

그리고 팔로워는 리더로부터 가져오기 Fetch를 통해 데이터를 복제한다.

특정 브로커에 접근이 몰려 hot spot이 되는걸 방지하고자 리더를 분산할 수 있다.

브로커의 렉 설정을 기재함으로써 알아서 렉 별로 리더를 분산시켜 서버의 지역 또는 렉 자체가 장애나 발생한 경우에 대비할 수 있다.

In-Sync Replicase (ISR)는 실제로 팔로워들이 정상적으로 데이터를 복제하고 있는지를 확인할 수 있는 지표를 의미한다.

즉, ISR은 High Water Mark라고 가장 리더와 비슷한 위치까지의 데이터를 가지고 있는 지점으로 이 지점까지 도달한 팔로워와 리더의 목록이다.

 

Replica.lag.max.message = 4로 설정되어 있는 상태임

주의한 점으로 ISR을 판단하는 설정값으로 replica.lag.max.messages 옵션은 문제점이 있다. 

바로 갑자기 메시지 유입량이 증가할 경우 순간적으로 OSR로 판단되면서 불필요한 retry와 에러 로그가 발생할 수 있다. 

그러므로 해당 옵션이 아닌 replica.lag.time.max.ms로 팔로워가 리더로부터 Fetch 요청을 보낸 interval 시간 체크를 통해 판단해야 된다.

 

 ISR 정보가 변경될 경우 리더 브로커는 주키퍼에게 해당 정보를 넘기고 주키퍼는 컨트롤러 브로커에게 해당 정보 갱신을 요청한다.

컨트롤러는 클러스터내에 브로커 중 1개로 그 순간 한 브로커로 지정되며 컨트롤러를 통해 변경사항들이 모든 브로커들에게 전달된다.

매번 변경이 발생할때 전달하는 이유는 캐싱을 통해 동작을 빠르게 진행되기 위함이다.

그리고 컨트롤러는 리더의 장애 발생 시 다음 리더를 결정하는 역할을 수행하며 만약, 컨트롤러에 장애가 발생하면 주키퍼가 동작 중이 브로커중에 컨트롤러를 다시 선출한다.

 

아래 강좌를 듣고 정리한 내용입니다.

 

[참고자료]

https://fastcampus.co.kr/courses/207099/clips/

 

패스트캠퍼스 온라인 강의 - Kafka 완전 정복 : 클러스터 구축부터 MSA 환경 활용까지

 

fastcampus.co.kr

 

반응형

'IT > 서버' 카테고리의 다른 글

MSA 가상머신, 컨테이너  (0) 2023.02.27
MSA 관심사 - 내부/외부 아키텍처  (0) 2023.02.27
MSA 아키텍처 스타일  (0) 2023.02.26
MSA 개념  (0) 2023.01.29
Docker Compose를 이용하기  (0) 2022.02.14