쿼카러버의 기술 블로그

[Kafka - step 3] 카프카의 아키텍처 및 구성요소 (기본 term. 브로커, 주키퍼, 토픽, 세그먼트, 파티션 등) 본문

분산 시스템/Kafka

[Kafka - step 3] 카프카의 아키텍처 및 구성요소 (기본 term. 브로커, 주키퍼, 토픽, 세그먼트, 파티션 등)

quokkalover 2022. 4. 3. 23:55

현재 카프카 정리 시리즈를 포스팅 하고 있다. 

 

카프카 정리 시리즈에서 다루는 여러가지 주제가 궁금할 경우 본 글 을 참고하길 바란다.

 

 

본 글은 카프카의 아키텍처 및 구성요소, 즉 카프카를 이해하기 위해 알아두어야 할 필수 Term들에 대해 다룬다.

 

Kafka의 아키텍처

 

pub - sub 모델 : 앞 글에서 다루었듯, publisher subscriber모델은 데이터 큐를 중간에 두고 서로 간 독립적으로 데이터를 생산하고 소비한다. 이런 느슨한(loose) 결합을 통해 publisher나 subscriber가 죽더라도 서로 간에 의존성이 없기 때문에 안정적으로 데이터를 처리할 수 있다.

  • 특히 kafka에는 offset을 통해 특정 토픽을 어디까지 읽었는지에 대한 정보를 관리하고 있기 때문에 컨슈머중 어느 하나가 죽더라도 같은 그룹 내 다른 컨슈머가 하던 일을 대신해 토픽의 파티션을 컨슘할 수 있다.

 

분산 시스템 : 카프카는 분산 시스템으로 동작하다. 따라서 Fault tolerant한 고가용성 서비스를 제공하고, 분산 처리를 통해 빠른 데이터 처리를 가능하게 한다. 또한 서버를 수평적으로 늘려 안정성 및 분산처리를 통한 성능을 향상시키는 Scale Out이 가능하다

  • 고가용성
  • 확장성

 

디스크 순차 저장 및 처리 : 메시지를 메모리 큐에 적재하는 메시징 시스템과는 다르게 엄청난 양의 데이터를 모두 디스크에 저장한다.

 

- 카프카는 메시지를 디스크에 순차적으로 저장한다.

 

- 너무 잦은 I/O와 과도한 바이트 복사와 같은 디스크 비효율을 줄이기 위해 메시지 셋 추상화를 기반으로 프로토콜을 새로 만들었다.

 

- 또한 다수의 메시지를 모아 한번에 큰 배치로 전송하게 된다.

  • 네트워크의 왕복 오버헤드를 줄일 수 있다.
  • 디스크에 있는 데이터를 네트워크를 통해 전송하는 과정이 궁금하면 아래 글을 참고하길 바란다.

 

페이지 캐쉬 :

잔여 메모리를 이용해 디스크 Read/Write을 하지 않고 페이지 캐시를 통한 Read / Write을 수행하기 때문에 처리속도가 빠름

분산 처리 :

카프카는 파티션이라는 개념을 도입하여 여러 개의 파티션을 서버들에 분산시켜 나누어 처리할 수 있다. 이로서 메시지를 상황에 맞추어 빠르게 처리할 수 있다.

 


Kafka의 구성요소

카프카 클러스터

  • 여러개의 브로커로 구성된 집합체를 의미한다.
  • 브로커들이 메시지를 나눠서 저장

 

브로커

카프카 애플리케이션이 동작하고 있는 서버 또는 노드를 broker라고 표현한다.

 

브로커라는 용어에 대한 정의는 혼동될 수 있다. 카프카는 카프카 애플리케이션과 주키퍼 애플리케이션 총 2개의 애플리케이션을 설치하고 운영해야 하기 때문이다. 따라서 브로커를 정확하게 정의해보자면 카프카는 애플리케이션의 이름을 말하고, 브로커는 카프카 애플리케이션이 설치된 서버 또는 노드를 의미한다. 많은 사람들이 카프카와 브로커를 동일한 의미로 호칭하거나 해석는 경우가 있으니 참고 바란다.

 

1) Controller로서의 역할

 

주키퍼의 지시를 받아 Kafka 클러스터 전체를 관리하는 역할을 담당한다.

  • 클러스터 내에서 하나의 브로커가 컨트롤러 역할을 한다.
  • 컨트롤러는 브로커들의 생존 여부를 체크한다.
  • 임의의 브로커가 동작하지 않을 경우, 해당 브로커에 있었던 리더 파티션을 탈락시키고 다른 팔로워 파티션들 중 하나를 리더로 뽑는다.
  • 새롭게 선출된 리더 정보를 모든 브로커에게 전달한다.

컨트롤러 선정은 주키퍼의 임시노드 /controller에 데이터가 없으면 브로커 번호를 저장하고 컨트롤러 역할을 담당한다. 다른 브로커들은 /controller를 확인했을 때 데이터가 있기 때문에 저장된 브로커 번호를 컨트롤러로 인식한다.

 

