Post
EN

Kafka 알아보기

Kafka 는 분산 Streaming 플랫폼이다.

  1. record의 stream을 pub/sub하고 싶을 때 message queue나 enterprise messaging System처럼 사용할 수 있다.

  2. record의 stream을 (고장에도 견딜 수 있는 시스템) 저장할 수 있다.

  3. record의 stream을 처리할려고 할 수 있다.

( stream of record = 데이터 흐름으로 -_-;; )

kafka가 무엇이 좋은지.

  1. 실시간으로 System과 application 사이의 믿을 수 있는 데이터 streaming data pipelines을 구축할 수 있다.

  2. 실시간으로 data stream의 변환 또는 반응 을 할 수 있는 streaming application을 구축할 수 있다.

kafka에 대해 알아보자

  1. kafka는 하나 이상의 서버에서 클러스터로 동작한다.

  2. kafka cluster는 데이터의 흐름을 topic이라고 불리우는 카테고리 형태로 저장한다.

  3. 각 record에는 key, value, timestamp들이 존재한다.

![](/assets/images/posts/221094981893/5ea607acbfea.png)

producer API = publisher

consumer API = subscriber

stream API = 어플리케이션을 하나 이상의 topic로부터 input stream 과 하나 이상의 topic들을 생산하는 스트림 프로세서로서 동작할 수 있다. 효율적으로 input stream 과 output stream을 변환합니다.

kafka는 클라이언트와 서버들간에 수행되는 통신은 단순하며, 높은 성능을 자랑하고, 언어에 비종속적인 TCP protocol을 사용합니다.

이러한 protocol은 버전이 지정되며 이전 버전과의 하위 호환성을 유지합니다.

우리는 java kafka client를 제공해줍니다. 그러나 clients들은 많은 language에서 가능하지는 않습니다.

Topics과 Logs

kafka는 topic을 통해서 데이터 흐름을 제공합니다.

하나의 topic은 record가 발행되는 category 또는 feed 이름 입니다.

카프카에서 토픽은 항상 다중 구독입니다. 즉 토픽은 작성된 데이터를 구독할 수 있는 0, 1또는 많은 구독자를 가질 수 있습니다.

각각 토픽은, kafka cluster 에 분활된 로그 형태로 남아 있습니다

![](/assets/images/posts/221094981893/840c899b9808.png)

각 파티션은 계속해서 추가될 수 있는 정렬된 불변형의 순차열로 구조화된 commit log 입니다.

파티션 안의 레코드들은 각각 offset이라 불리우는 sequential id number로 할당되어집니다.

파티션 안의 레코드들은 유일하게 식별될 수 있습니다.

kafka cluster는 발행된 모든 레코드들을 보관합니다. (소비가 되었는지 안되었는지도 포함)

보유 기간도 설정 가능합니다.

예를 들어, 만약 보유 정책이 2일로 설정되어있다면, 레코드가 발행되어진지 2일 동안 사용할 수 있으며 그 이후에는 사용 가능한 공간을 늘리기 위해 폐기 됩니다. Kafka의 성능은 데이터 크기와 관련하여 사실상 일정하기 때문에 오랫동안 데이터를 저장하는 것은 문제가되지 않습니다.

![](/assets/images/posts/221094981893/434ec275e923.png)

사실, 소비자 당 기준으로 유지되는 유일한 메타 데이터는 로그에서 해당 소비자의 오프셋 또는 위치입니다. offset은 consumer에 의해서 제어 되어집니다. 정상적으로 consumer는 offset은 record들을 읽기 위해서 선형적으로 증가 되지만 실제로 position은 소비할 수 있는 record는 consumer 제어됩니다. 예를 들어 소비자는 과거의 데이터를 다시 처리하기 위해 이전 오프셋으로 재설정하거나 가장 최근 레코드로 건너 뛰고 지금에서 소비하기를 시작할 수 있습니다.

이러한 형태의 조합은 카프카 컨슈머들은 매우 값싸다는 것을 의미합니다. 카프카 컨슈머들은 클러스터 나 다른 소비자들에게 큰 영향을 미치지 않고 왔다갔다 할 수 있습니다. 예를 들어, 당신은 우리의 커멘드 라인 툴에서 “tail”을 이용하어 어떤 토빅의 내용을 다른 컨슈머가 소비하여도 변경되는 것 없이 사용 할 수 있습니다

