Kafka 한번 살펴보자... Introduction

2019. 6. 21. 17:08해보자/Kafka

발번역하면서, 살펴본다.

필요하다면 반드시, https://kafka.apache.org/intro 에 가서 직접 원문을 직접 읽어보는 것을 추천합니다.


 

Introduction

 

Apache Kafka is a distributed streaming platform.

What exactly does that mean?

 

Kafka 를 간략 정리하면. Apache Kafka는 분산 스트리밍 플랫폼입니다. 

 

  • 스트리밍 플랫폼은 세가지 핵심 능력을 갖고 있습니다.

    • 메시지 큐나 엔터프라이즈 메시징 시스템과 비슷하게, 레코드 스트림을 구독하고 발행합니다.

    • 장애 허용 지속 방식(fault-tolerant durable way)으로 레코드 스트림을 저장합니다.

    • 레코드 스트림이 발생할 때 처리합니다.(Process streams of records as they occur.)

  • Kafka는 크게 두 분류의 어플리케이션에 사용됩니다.

    • 시스템 또는 어플리케이션간에 데이터를 안정적으로(reliably) 획득하는
      실 시간 스트리밍 데이터 파이프라인 구축 용도 

    • 데이터 스트림을 변형하거나 반응하는 실 시간 스트리밍 어플리케이션 구축 용도 

우선 몇가지 개념으로 

  • Kafka는 다수의 데이터센터로 확장 될 수 있는 다수의 서버에서 하나의 Kafka Cluster로 실행됩니다.

  • Kafka Cluster는 Topic이라는 카테고리에 레코드 스트림을 저장합니다.

  • 각각의 레코드는 하나의 키, 값 그리고 타임스탬프로 구성되어 있습니다.

Kafka는 네가지의 핵심 API를 가지고 있습니다.

 

 

Kafka에서 클라이언트와 서버 간에 커뮤니케이션은 단순하고,
높은 성능의 언어에 구애 받지 않은 TCP 프로토콜로 수행됩니다.

이 프로토콜은 버전이 지정되며, 이전 버전과의 하위 호환성(backward compatibility)을 유지합니다.

Kafka를 위한 자바 클라이언트를 제공하지만, 클라이언트는 많은 언어로 제공합니다.

Clients :  https://cwiki.apache.org/confluence/display/KAFKA/Clients

 

 

Topics and Logs

 

Kafka가 레코드 스트리밍을 위해 제공하는 핵심 추상 개념인 Topic에 대해서 알아봅시다.

Topic은 발행된(published) 레코드의 카테고리 혹은 피드명입니다.

Kafka의 Topic은 항상 멀티-구독자(multi-subscriber)입니다.

그 말은, Topic은 Topic에 작성된 데이터를 구독(subscribe)하는 
0, 1 또는 다수의 Consumer(consumer)들을 가질수 있습니다.

 

각각의 Topic에 대해, Kafka Cluster는 아래와 같이 파티션된 로그를 유지합니다. 

 

각각의 파티션은 하나의 정렬된, 불변의 레코드의 시퀀스이고, 그것은 구조화된 커밋 로그에 연속해서 추가됩니다.

 

파티션에서 레코드는 파티션 안에서 각각의 offset이라는 순차적인 id number가 할당되어 있습니다.

그것은 유니크하게  파티션 안에서 각각의 레코드를 구별합니다.

 

Kafka Cluster는 그 데이터의 소비 여부와 상관없이 설정 가능한 보류 기간을 사용하여
견고하게 모든 발행된 레코드들을 유지합니다. 

예를 들어 보유 정책을 이틀로 정했다면, 이틀동안, 레코드가 발행된 후에, 소비가 가능합니다.

그 후에 공간을 비우기 위해 버려질 것입니다.

Kafka의 성능은 데이터 크기와 관련하여 사실상 일정하기 때문에 오랫동안 데이터를 저장하는 것은
문제가 되지 않습니다.

 

 

사실상, consumer (per-consumer basis)마다 남아 있는 유일한 메타 데이터는
해당 로그에서 offset  혹은 consumer의 위치 입니다.

