Kafka 정리
web/kafka

Kafka 정리

반응형

카프카는 분산형 스트리밍 플랫폼으로써 다음으로 정의할 수 있다.

  • 메시지 큐와 유사하게 스트림을 publish하고 subscribe 하는 방식이다.
  • fault-tolerant 지속 방식으로 레코드들의 스트림들을 저장한다.


용도

  • 시스템이나 어플리케이션에서 발생한 실시간 스트리밍 데이터를 안정적으로 데이터 파이라인 구축할 때
  • 데이터 스트림을 전송하거나 처리해야할 때 사용


구성

  • 하나이상에 서버에 여러 cluster로 구성되어 있다.
  • topic이라는 카테고리로 레코드 스트림들을 저장한다.
  • 각각의 레코드들은 key, value, timestamp로 구성되어 있다.


핵심 API

Producer API

  • 하나 또는 그 이상의 카프카 topic을 데이터 스트림에 발행할 수 있도록 해주는 API

Consumer API

  • 어플리케이션이 하나 또는 하나이상의 topic을 구독할 수 있게 해주고 그것으로 부터 생산된 스트림을 처리하게 해준다.

Streams API

  • 어플리케이션을 효과적으로 input stream에서 output stream으로 데이터가 잘 전송될 수 있도록 하나 또는 하나 이상의 topic으로 부터 들어온 input stream을 소비하고 하나 또는 하나 이상의 topic을 생산하도록 하는 stream processor로서 행동하게 해준다.

Connector API

  • 어플리케이션 또는 데이터 시스템에서 존재하는 kafka topic에 재사용 가능한 producer 또는 consumer로 구성되고 동작할 수 있도록 제공해주는 API


Topics and Logs
kafka에서는 제공하는 핵심 추상화인 Topic에 대해 정리해보자.

topic은 category 또는 publised된 레코드의 feed name이다. 카프카에서 topic은 항상 멀티 subscriber를 가지고 있고 데이터를 구독하는 consumer를 0 또는 1 그리고 더 많이 소유할 수 있다.

각각의 토픽에 대해 kafka 클러스터는 다음과 같은 파티션 로그를 유지한다.

각각의 파티션은 연속적으로 추가되는 정렬된 시퀀스화되어 있는 커밋로그이다. 파티션 안에서 recode는 파티션 내에서 고유하게 식별이 가능하도록 offset이라는 연속적인 id를 가지고 있다.

kafka에서 크러스터는 소비가 되기전까지 데이터가 보관되고 만약 데이터 보관 정책에 따라서 몇일까지만 보관하도록 지정할 수 있다. 소비가된 레코드는 공간에서 제거된다.



또한 offset을 기준으로 사용자가 데이터를 접근하여 읽을 수 있다.


Producers
producers는 topic을 선택하여 데이터를 publish할 수 있다. producers는 topic내에서 어떤 파티션에 레코드를 publish 할건지 선택해야한다.
이 선택 방식은 load balance를 맞추기 위해서 라운드 로빈 방식으로 수행되거나 일부 의미적 파티션 함수에 따라 수행될 수도 있다.(파티셔닝으로 선택되기도 한다.)

Consumers
Consumers는 Consumers group 이름을 가지고있다. topic이 published된 각각의 레코드는 각각의 구독 consuber group내에 하나의 컨슈머에게 전달된다. Consumer 인스턴스는 각각의 프로세서로 구성되거나 각각의 서버에서 구성되어 있을 수 있다.

만약의 모든 consumer가 모두 같은 consumer group에 있으면 레코드는 효과적으로 각각의 consumer들에게 적절하게 부하분산 처리가 될 것이다.

만약 모든 consumer가 서로 다른 consumer 그룹에 포함되는 각 레코드가 모든 consumer processor에 브로드 캐스팅을 하게 된다. (즉 다시 말하자면 구독하고자 하는 레코드가 있는 consumer는 하나의 group으로 지정하는게 좋다.)



위에 그림은 2개의 Consumer group에서 4개의 파티션으로 구성된 kafka cluster를 구독하고 있다. A Consumer 그룹은 2개 B는 4개의 Consumer를 보유하고 있다.