로그의 파티션은 여러 가지 용도로 사용됩니다.

첫번째, 로그의 파티션들은 싱글 서버의 규모 이상으로 확장을 허용합니다. 이런 각각의 파티션들은 반드시 서버에 알맞게 맞아야 합니다. 그러나 토빅은 많은 파티션들을 가지고 있을지도 모릅니다. 그래서 토빅은 데이터의 대부분을 임의적으로 조절 할 수 있습니다.

두번째, 파티션들은 병렬처리 단위 처럼 동작합니다.

Distribution

로그의 파티션들은 각각의 서버에서 데이터를 관리하는 것과 공유를 위한 요청들을 카프카 클러스터 서버에 의해서 분산되어 집니다. 각각의 파티션은 장애허용을 위해서 설정가능한 서버들의 숫자를 통해서 복제되어집니다.

각각의 파티션은 리더의 역활을 하는 서버나 follower라는 역할을 하는 서버를 0개 또는 1개 이상 서버를 갖습니다.

리더는 follower가 수동적으로 leader를 복제하는 동안 파티션의 모든 읽기/쓰기의 요청들을 관리합니다. 만약 리더에 문제가 생겻을 때, follower들 중 하나가 자동적으로 새로운 리더가 될 것입니다.

각 서버는 일부 파티션의 리더와, follower의 역할을 합니다. 그것들은 클러스터들 안에서 부하가 분산되어 유지하게 됩니다.

Producers

producer들은 결정된 topic들로 data를 생산합니다. producer는 topic내에서 어떤 파티션에 할당 할 레코드를 선택해야 합니다. 이것은 라운드 로빈 방법으로 균형있게 적제되거나 또는 일부 의미적 파티션 함수를 따라서 완료 할 수 있습니다.

Consumer

Consumer들은 각자마다 consumer group name이 붙여집니다, 그리고 각각 topic으로 발행되어진 레코드들은 consumer group의 구독 인스턴스들 중 1개의 consumer에게 전달되어 집니다.

consumer 인스턴스들은 별도의 프로세스나, 별도의 머신들에 있을 수 있습니다.

만약 모든 consumer 인스턴스들이 같은 consumer group을 가지고 있다면, 그러면 레코드들은 효율적으로 consumer instance들로 인하여 부하 분산 될 것입니다.

만약 모든 consumer 인스턴스들이 다른 consumer group을 가지고 있다면, 그러면 모든 consumer process들에게 각 레코드들은 broadcast 될 것 입니다.

![](/assets/images/posts/221094981893/60e8f7c6fd4f.png)

두개의 consumer group과 4개의 partition인 kafka cluster 호스팅 서버 2개.

consumer gorup A는 2개의 consumer 인스턴스를 가지고 있고 group B는 4개를 가지고 있다.

그러나 보다 일반적으로, 우리는 topics이 하나의 논리적인 구독자 형태로 적은 수의 consumer 그룹을 가지고 있는 발견했습니다.

각 그룹은 많은 consumer instance들과 확장성과 장애허용을 위해서 구성되어져 있었습니다.

이것은 publish-subscribe 의미들 이상이 아닙니다. subscriber는 single process 대신에 consumer들의 인스턴스 클러스터 입니다.

카프카에서 소비가 구현되는 방식은 소비자 인스턴스를 통해 로그의 파티션을 나누어 각 인스턴스가 어느 시점에서든 파티션의 “공정한 공유”를 독점적으로 사용하는 것입니다. 이러한 그룹 안에 인스턴스들이 유지하는 과정은 kafka 프로토콜이 다이나믹하게 관리합니다. 만약 새로운 인스턴스들이 그룹에 가입하면 그들은 그룹의 다른 멤버들로 부터 일정 파티션으로 인계 됩니다. 만약 인스턴스가 죽으면, 이 파티션은 남아있는 instance로 분산되어 질 것입니다.

kafka는 topic의 다른 파티션 사이가 아닌 파티션내의 레코드에 대해서만 전체 순서를 제공해줍니다.

대부분의 응용 프로그램에서 키 단위로 데이터를 분할하는 기능과 결합 된 분할 단위 별 정렬로 충분합니다. 그러나, 만약 너가 전체 레코드의 정렬을 요구하면 유일한 하나의 파티션이 가지고 있는 토픽들과 함께 수행할 수 있습니다. 이것은 consumer group의 유일한 1개의 consumer process 를 의미합니다.