2) 메시지 저장과 메시지 파일 관리

 

브로커는 프로듀서로부터 전달되는 메시지를 로그자료구조 형태로 디스크에 저장한다. 로그 자료구조는 새로운 내용이 중간에 삽입되지 않고 오로지 끝에만 저장되는 append-only특징을 가진다.

 

프로듀서가 생성한 메시지를 받아서 메시지 내용과 함께 오프셋 정보를 저장한다. 브로커는 오프셋을 관리하고 컨슈머로부터 메시지를 읽으려는 요청에 대한 응답을 하는 등의 역할을 하고 있다.

브로커 내부에 여러 토픽들이 생성될 수 있고, 토픽들에 의해 생성된 파티션들 또한 여러 브로커에 분산 저장되거나 장애 발생시 안전하게 데이터를 사용할 수 있도록 도와주는 역할을 한다.


주키퍼

주키퍼는 현재 카프카에 필수적이기 때문에 설명이 필요하다. 2021년 4월에 주키퍼 없이 구동될 수 있는 카프가가 공개되긴 했지만, 아직까진(현재 2022년 4월 2) 주키퍼를 활용하는 버전이 더 안정적이기 때문이다.

 

주키퍼는 broker와 같은 서버에 구축해도 되고, 별도의 서버에 구축해도 된다.

 

주키퍼는 아파치 프로젝트 중 하나로 분산 애플리케이션 관리를 위해 안정적인 코디네이션을 담당하는 어플리케이션이다. 주역할은 분산 어플리케이션이 안정적인 서비스를 할 수 있도록 분산되어 있는 각 애플리케이션의 메타 정보를 중앙에 집중하고 구성 관리, 그룹관리 네이밍 동기화 등의 서비스를 제공한다.

 

클러스터의 설정 정보를 최신으로 유지하기 위한 시스템으로 사용한다.

 

주키퍼는 분산 시스템의 마스터를 선출한다. 예를 들면 카프카 클러스터를 구성할 때 카프카 클러스터의 식별 정보부터 현재 살아있는 브로커 정보 나아가 권한 정보 등이 저장된다. 또한 카프카 브로커들 중 일종의 지휘자 역할을 하는 컨트롤러 브로커를 뽑는 역할을 담당한다.

 

주키퍼는 디렉토리 형태로 파일시스템에 데이터를 저장, 관리한다. 상태 정보들을 지노드(znode)라고 불리는 곳에 key-value형태로 저장한다. znode는 일반 컴퓨터의 파일이나 폴더 개념과 비슷하게 자식노드를 가지는 계층형 구조로 구성한다. 따라서 동일한 카프카 클러스터는 주키퍼 연결 설정에서 동일한 디렉토리 경로를 가지고 있다.

 

주키퍼에 저장되는 데이터는 모두 메모리에 저장된다. 따라서 처리량이 매우 크고 속도 또한 매우 빠르다.

 

주키퍼는 좀 더 신뢰성 있는 서비스를 위해 앙상블을 구성하는데, 주키퍼는 과반수 방식에 따라 살아 있는 노드 수가 과반 수 이상 유지된다면 지속적으로 서비스를 제공한다.

 

또한 하나의 주키퍼 클러스터에 여러 카프카 클러스터가 동시에 구성될 수 있다.

 


토픽

카프카에서 토픽은 데이터를 구분하기 위한 저장소라고 생각할 수 있다. 메시지를 받을 수 있는 논리적인 모델로 데이터를 구분한다. 아파트에 있는 호별로 만들어진 우편함이나 이메일 주소와 같은 개념을 카프카 관점에서는 토픽이라 볼 수 있다.

카프카는 데이터를 주고 받을 때 지정된 토픽으로 데이터를 주고받게 되고, 따라서 토픽을 어떻게 설계하는지가 매우 중요하고 그 중 하나가 파티션이다.

토픽은 1개 이상의 파티션을 소유하고 있다.

 


Partition

하나의 토픽이 한 번에 처리할 수 있는 데이터의 한계를 높이기 위해 토픽 하나를 여러 개로 나눠 병렬 처리가 가능하게 만든 것을 파티션이라고 한다. 이렇게 하나를 여러 개로 나누면 분산 처리도 가능하다. 파티션은 수 만큼 컨슈머를 연결할 수 있다.

토픽을 구성하는 데이터 저장소이자 메시지가 저장되는 위치를 의미한다.

토픽이 카프카에서 일종의 논리적인 개념이라면, 파티션은 토픽에 속한 레코드를 실제 저장소에 저장하는 작은 단위다. 각각의 파티션은 append-only방식으로 기록되는 하나의 로그 파일이다.

 

 

파티션은 많을 수록 좋은가?

