안녕하세요. J4J입니다.
이번 포스팅은 kafka로 분산형 데이터 처리하기 첫 번째인 kafka란 무엇인가에 대해 적어보는 시간을 가져보려고 합니다.
Kafka란 ?
kafka는 실시간 데이터 스트리밍 처리를 도와주는 분산형 스트리밍 플랫폼입니다.
대규모 스트리밍 애플리케이션 구축을 가능하도록 도와주며 실시간 데이터 스트리밍, 메시징 시스템, 로그 수집 등 다양한 곳에서 활용될 수 있습니다.
kafka는 2011년 링크드인 (LinkedIn)에서 처음 개발되었습니다.
하루에 1조 이상의 대용량으로 생성되는 데이터들을 처리해야 되는 링크드인에서는 파편화된 데이터 수집 및 처리를 하기 위해 현존하던 다양한 메시징 플랫폼과 ETL 툴들을 적용하여 아키텍처를 구성했다고 합니다.
하지만 초기에는 문제가 없던 아키텍처들은 점점 거대해지기 시작했고 몸집이 커짐과 동시에 파편화 처리를 위한 source 애플리케이션과 target 애플리케이션이 많아 짐에 따라 아키텍처가 점점 복잡해지기 시작했습니다.
이를 표현할 수 있는 아키텍처 그림은 대표적으로 다음과 같습니다.
이런 아키텍처를 사용되고 있는 상황에서 링크드인은 신규 시스템을 만들기로 결정했고 그에 따른 결과물이 kafka가 되었습니다.
각각의 애플리케이션끼리 연결되어 있어서 하나의 애플리케이션에 장애가 발생할 경우 연결되어 있는 다른 애플리케이션에도 영향을 주던 기존 방식과 달리 각각의 애플리케이션끼리 연결하지 않고 kafka라는 한 곳에서 데이터를 모아 처리할 수 있는 아키텍처가 된 것입니다.
그래서 애플리케이션 사이에 발생되던 의존 관계도 줄어들게 되었고 데이터를 단순하게 kafka에만 전달하면 되었기 때문에 어떤 데이터를 어느 애플리케이션에 보내야 하는 고민도 하지 않게 되었습니다.
이를 표현할 수 있는 아키텍처 그림은 다음과 같습니다.
Kafka 특징
[ 1. 높은 처리량 ]
kafka는 데이터를 전달하는 애플리케이션에서 kafka를 구성하는 브로커 서버에 데이터를 전달할 때와 브로커 서버에서 데이터를 전달받아야 하는 애플리케이션에 데이터를 전달할 때 모두 데이터를 묶어서 전달합니다.
즉, 데이터 송수신 처리를 위해 발생될 수 있는 네트워크 비용을 줄여주기 때문에 동일한 양의 데이터를 주고받을 때 묶음 단위로 처리하지 않는 경우보다 더 빠른 속도로 데이터를 처리할 수 있습니다.
그래서 kafka는 대용량의 실시간 로그 데이터 등을 처리하는데 매우 적합하다고 할 수 있습니다.
또한 브로커 서버 내부에서 파티션이라는 단위를 가지고 있으며 동일한 데이터를 여러 파티션에 분배하고 있습니다.
즉, 분배되어 있는 여러 파티션을 통해 병렬 처리를 수행할 수 있으며 이러한 행위는 동일한 시간에 데이터를 처리할 수 있는 양을 늘려주는 결과를 제공해 줍니다.
결과적으로 kafka의 이러한 기능들은 초당 수백만 개의 메시지들을 처리할 수 있도록 도와주기에 높은 처리량을 제공하고 있다고 말할 수 있습니다.
[ 2. 확장성 ]
데이터라고 하는 것은 항상 일정하게 적재되는 것이 아니기에 언제, 얼마나 들어올지 정확히 예측하기가 힘듭니다.
그래서 kafka는 이런 상황을 대비하기 위해 가변적인 상황에서 안정적으로 확장이 가능하도록 설계되어 있습니다.
kafka는 데이터를 처리해야 되는 요청이 적게 들어오는 경우 kafka를 구성하고 있는 브로커 서버들을 최소한으로만 운영시킵니다.
이런 상황에서 동작이 되고 있을 때 갑자기 처리해야 되는 데이터가 방대하게 많아지는 경우 kafka는 브로커 서버의 개수를 자연스럽게 늘려 scale-out 처리를 합니다.
scale-out 처리된 브로커 서버는 방대하게 들어온 데이터를 모두 처리하게 될 것이고 또 다시 처리해야 될 데이터가 적어지는 경우가 발생하면 kafka는 브로커 서버의 개수를 줄이는 scale-in 처리를 할 수도 있습니다.
그리고 kafka는 이러한 행위를 무중단으로 운영하게 됩니다.
그래서 데이터 처리를 방대하게 수행하는 곳에서도 확장성 있는 안정적인 운영을 제공하고 있다고 말할 수 있습니다.
[ 3. 영속성 ]
kafka는 전달받은 데이터를 메모리가 아닌 파일 시스템에 저장하기 때문에 kafka 브로커 서버가 갑자기 종료되었다가 재 시작되어도 전달 받은 데이터가 사라지지 않고 보관되어 있습니다.
또한 kafka는 전달 받은 데이터를 target 애플리케이션에 전달하더라도 가지고 있던 데이터가 사라지지 않습니다.
이런 특징들을 가지고 있기 때문에 한번 전달된 데이터에 대해서 안전한 데이터 처리를 할 수 있는 것을 보장합니다.
하지만 데이터가 항상 유지되는 것은 아닙니다.
kafka에 데이터를 전달하는 애플리케이션이나 전달받는 애플리케이션에 의해 데이터가 삭제되는 것은 아니지만 kafka 브로커 서버의 설정에 의해 데이터 보관되는 기준이 정해집니다.
설정된 보관 기준 안에서는 지속적으로 데이터를 가지고 있으며 기준이 넘어간 시점에는 데이터를 파기하게 되고 세그먼트 단위로 데이터를 관리하기 때문에 삭제될 때는 세그먼트 단위로 데이터가 삭제됩니다.
이러한 특징들 때문에 영속적인 데이터 관리를 제공하고 있다고 말할 수 있습니다.
[ 4. 고가용성 ]
kafka는 전달받은 데이터를 파일 시스템에 보관할 때 한 개의 브로커 서버에만 보관하는 것이 아니라 kafka에서 관리되고 있는 모든 브로커 서버에 데이터 복제를 수행합니다.
그래서 다수의 브로커 서버가 존재하는 상황에서 1개의 브로커 서버에 장애가 발생하더라도 복제된 데이터들이 각 서버들에 모두 저장되어 있기 때문에 지속적으로 데이터를 처리하는데 전혀 문제가 발생하지 않습니다.
즉, kafka는 특정 브로커 서버에 장애가 생기더라도 kafka를 사용하는 애플리케이션 입장에서 문제점이 발생될 확률이 낮습니다.
이런 특징을 가지고 있기 때문에 고가용성 처리를 할 수 있는 것을 보장합니다.
Kafka 주요 구성 요소
[ 1. 브로커 (Broker) ]
위에서도 언급되었던 브로커는 kafka를 구성하는 노드 서버들을 의미합니다.
k8s와 비교를 해보면 k8s가 master node, worker node 등의 서버들이 필요한 것처럼 kafka도 브로커 역할을 수행하기 위한 서버들이 필요한 것이라고 이해해주시면 됩니다.
kafka를 구성할 때 브로커 서버를 최소 3대 이상으로 묶어서 운영합니다.
그 이유로는 위에서 얘기한 kafka의 특징들을 유지하기 위해 브로커 서버에 전달받은 데이터를 파일 시스템에 저장하고, 복제를 통한 분산 저장들을 수행하기 위함입니다.
그리고 이런 파일 시스템들에 담겨있는 데이터들은 파일 단위 별로 데이터가 적재되어 있는데, 이 단위를 로그 세그먼트라고 부릅니다.
이 외에도 브로커는 한 대의 브로커가 다른 브로커의 상태를 관리하는 컨트롤러 역할과, 어느 데이터까지 데이터를 가져왔었는지에 대한 정보를 담아두는 컨슈머 오프셋 저장 기능 등 다양한 역할을 수행합니다.
[ 2. 토픽 (Topic) ]
토픽은 kafka에서 데이터를 분류하는 기본 단위입니다.
RDB와 비교를 해보자면 테이블과 같은 역할을 수행한다고 생각해 주시면 됩니다.
그래서 source 애플리케이션에서 kafka에 데이터 저장을 위한 행위를 할 때 어떤 토픽에 데이터를 저장할 것인지를 설정해 주게 됩니다.
그러면 해당 데이터는 설정한 토픽으로 전달되고 target 애플리케이션에서는 데이터를 확인하고자 할 때 어떤 토픽에 담겨 있는 데이터를 확인할 것인지를 설정하여 데이터를 전달받을 수 있게 됩니다.
[ 3. 파티션 (Partition) ]
파티션은 토픽에 전달된 데이터가 실제 저장되는 단위를 말합니다.
한 개의 토픽은 여러 개의 파티션으로 분할될 수 있고 파티션에 데이터가 저장될 때는 FIFO (First In First Out) 방식으로 저장이 이루어집니다.
그래서 먼저 저장된 메시지가 가장 먼저 target 애플리케이션에 전달되는 구조입니다.
파티션은 크게 리더 파티션과 팔로워 파티션으로 나눌 수 있습니다.
위에서 얘기한 것처럼 kafka는 각 브로커 서버마다 데이터를 복제해두기 때문에 브로커 서버마다 동일한 목적의 파티션들이 존재하게 됩니다.
이들 중 1개의 파티션에 대해서만 리더 파티션으로 설정되고 나머지는 팔로워 파티션으로 설정이 됩니다.
리더 파티션의 역할은 source 및 target 애플리케이션과 kafka가 통신될 때 직접적으로 통신되는 파티션을 의미합니다.
그래서 데이터가 kafka에 전달될 때나 또는 kafka에 담겨있는 데이터를 각 애플리케이션에 보낼 때 모두 리더 파티션을 통해서 작업이 이루어집니다.
나머지 팔로워 파티션 같은 경우는 리더 파티션의 오프셋 정보를 확인하여 자기 자신과 차이나는 경우 리더 파티션에서 데이터를 가져오는 작업을 수행하고 이런 과정이 데이터를 복제하는 과정이 됩니다.
그리고 만약 리더 파티션에 문제가 발생되는 경우 팔로워 파티션 중 하나를 리더 파티션으로 승격시켜 리더 파티션의 역할을 수행하게 되고 이런 과정을 통해 kafka가 고가용성이 보장되는 것입니다.
파티션은 토픽을 생성할 때 원하는 개수만큼 추가시킬 수 있습니다.
또한 기존의 파티션 개수보다 더 많은 파티션이 필요한 경우 개수를 증가시킬 수 있습니다.
하지만 아직까지 파티션의 개수를 줄이는 기능을 kafka에서 제공하고 있지 않습니다.
그래서 파티션의 개수를 늘렸었지만 더 이상 많이 필요하지 않은 상황일 때 파티션의 개수를 줄이고 싶다면 토픽을 처음부터 다시 만들어야 합니다.
[ 4. 레코드 (Record) ]
레코드는 kafka의 파티션에 저장되는 가장 기본적인 단위를 의미합니다.
레코드는 토픽에 전달되어 저장되는 메시지나 이벤트로도 부를 수 있습니다.
즉, 파티션에 저장되는 각각의 데이터들을 모두 레코드라고 부릅니다.
레코드는 다음과 같은 정보들이 담겨있습니다.
- 키 (Key) → 어떤 파티션에 레코드가 저장될지를 정하며 동일한 키는 항상 동일한 파티션에 저장되도록 도와줌
- 값 (Value) → kafka에 저장하고자 하는 실제 데이터를 의미
- 오프셋 (Offset) → 파티션 내부에서 레코드가 위치한 순서를 나타내는 값
- 타임스탬프 (Timestamp) → 레코드가 kafka에 저장된 시간을 의미
[ 5. 프로듀서 (Producer) ]
프로듀서는 kafka에 레코드를 전달하는 주체이며 source 애플리케이션에 존재합니다.
프로듀서는 어떤 토픽에 어떤 레코드를 담을지에 대한 정보들을 담아 kafka에 전달하는 역할을 수행합니다.
또한 레코드를 전달할 때 kafka의 설정에 맞게 파티션이 설정되지 않고 프로듀서에 의해 파티션이 설정되어 저장할 수도 있습니다.
[ 6. 컨슈머 (Consumer) ]
컨슈머는 kafka를 구독하고 있다가 프로듀서에 의해 전달된 레코드가 존재한 것을 인식하면 레코드를 가져와 필요한 비즈니스 로직을 수행하는 주체입니다.
즉, target 애플리케이션에 존재합니다.
컨슈머는 컨슈머 그룹을 통해 파티션으로부터 읽어온 오프셋 정보가 관리될 수 있습니다.
여러 컨슈머가 한 개의 컨슈머 그룹을 형성하여 부하를 분산시킬 수 있고, 때로는 동일한 토픽에 저장되어 있는 데이터들을 서로 다른 비즈니스 로직에서 활용하고자 할 때 각 로직 별 컨슈머 그룹을 설정하여 독립적으로 각각 데이터를 전달받을 수도 있습니다.
또한 데이터를 읽어오는 과정에서 애플리케이션에 장애가 발생되었을 때 애플리케이션이 다시 구동이 된 이후 어떤 데이터부터 읽어와야 되는지에 대한 정보가 컨슈머 그룹 별로 설정되어 있기 때문에 중복된 레코드 정보를 가져오지 않도록 관리되는 것에도 도움을 줍니다.
Kafka 실 사용 사례
[ 1. 실시간 로그 수집 및 분석 ]
kafka는 여러 서비스에서 발생되는 로그 데이터들을 수집하는 데 사용될 수 있습니다.
예를 들어, 다양한 서비스에서 사용되는 API 호출 로그를 수집하고자 할 때 모든 서비스에서 API가 호출될 때마다 호출된 API 정보를 한 개의 토픽에 지속적으로 전달할 수 있습니다.
그리고 해당 토픽을 구독하고 있는 컨슈머는 전달된 로그 정보를 확인하여 데이터를 저장하고 다양한 사례에 맞게 분석 데이터로써 활용될 수 있습니다.
[ 2. 메시징 시스템 ]
kafka의 메시징 시스템은 msa에서 많이 활용될 수 있습니다.
각 마이크로 서비스에서 가지고 있는 고유한 도메인 정보들을 서로 다른 서비스에 공유해야 될 때 kafka의 메시징 처리를 이용하여 효율적인 관리를 할 수 있습니다.
예를 들어, 다양한 서비스에서 사용자의 이름 정보를 사용하고 있을 때 사용자를 관리하는 마이크로 서비스에서 사용자의 정보가 바뀌게 되면 변경된 데이터를 토픽에 전달하게 됩니다.
그리고 사용자의 이름 정보를 사용하는 각 서비스에서는 해당 토픽을 구독하고 있다가 전달된 데이터 정보에 맞게 이름을 변경해 줄 수 있습니다.
이를 통해 각 마이크로 서비스 단위로 나뉘어 있는 정보들이지만 필요에 따라 메시징 시스템 기능을 활용하여 각 마이크로 서비스들에 정보를 공유할 수 있습니다.
[ 3. 데이터 파이프라인 ]
kafka는 커넥트와 커넥터를 활용하여 데이터 파이프라인의 중추적인 역할을 수행할 수 있습니다.
특정 데이터베이스에 담겨 있는 데이터 정보가 변경 및 삭제될 때 작업이 이루어진 데이터 정보를 수집하고, 이를 필요로 하는 데이터베이스나 분석 시스템으로 전달할 수 있습니다.
예를 들어, 데이터를 삭제할 때마다 삭제된 데이터 정보를 수집하여 삭제 이력 정보를 관리하는 데이터베이스로 전달하는 기능을 제공할 수 있습니다.
이 과정에서도 특정 토픽과 파티션에 레코드 정보를 저장하는 절차가 동일하게 수행됩니다.
이상으로 kafka로 분산형 데이터 처리하기 첫 번째인 kafka란 무엇인가에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'Spring > SpringBoot' 카테고리의 다른 글
[SpringBoot] Kafka로 분산형 데이터 처리하기 (3) - Kafka에서 사용하는 명령어 (0) | 2024.09.03 |
---|---|
[SpringBoot] Kafka로 분산형 데이터 처리하기 (2) - Virtual Box에서 Kafka 설치하기 (8) | 2024.08.25 |
[SpringBoot] Redis 테스트 환경 구축하기 (2) - Test Container (0) | 2024.07.27 |
[SpringBoot] Redis 테스트 환경 구축하기 (1) - Embedded (0) | 2024.07.07 |
[SpringBoot] Redis NOAUTH HELLO must be called with the client already authenticated 이슈 (0) | 2024.06.30 |
댓글