Guarantees

높은 수준의 kafka에서는 다음의 보장을 합니다.

메시지들은 특별한 Topic partition에 의해서 그들이 보내준 순서대로로 덧붙여지는 형태로 보내집니다. 이것은, 만약 record M1이 같은 producer가 record M2로 보냈을 때와 M1 첫번째로 보내졌을때,

그러면 M1은 M2보다 적은 offset 을 가질져서 로그상에서 더 빨리 나타날 것입니다.

Consumer 인스턴스는 정렬된 record들을 볼때 로그에 저장되어 있을 것입니다.

복제 인수 N이있는 항목의 경우 로그에 커밋 된 레코드를 손실하지 않고 최대 N-1 개의 서버 오류를 허용합니다. 더 자세한것들은 이러한 보장성들 도큐먼트의 디자인 섹션에서 얻어라.

Kafka as a Messaging System

어떻게 kafka의 stream의 개념은 전통적인 엔터프라이즈 메시지 시스템과 비교할 수 있을까?

전통적으로 메시징은 queuing 과 publish-subscribe의 2가지 모델을 가지고 있습니다.

대기열에서 소비자 풀은 서버에서 읽을 수 있으며 각 레코드는 그 중 하나에 저장됩니다.

publish-subscribe의 경우, 레코드는 모든 consumer들에게 방송합니다. 각 두가지 모델은 강점과 약점을 가지고 있습니다. 대기열의 강점은 다중 consumer 인스턴스들에게 데이터를 분할해서 처리할 수 있도록 해줍니다. 이러한 것은 처리 규모를 확장할 수 있습니다.

불행하지만, queue들은 다중 구독자는 아닙니다. - 하나의 프로세스가 데이터를 읽었을 때. publish-subscribe은 여러 프로세스에 데이터를 브로드 캐스트 할 수 있지만, 모든 메시지가 모든 subscriber에게 전달되므로 처리 규모를 조절하는 것은 불가능합니다.

kafka에서의 consumer group의 개념은 이 2 개념을 일반화 합니다.

queue에서처럼 consumer group은 프로세스 모음 (소비자 그룹의 구성원)을 통해 처리를 나눌 수 있습니다. publish-subscribe에서 처럼, kafka는 다중의 consumer 그룹들에게 메시지를 broadcast 할 수 있습니다.

카프카의 모델의 장점은 모든 주제가 이러한 속성을 모두 갖추고 있다는 것입니다. 즉, 처리 규모를 조정할 수 있고 다중 subscribe 이기도하므로 둘 중 하나를 선택할 필요가 없습니다.

kafka는 기존의 메시지 시스템 보다 강력하게 순서를 보장합니다.

기존의 queue는 서버에 정렬된 record를 보유하고, 여러 consumer가 queue에서 소모하는 경우 서버는 저장된 순서대로 record를 전달합니다.

그러나, 비록 서버에서 처리된 정렬된 레코드들은, 비동기적으로 consumer에서 전달되어지므로 record는 서로 다른 consumer들에게 순서가 잘못 될 수 있습니다. 병렬 소비가 발생하면 레코드의 순서가 손실된다는 것을 의미합니다.

kafka는 더 잘합니다. 주제 내에서 병렬 처리 개념 (파티션)을 가짐으로써 카프카는 kafka는 더 좋습니다. 프로세스 풀에 대해 주문 보증과로드 밸런싱을 모두 제공 할 수 있습니다. 이는 주제의 파티션을 소비자 그룹의 소비자에게 할당하여 각 파티션이 그룹의 정확히 한 소비자에 의해 소비되도록하여 수행됩니다. 이렇게하면 소비자가 해당 파티션의 유일한 독자이고 순서대로 데이터를 사용하게됩니다. 파티션이 많으므로 많은 소비자 인스턴스에서로드의 균형을 유지합니다. 그러나 소비자 그룹에는 파티션보다 더 많은 소비자 인스턴스가있을 수 없습니다.

Kafka as a storage System

분리 된 공개 메시지가 메시지를 소비하지 못하게하는 메시지 큐는 사실상 메시지의 저장 시스템으로 작동합니다. 카프카가 다른 점은 그것이 매우 훌륭한 저장 시스템이라는 것입니다.