이 offset은 Consumer(consumer)에 의해 조절됩니다.

일반적으로 consumer는 레코드를 읽음으로싸, offset이  선형으로 나아갈 것입니다.

하지만, 실제 consumer가 그 위치를 제어하므로써, 원하는 순서대로 레코드를 소비할수 있습니다.

예를 들어 consumer는 과거의 데이터를 다시 처리하기 위해 이전 offset으로 재설정하거나,

가장 최근의 레코드 앞으로 건너 뛰고 "now"에서 소비하기 시작할 수 있습니다.

 

이 기능의 결합은 kafka consumer가 매우 싸다

- consumer들은 큰 충격없이 cluster 또는 다른 consumers로 오갈수 있다"라는 것을 의미합니다.

예를 들어, 모든 기존 consumer에 의해 소비된 것을 변경없이,
어떤 Topic의 내용을 "tail" 하는 커맨드 라인 툴을 사용할 수 있습니다.

 

로그의 파티션은 몇몇의 용도를 제공합니다.

첫번째, 로그를 단일 서버에 맞는 크기 이상으로 확장 가능하게 합니다.

각각의 개별적인 파티션은 호스트하는 서버에 적합해야 합니다.

하지만 하나의 Topic은 많은 파티션이 가질수가 있어서, 임의의 데이터 양을 처리 할 수 있습니다.

두번째, 로그의 파티션은 병렬 단위로 처리합니다. 

 

Distribution, 분산

 

로그의 파티션은 각 서버가 데이터를 처리하고  파티션의 공유에 대한 데이터와 요청과 함께 

Kafka Cluster의 Server들을 통해(over) 분산됩니다. 

각각의 파티션은 장애 허용을 위해  구성가능한 수의 서버들에 복제됩니다.

 

각 파티션은 "leader"로 동작하는 하나의 서버를 가지고 있고, 

"followers"로 동작하는 0 또는 그 이상의 서버들을 가지고 있습니다.

리더는 파티션을 위한 모든 read 와 write 요청을 다루는 반면 follower은 리더를 수동적으로 복제합니다.

만일 leader가 실패하면 , follower중에 하나가 자동으로 새로운 리더가 됩니다.

각 서버는 일부 파티션의 리더와 다른 서버의 팔로어로 작동하므로, 로드는 Cluster 안에서 잘 균형을 잡습니다.

 

 

Geo-Replication

 

Kafka MirrorMaker는 여러분의 cluster를 위해 geo-replication support를 제공합니다.

MirrorMaker와 함께, 멀티 데이터 센터 또는 클라우드 지역을 넘어 메세지가 복제됩니다.

 backup과 recovery을 위해 능동/수동(active/passive) 시나리오에서 이것을 사용할 수 있습니다.

또는 데이터를 유저 가까지 위치하거나 데이터 지역성 요구사항을 지원하는
활성/비활성 시나리오에서 사용할 수 있습니다.

 

 

Producers

 

producers는 선택한 Topic에 데이터를 게시합니다.

producer는 Topic안에서 어떤 파티션에 어떤 레코드를 할당할지를 선택해야 할 책임이 있습니다.

(The producer is responsible for choosing which record to assign to which partition within the topic)

이건 간단히 부하에 대한 균형잡기 위해 라운드 로빈 방식으로 수행될 수 있습니다.

또는 의미론적 파티션 함수에 따라 수행될 수 있습니다.(레코드의 일부 키에 기반해서)

두번째로 파티셔닝을 많이 사용합니다.

 

Consumers

 

Consumer는 자신의 consumer group 이름으로 레이블을 지정하고, 

Topic에 게시된 각 레코드는 구독하고 있는 각각의 consumer group안에 한 Consumer 인스턴스에 전달됩니다. 

Consumer 인스턴스는 분리된 프로세스 또는 분리된 장비에 있을 수 있습니다.

모든 Consumer 인스턴스가 동일한 Consumer 그룹을 갖는 경우,
레코드는 Consumer 인스턴스를 넘어 효율적으로 로드 밸런싱 됩니다.

모든 Consumer 인스턴스가 다른 Consumer 그룹을 갖는 경우,
레코드는 모든 Consumer 프로세스들에 브로드캐스팅 될겁니다.

 

 

 