각각의 그룹은 다수의 Consumer로 구성되어 있다. 이는 하나의 consumer가 죽으면 각 파티션은 다른 consumer 인스턴스에 값을 전달한다. 


Messaging System으로써 Kafka

일반적으로 이런 메시지 방식을 지원하는 rabbitMQ와 같음 메시지 큐가 존재한다. 하지만 이런 전통적인 Message Queue와 kafka가 무엇이 다른지 알아보자.

일반적인 메시징은 Queuing와 publish-subscribe 두 개의 모델을 가지고 있다. Queue에서는 소비자의 pool은 서버로 부터 읽어들이고 각각의 레코드는 그 둘 중 하나로 저장된다. publish-subscribe 모델에서 레코드는 모든 고객에게 brodecast된다. 이 두 가지 모델은 각각 강점과 약점이 존재한다. Queuing의 강점은 여러 consumer 인스턴스에서 데이터 처리를 나눌 수 있으므로 나눌 수 있다. 하지만 Queing은 Multi subscribe 방식이 아니기 때문에 하나의 프로세스에서 읽으면 다른 프로세스는 읽을 수 없게 데이터가 사라진다. publish-subscribe는 다중 프로세스에게 브로드캐스트하는 장점이 있지만 모든 메시지가 모든 구독자에게 전달 되기 때문에 scaling을 조절할 방법이 없다. (어차피 모든 구독자에게 전달되기 때문에)

반면에 kafka에 있는 consumer group 개념은 두 가지 개념을 생성한다. queue와 비슷하게 consumer group은 그룹내에 각 consumer들에게 처리를 분산할 수 있다. 그래서 별도의 consumer를 지정할 필요없이 자동으로 값을 분산할 수 있다. publish-subscribe 방식과 비슷하게 모든 그룹에게 kafka는 메시지를 브로드 캐스트 할 수 있다.

그리고 일반적인 Message system에서 queue는 서버에서 순서대로 레코드를 보유하고 있으며 다중 consumer가 소비하려할 경우 서버에 저장된 순서대로 레코드를 전달한다. 하지만 서버가 순서대로 보내도 다중 Consumer에게 비동기로 값을 전달하기 때문에 결국 순서 보장이 되지 않는다. (이를 Consumer를 하나로 지정하여 문제를 해결할 수 있지만 병렬처리가 안되는 단점 발생)

하지만 카프카는 파티션 개념을 가짐으로써 consumer 프로세스 풀에 대한 순서를 보장하고 부하분산도 보장한다. 방식은 Consumer 그룹 내에서 topic내에 특정 파티션을 하나의 Consumer에게 특정하여 subscribe하게 전달한다.. 그러면 Consumer가 해당 파티션의 유일한 독자가 되기 때문에 문제에 소지가 없어지고 순서대로 순서가 보장된다. 파티션이 많아지면 많은 Consumer를 하나의 그룹으로 지정함으로써 부하분산을 처리한다. 하지만 Consumer group은 파티션보다 더 많은 수의 consumer를 보유 할 수 없다.

-> 정리하자면 기존의 메시지 큐는 하나의 큐에서 멀티 consumer가 있을 경우에 서로 데이터를 순서보장없이 가져가서 처리하기 때문에 순서가 보장되어야 하는 동작에 문제가 생긴다. 하지만 카프카에서는 소비자 그룹을 지정하고 각 그룹에서 특정 소비자는 특정 파티션의 내용만 받아서 처리하기 때문에 순서가 보장된다. 결국에 핵심은 kafka에는 consumer group이라는 개념이 도입되어서 더 안정적인 부하분산과 데이터처리가 가능해진 것 같다. 그리고 하나더 브로드 캐스팅 할 때도 모든 데이터가 다 consumer들에게 전달되는 일반 메시지 큐와 달리 브로드캐스팅시 각 그룹내에 consumer에게 값을 나눠서 전달하고 하나로 처리하는 kafka가 더 좋다는 이야기인 것 같다.


다음 시간에는 카프카를 spring reactive를 사용해서 한번 메시지를 전달하고 받아보고 처리하는 동작을 만들어보자.

참고 : https://kafka.apache.org/intro


반응형