kafka에 기록된 데이터는 disk에 기록되고 내구성을 위해서 복제됩니다. kafka는 producer들에게 접수통지를 받을 때까지 기다리게 합니다. 그래서 쓰기가 완료 될 때까지 쓰기가 완료된 것으로 간주되지 않으므로 서버 작성이 실패한 경우에도 지속됩니다.

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

스토리지를 중요하게 생각하고 클라이언트가 읽기 위치를 제어 할 수있게 된 결과, Kafka는 고성능, 낮은 대기 시간의 커밋 로그 저장, 복제 및 전달 전용의 일종의 특수 목적의 분산 파일 시스템으로 생각할 수 있습니다.

Kafka for Stream Processing

데이터 스트림을 읽고, 쓰고, 저장하는 것만으로는 충분하지 않습니다. 목적은 스트림의 실시간 처리를 가능하게하는 것입니다.

Kafka에서 스트림 프로세서는 입력 항목에서 연속적인 데이터 스트림을 가져 와서이 입력에 대한 일부 처리를 수행하고 topic을 출력하기 위해 지속적인 데이터 스트림을 생성하는 모든 것입니다.

예를 들어, 소매 응용 프로그램은 판매 및 출하의 입력 스트림을 받아 들여이 데이터에서 계산 된 재주문 및 가격 조정 스트림을 출력 할 수 있습니다.

producer API와 consumer API를 사용하여 직접 간단한 처리를 수행 할 수 있습니다. 그러나보다 복잡한 변환의 경우 Kafka는 완전히 통합 된 Streams API를 제공합니다. 따라서 스트림에서 집계를 계산하거나 스트림을 함께 결합하는 중요하지 않은 처리를하는 응용 프로그램을 작성할 수 있습니다.

이 기능은이 유형의 애플리케이션이 직면 한 어려운 문제를 해결하는 데 도움이됩니다. 즉, 순서가 잘못된 데이터 처리, 코드 변경으로 인한 입력 재 처리, 상태 계산 등입니다.

스트림 API는 Kafka가 제공하는 핵심 기본 요소를 기반으로합니다. 입력에 생산자 및 소비자 API를 사용하고, 상태 저장을 위해 Kafka를 사용하며, 스트림 프로세서 인스턴스 간의 내결함성을 위해 동일한 그룹 메커니즘을 사용합니다.

Putting the Pieces Together

메시징, 스토리지 및 스트림 처리의 이러한 결합은 드문 것처럼 보일 수 있지만 스트리밍 플랫폼으로서의 카프카의 역할에 필수적입니다.

HDFS와 같은 분산 파일 시스템을 사용하면 일괄 처리를 위해 정적 파일을 저장할 수 있습니다. 사실상 이와 같은 시스템을 사용하면 과거의 기록 데이터를 저장하고 처리 할 수 ​​있습니다.

기존 엔터프라이즈 메시징 시스템을 사용하면 가입 한 후에 도착할 향후 메시지를 처리 ​​할 수 ​​있습니다. 이런 식으로 작성된 응용 프로그램은 도착하는대로 미래의 데이터를 처리합니다.

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

스토리지 및 대기 시간이 짧은 구독을 결합하여 스트리밍 응용 프로그램은 과거 및 미래 데이터를 동일한 방식으로 처리 할 수 ​​있습니다. 즉, 단일 응용 프로그램에서 기록 된 저장된 데이터를 처리 할 수 ​​있지만 마지막 레코드에 도달 할 때 종료하지 않고 이후 데이터가 도착할 때 처리를 유지할 수 있습니다. 이는 메시지 처리 응용 프로그램뿐만 아니라 일괄 처리를 포함하는 스트림 처리의 일반화 된 개념입니다.

마찬가지로 스트리밍 데이터 파이프 라인의 경우 실시간 이벤트에 가입하면 매우 짧은 지연 시간의 파이프 라인에 Kafka를 사용할 수 있습니다. 데이터를 안정적으로 저장하는 기능은 데이터 전달을 보장해야하는 중요한 데이터 또는 주기적으로 데이터를로드하는 오프라인 시스템과의 통합을 위해 사용하거나 유지 관리를 위해 오랜 기간 동안 중단 될 수 있습니다. 스트림 처리 설비는 도착하는대로 데이터를 변환 할 수있게합니다.

Kafka가 제공하는 보증, API 및 기능에 대한 자세한 내용은 나머지 설명서를 참조하십시오.

This article is licensed under CC BY 4.0 by the author.