두개의 Consumer 그룹과 함께 네개의 파티션(p0-p3)을 호스팅하는 두 서버 Kafka Cluster.

Consumer 그룹 A은 두 Consumer 인스턴스를 갖고, 그룹 B는 네개의 Consumer를 가지고 있습니다.

 

그러나 더 일반적으로 ,
각각의 "논리적 구독자"에 대비해 한개 적은  Topic의 Consumer 그룹을 가지고 있는것을 발견했습니다.

각 그룹은 확장성 및 내결함성에 대한 많은 Consumer 인스턴스로 구성됩니다.

구독자가 단일 프로세스 대신 Consumer Cluster인 게시/구독 의미 체계, 그 이상도 아닙니다.

 

Kafka에서 소비가 구현되는 방법은 

각 인스턴스가 어느 시점에서 파티션의 "공정한 공유"에 독점적인 Consumer이기 위해서

Consumer 인스턴스로(over) 로그의 파티션을 나누는 것입니다.

그 그룹에서 멤버쉽 유지의 절차는 동적으로 Kafka 프로토콜에 의해 다뤄집니다.

새 인스턴스가 그룹에 참여하면, 그 그룹의 다른 멤버들로 부터 일부 파티션을 인수할 것입니다.

만약 인스턴스가 죽으면, 해당 파티션은 남아있는 인스턴스에 분배될것입니다.

 

카프카는 하나의 Topic안에 다른 파티션들간이 아니고 오로지 파티션 안에서만 전체 주문을 제공합니다. 

키에 의해 데이터를 분할하는 능력과 결합된 파티션별 순서 지정은 대부분의 어플리케이션에 대해선 충분합니다.

하지만, 레코드의 전체 순서가 필요하다면 , 한 파티션만을 갖는 Topic으로 얻을수 있습니다.

다만 이것은 오직 하나의 Consumer 그룹마다 하나의 Consumer만 처리한다는 것을 의미합니다.

 

 

Multi-tenancy 

 

여러분은 Kafka를 다수의 사용자를 위한 솔루션으로 배포할수 있습니다.

Muti-tenancy은 데이터를 생산 할 수 있고, 소비할 수 있는지를 특정 토픽들을 설정으로 가능합니다.

할당량(quotas)를 위한 운영 지원 역시 있습니다.

관리자는 클라이언트가 사용하는 브로커 리소스를 조정하기 위해 요청에 대한 할당량을 정의할수 있고
강화할수 있습니다. 