파티션이 많을 수록 꼭 좋은 것은 아니다. 파티션 수를 정하는 기준은 모호한데, 각 메시지 크기나 초당 메시지 건수에 따라 달라지므로 정확하게 예측하기 어렵다. 또한 파티션 수만큼만 컨슈머를 1:1로 연결할 수 있기 때문에, 컨슈머의 갯수와 함께 고려가 필요하다.

  • 파티션은 초기 생성 후 언제든지 늘릴 수 있지만 반대로 줄일 수는 없다. 따라서 초기에 파티션을 생성할 때 파티션 수를 작게 생성한 후 컨슈머의 LAG등을 모니터링하면서 조금씩 늘려가는 방법이 가장 좋다.

또한 파티션수가 많아졌을 때의 단점은 아래를 생각해볼 수 있다.

  • 노드가 다운됐을 경우 관리해야 될 포인트가 많아지고 오래걸린다.
  • 파티션이 많아지는 만큼 파일 핸들러도 늘어나게 되어서 파티션이 많다고 무조건 좋다고 볼수 없다.

로그 세그먼트

카프카의 토픽으로 들어오는 메시지는 파티션마다 세그먼트라는 파일에 저장된다. 메시지는 정해진 형식에 맞추어 순차적으로(append-only) 로그 세그먼트 파일에 저장된다.

 

로그 세그먼트에는 메시지의 내용만 저장되는 것이 아니라, 메시지의 키, 밸류, 오프셋, 메시지 크기와 같은 정보가 함께 저장되며, 로그 세그먼트 파일들은 브로커의 로컬 디스크에 보관된다.

 

하나의 로그 세그먼트 크기가 너무 커져버리면 파일을 관리하기 어렵기 때문에 로그 세그먼트의 최대 크기는 1GB가 기본적으로 설정되어 있다.

 

로그 세그먼트 컴팩션

  • 컴팩션(compaction)은 카프카에서 제공하는 로그 세그먼트 관리 정책 중 하나로, 로그를 삭제하지 않고 컴팩션하여 보관한다.
  • 카프카에서는 단순하게 메시지를 컴팩션해서 보관하기 보다는 메시지의 키값을 기준으로 마지막의 데이터만 보관한다.
  • 메시지의 키값을 기준으로 과거 정보는 중요하지 않고 가장 마지막 값이 필요한 경우에 사용한다.
  • 로그 컴팩션의 장점은 빠른 장애 복구다. 장애 복구시 전체 로그를 복구하지 않고 메시지의 키를 기준으로 최신의 상태만 복구한다. 따라서 전체 로그를 복구할 때보다 복구 시간을 줄일 수 있다.
  • 모든 토픽에 로그 컴팩션을 적용하는 것은 바람직하지 않다. 키값을 기준으로 최종값만 필요한 워크로드에 적용하는 것이 바람직하다.

리플리케이션

카프카는 브로커의 장애에도 불구하고 연속적으로 안정적인 서비스를 제공함으로써 데이터 유실을 방지하며 유연성을 제공한다. 카프카의 리플리케이션 동작을 위해 토픽 생성시 필숫값으로 replication factor라는 옵션을 설정해야 한다.

 

리플리카는 파티션의 복제본을 의미하고, 위에서 설정한 replication factor만큼 파티션의 복제본이 각 브로커에 생긴다.

 

또한 카프카는 파티션에 대한 리더와 팔로워를 구성하여, 프로듀서와 컨슈머는 리더를 통해서만 메시지를 처리하고 팔로워는 리더로부터 데이터를 복제해둔다. 그리고 장애가 발생했을때, 다른 팔로워가 리더가 되고 이에 따라 새로운 리더를 통해 메시지를 다시 처리할 수 있게 된다.

 

리플리케이션의 자세한 동작 방식은 추후 글에서 다루도록 하겠다.


Producer

프로듀서는 메시지를 생산해서 카프카의 토픽으로 메시지를 보내는 역할을 담당한다.

프로듀서는 데이터를 전송할 때 리더 파티션을 가지고 있는 카프카 브로커와 직접 통신한다.

프로듀서의 자세한 역할 밀 구현은 추후 글에서 다루도록 하겠다.


Consumer

컨슈머는 토픽의 파티션에 저장되어 있는 메시지를 소비하는 역할을 하는 애플리케이션이나 서버를 컨슈머라고 부른다.

컨슈머는 데이터를 요청할 때 리더 파티션을 가지고 있는 카프카 브로커와 통신한다.

컨슈머의 자세한 역할 및 구현은 추후 글에서 다루도록 하겠다.

 


본 글에서는 카프카의 아키텍처와 카프카를 이해하기 위해 알아두어야 할 필수 구성요소를 다루었다.

 

다음 글은 카프카의 프로듀서에 대해 다루도록 하겠다. 

 

참고자료

 

https://steady-coding.tistory.com/580

https://always-kimkim.tistory.com/entry/kafka101-broker

https://velog.io/@hyun6ik/Apache-Kafka-Partition-Assignment-Strategy

https://velog.io/@jaehyeong/Apache-Kafka아파치-카프카란-무엇인가

https://medium.com/@umanking/카프카에-대해서-이야기-하기전에-먼저-data에-대해서-이야기해보자-d2e3ca2f3c2

https://freedeveloper.tistory.com/396

Comments