좀 더 자세한 내용은 security documentation( https://kafka.apache.org/documentation/#security)을 보시길 바랍니다.

 

Guarantees

 

하이레벨 카프카에서 제공하는 게런티는 다음과 같습니다.

 

  • 프로듀서가 특정 토픽 파티션에 보낸 메시지는 보낸 순서대로 추가 됩니다.
    즉, 레코드 M1이 레코드 M2와 동일한 프로듀서에 의해 보내지고,
    M1이 먼저 보내지면, M1은 M2 보다 더 낮은 오프세을 가지며 로그에서 더 일찍 나타납니다. 

  • consumer 인스턴스는 로그에 저장된 순서대로 레코드를 봅니다.

  • replication factor N을 갖는 Topic을 위해,
    로그에 커밋된 레코드를 잃지 않고 최대 N-1 개의 서버 오류를 허용합니다.

 

Kafka as a Message System

 

전통적인 엔터프라이즈 메세징 시스템과 비교해서 Kafka의 스트림의 개념은 어떻게 비교할까?

메시징은 전통적으로 두개의 모델을 가지고 있습니다 : 큐잉과 pub-sub.

큐에서는, consumer의 pool은 서버로 부터 읽혀서, 각각의 레코드는 그중에 하나로 갈것이다.

pub-sub에서는, 그 레코드가 전체 consumer들에게 브로드캐스트될것입니다.

이들 두 모델마다 강점과 약점을 가지고 있습니다.

큐의 강점은 다수의 consumer 인스턴스에서(over) 데이터 처리를 나눌수 있으므로, 처리 규모를 확장할수 있습니다.

불행하게도, 큐은 멀티-subscriber가 아니다.

한 프로세스가 데이터를 읽고 가버린다.

pub-sub은 멀티 처리를 하기 위해 데이터를 브로드캐스팅하지만, 

모든 메세지가 모든 구독자에게 가기 때문에 프로세싱을 확장할수 있는 방법이 없습니다.

 

Kafka의 consumer group은 두가지 컨셉을 일반화합니다.

큐와 마찬가지로 consumer group은 프로세스 컬렉션(consumer group의 멤버)을 통해 프로세싱을 나눌수 있습니다.

pub-sub과 마찬가지로, Kafka은 멀티 consumer groups에 메세지를 브로드캐스팅하게 합니ㅣ다.

 

kafka 모델의 장점은, 모든 토픽이 이런 속성 모두를 가지고 있다는 것입니다.

프로세싱을 확장할수 있고, 또한 멀티-구독자라는 것이죠.

하나 또는 둘 다를 선택할 필요가 없습니다.

 

카프카는 정렬을 보장하는데, 전통적인 메세징 시스템보다 강점이 있습니ㅣ다.

 

전통적인 큐는 서버에 순서대로 레코드를 남기고,

만약 멀티 consumer가 큐에서 소비하면, 서버는 저장된 순서대로 레코드를 분배(hand out)합니다.

하지만, 서버가 순서대로 레코드를 분배하더라도, 레코드는 비동기적으로 consumer에게 전달됩니다.

그래서 다른 consumer에 순서 없이 도착할 것입니다.

이것은 실제로 별렬 소비가 발생하면 레코드의 순서가 손실된다는 것을 의미합니다.

메세징 시스템은 대기열에서 하나의 프로세스만 사용할 수 있는 "독점적인 consumer"라는 개념을 사용하여,

이 문제를 해결하기도 하지만, 처리 과정상에서는 병렬 처리가 없다는 것을 의미 합니다.

 

Kafka는 이보다 낫습니다.

Topic 내에서 병렬 처리 개념(파티션)을 가짐으로써 Kafka는 고객 프로세스 풀에 대해 주문 보증 및 로드 밸런싱을 제공 할 수 있습니다.

이는 Topic에 파티션을 consumer group의 consumer에게 할당하여 각 파티션이 그룹의 정확히 한 소비자에 의해 소비되도록 하여 수행됩니다.

이렇게 하므로써 우리는 소비자가 해당 파티션의 유일한 독자임을 확인하고 순서대로 데이터를 소비합니다.

파티션이 많으므로 많은 소비자 인스턴스에서 로드의 균형을 유지합니다.

그러나 소비자 그룹에는 파티션보다 더 많은 소비자 인스턴스가 있을 수 없습니다.

 

 

Kafka as a Storage System

 

분리된 공개 메시지가 메세지를 소비하지 못하게 하는 메시지 대기열은 사실상 메시지의 저장 시스템 역활을 합니다.

카프카가 다른점은 그것이 매우 훌륭한 저장 시스템이라는 것입니다.

 

Kafka에 기록된 데이터는 디스크에 기록되고 내결함성을 위해 복제됩니ㅣ다.

Kafka는 생산자가 승인을 기다릴 수 있도록 하여 쓰기가 서버가 완전히 실패 할 때까지 

계속 복제 될 때까지 쓰기가 완료된 것으로 간주하지 않도록 합니ㅣ다.

 

Kafka가 scale well-Kafka를 사용하는 디스크 구조는 서버에 50KB 또는 50TB 의 영구 데이터 가지고 있더라도 동일하게 수행합니다.

스토리지를 중요하게 생각하고 클라이언트가 읽기 위치를 제어 할 수 있게 된 결과,

Kafka는 고성능, 낮은 대기 시간의 커밋 로그 저장, 복제 및 전파 전용의 특수 목적 분산 파일 시스템으로 생각 할 수 있습니다.

 

보다 자세한건, Kafka의 커밋 로그 저장소와 복제 설계는 여기서 읽으세요

https://kafka.apache.org/documentation/#design

 

 

Kafka for Stream Processing

 

데이터 스트림을 읽고, 쓰고, 저장하는 것만으로는 충분하지 않습니다.

목적은 스트림의 실시간 처리를 가능하게 하는 것입니다.

 

Kafka에서 스트림 프로세스는 입력 Topic에서 연속적인 데이터 스트림을 취하여,

이 입력에 대한 처리를 수행하고 주제를 출력하기 위해 지속적인 데이터 스트림을 생성하는 모든 것입니다.

 

예를 들어, 소매 응용 프로그램은 판매 및 출하의 입력 스트림을 받아 들여,

이 데이터에서 계산 된 재주문 및 가격 조정 스트림을 출력 할 수 있습니다.

 

producer API와 consumer API를 사용하여 직접 간단한 처리를 수행할 수 있습니다.

그러나 보다 복잡한 변환의 경우 Kafka는 완전히 통합된 Stream API를 제공합니다.

따라서 스트림에서 집계를 계산하거나 스트림을 함께 결합하는 중요하지 않은 처리를 하는 응용 프로그램을 빌드 할 수 있습니다.

 

이 기능은 이러한 유형의 응용 프로그램이 직면 한 어려운 문제를 해결하는데 도움이 됩니다.

즉, 순서가 잘 못된 데이터 처리, 코드 변경으로 입력 다시 처리, 상태 저장 계산 등을 수행하는 데 도움이 됩니다.

스트림 API는 Kafka가 제공하는 핵심 기본 요소를 토대로 입력을 위한 producer API와 consumer API는 상태 저장을 위해 Kafka를 사용하고 

스트림 프로세서 인스턴스 간에 내결함성을 위해 동일한 그룹 매커니즘을 사용합니다.

 

Putting the Pieces Together

 

 

메시징, 스토리지, 스트림 처리의 결합은 보기 드문것처럼 보이지만,
스트리밍 플랫폼으로써 Kafka의 역활에 필수 적입니다.

 

HDFS와 같은 분산 파일 시스템은 일괄 처리(batch processing)을 위해 정적 파일을 저장할 수 있습니ㅣ다.

사실상, 이와 같은 시스템은 데이터를 저장하고 처리 할 수 있게 합니ㅣ다.

 

전통적인 엔터프라이즈 메시징 시스템을 사용하면 가입 후 도착할 예정인 메시지를 처리 할 수 있습니다.

이러한 방식으로 구축된 응용 프로그램은 도착할 때 미래의 데이터를 처리합니ㅣ다.

 

Kafka는 이 두 가지 기능을 모두 갖추고 있으며, 스트리밍 응용 프로그램 및 스트리밍 데이터 파이프 라인을 위한 플랫폼으로 Kafka를 사용하는 데 있어, 이 두 가지 기능이 모두 중요합니다.

 

스토리지 및 대기 시간이 짧은 구독을 결합하여 스트리밍 응용 프로그램은 과거 및 미래 데이터를 동일한 방식으로 처리 할 수 있습니다.

즉, 단일 응용 프로그램에서 기록된 저장된 데이터를 처리 할 수 있지만 마지막 레코드에 도달 할 때 종료하지 않고, 

이후 데이터가 도착할 때 처리를 유지할 수 있습니다.

이는 메시지 처리 응용 프로그램 뿐만 아니라 일괄 처리를 포함하는 스트림 처리의 일반화된 개념입니다.

 

마찬가지로 스트리밍 데이터 파이프 라인의 경우 실시간 이벤트에 가입하면 매우 짧은 지연 시간의 파이프 라인에 Kafka를 사용할 수 있습니다.

그러나 데이터를 안정적으로 저장하는 기능은 데이터 전달을 보장해야 하는 중요한 데이터 또는 정기적으로 데이터를 로드하거나 유지 관리를 위해 오랜 기간 동안 데이터를 다운로드 하는 오프라인 시스템과의 통합을 위해 데이터를 사용 할 수 있게 합니다.

스트림 처리 설비는 도착한 데이터를 변환 할수 있게 합니다.

 

좀더 자세한 내용은 여기서 보세요

https://kafka.apache.org/documentation.html