Apache Kafka 개념 소개
Kafka란?
Kafka는 분산 메시징 시스템이라고 불리며, 메시지(데이터)의 송신자와 수신자의 중개를 하는 시스템이다. 대용량, 대규모 메시지 데이터를 빠르게 처리하도록 개발된 송신자와 수신자의 중개를 하는 메시지 플랫폼이며, Pub-Sub 모델의 메시지 큐이다. 그리고, 분산 환경에 특화되는 특징을 가지고 있다.
“빅데이터"나 “IOT"가 트렌드가 되어 가면서 링크드인(LinkedIn)에서 서비스의 확장으로 인한 여러 메시지 큐 시스템을 관리하기 어려워 사내 프로젝트로 개발이 시작되었고, 2011년 초 아파치 공식 오픈소스로 세상에 공개되었다. 현재는 공개 소프트웨어(OSS)로 개발되어 개발 커뮤니티에는 미국의 Confluent, LinkedIn, Uber, 중국의 Alibaba 등 많은 곳에서 사용되고 있다.
메시징 시스템이란?
메시징 시스템은 의미가 넓고 “송신자로부터 데이터를 일단 수신하고 수신자에게 적절한 타이밍에 데이터를 보내는 시스템"을 말한다.
예를 들면, 웹 사이트의 로그 수집을 한다고 한다면, 여러 웹 서버에서 로그를 중계 서버에 보내고, 중계 서버가 배치 처리로 데이타베이스 등에 로그를 보내는 등의 구성을 생각할 수 있는데 이것도 메시징 시스템이라고 할 수 있다. 이것만으로는 부족하기에 Pub-Sub 메시징 모델을 예로 들어 그림으로 설명해 보도록 하겠다.
Pub-Sub 메시징 모델에서는 Publisher(송신자)가 Broker에게 메시지를 보내고, Subscriber(수신자)는 Broker로부터 메시지를 받는다. Publisher가 Subscriber에 직접 메시지를 보내는 대신 항상 Broker를 사이에 넣는다. Publisher에서 보낸 메시지는 Broker의 Topic에 저장된다. Topic은 여러개가 있어서 메세지의 내용에 따라, 어느 Topic에 저장되어야 하는지를 Publisher로부터 지정한다. 한편, 각 Subscriber는 특정 Topic에서만 선택적으로 메시지를 받는다. 이러한 구성으로 되는 이유는 우리의 일상 생활을 생각해 보면 알 수 있다. 세상의 서비스 및 제품은(어느 정도 타겟은 정해져 있지만) 기본적으로는 누구나 이용할 수 있는 형태로 만들어지고 있지만, 사용자 측은 당연히 모든 것을 이용하는 것은 아니고, 자신의 흥미 및 관심에 따라 선택하게 된다. Pub-Sub 메시징 모델도 이와 같다.
왜 브로커가 중재를 하는가?
Publisher에서 Subscriber로 데이터를 보내는 것이 목적이라면 언뜻 보면 Broker가 필요 없을거 같지만, Broker의 존재는 다음 두 가지 관점에서 매우 중요하다.
1. Publisher/Subscriber는 Broker만 통신하면 좋다
만약 Broker가 없었다고 하면, Publisher는 각각의 Subscriber를 모두 파악하고 있어야 한다. 반대로 Subscriber는 데이터를 보내는 각각의 Publisher를 모두 파악해야 한다. Broker가 있으므로써 Publisher는 Subscriber를 의식하지 않고, 어쨌든 Broker에게만 메시지를 보내면 되는 거다.
2. 메시징 모델 변경이 용이하다.
Broker만 통신을 하게 되면, Publisher/Subscriber의 추가나 삭제를 하기가 쉽게 된다. Broker가 없다면, 추가/삭제를 할 때에 모든 Publisher/Subscriber를 고려해야 하기 때문에 작업이 어려워 진다.
Publish/Subscribe 는?
메시징 시스템 시스템마다 Publish/Subscribe 용어를 각각 다르게 사용한다. 결국에는 대체로 동일한 의미로 아래와 같이 정리 된다.
- 메시지 생성(송신)
- Publisher
- Producer : Kafka에서는 이 용어 사용
- Writer
- 메시지 소비(수신)
- Subscriber
- Consumer : Kafka에서는 이 용어 사용
- Reader
메시지 큐잉 시스템과 무엇이 다른가?
Publish/Subscribe 메시징 시스템은 메시지 소비를 여러 번 가능(Producer는 메시지를 한 번 전송해야 함)하다. 그에 비해, 메시지 큐잉 시스템는 메시지 소비를 1회만(Producer는 메시지를 소비하는 횟수만 송신할 필요가 있다)만 가능하다는 것이 큰 차이이다.
Kafka의 특징
카프카의 특징에 대해서 알아보겠다.
1. 대량의 데이터를 고속으로 처리할 수 있다.
앞에서 “빅데이터”, “IOT"와 같은 트렌드에서 Kafka가 개발되었다고 말했지만, 이러한 배경을 고려하면 대량의 데이터를 고속으로 처리할 수 있는 것은 매우 중요하다. 자세한 설명은 다시 하겠지만, Kafka는 Pub-Sub 메시징 모델과 약간 다른 구성을 되어 있고, 여러 Broker 구성으로 되어 있어 스케일 아웃을 하기 쉽다. 스케일 아웃의 용이성은 빠른 처리 향상에 직결된다.
2. 자유로운 타이밍에서의 데이터 이용이 가능하다.
앞에서 언급한 “고속"이라고 하는 것은 리얼타임 처리를 말하지만, 반드시 리얼타임 처리 뿐만이 아니다. Kafka에 접속되는 Consumer(Pub-Sub 메시징 모델의 Subscriber에 해당)는 다양하고, 일괄 처리를 하는 경우도 있다. 또, 데이터도 곧바로 사용하는 것은 아니고, Broker내에서 장기간에 걸쳐 보존이 필요한 경우가 있지만, Kafka에서는 데이터를 메모리상 뿐만이 아니라 디스크에 기입하는 것으로 영속적인 보존을 가능하게 한다. 이렇게 함으로써 데이터를 자유롭게 사용할 수 있다.
3. 고속성을 유지하면서 데이터의 송신 보증이 가능하다.
데이터의 전달 보증이라고 하면, 1건씩 데이터에 대한 트랜잭션 처리가 쉬울 수 있다고 생각할 수도 있지만, 이는 실행하면서 고속으로 데이터를 처리한다는 것은 난이도가 매우 높다. 그리고 당연히 도중에 데이터가 손실되는 것도 피해야 한다. 가장 엄격한 데이터 전달 보증은 “1건의 데이터를 확실히 1회씩 보내기”(Exactly at once)이지만, Kafka에서는 “(중복이어도 상관 없기 때문에) 적어도 1회는 확실하게 데이터를 송신한다”(At least once)를 실현함으로써 고속성과 데이터 전달 보증의 균형을 맞추고 있다.
4. 데이터를 송수신하기 위한 API가 충실하다
Kafka에 접속되는 Producer/Consumer(Producer는 Pub-Sub 메시징 모델의 Publisher에 해당)는 하나만 있는 것이 아니고, 다른 시스템에 속하고 있는 경우도 많다. 이러한 경우에는 Publisher/Subscriber와 Kafka 사이에 접속용 API가 중요해 진다. 접속 API의 역할을 하는 것으로서 “Kafka Connect”(및 Kafka Connect 접속하는 Connector 플러그인)가 제공되고 있다. API를 사용자 측에서 개발하는 것은 매우 번거롭기 때문에 풍부한 API를 제공하면 개발 효율성을 높이는 데 도움이 된다.
그밖에 아래와 같은 특징을 가지고 있다.
- Producer와 Consumer의 분리
- 카프카는 메시징 전송 방식 중 메시지를 보내는 역할과 받는 역할이 완벽하게 분리된 Pub-Sub 방식을 적용한다.
- 각자의 역할이 완벽하게 분리되면서, 어느 한쪽 시스템에서 문제가 발생하더라도 연쇄작용이 발생할 확률은 매우 낮다.
- 멀티 프로듀서, 멀티 컨슈머
- 카프카는 하나의 토픽에 여러 프로듀서 또는 컨슈머들이 접근 가능한 구조로 되어있다.
- 데이터 분석 및 처리 프로세스에서 하나의 데이터를 다양한 용도로 사용하는 요구가 많아지기 시작했고, 멀티 기능 덕분에 이러한 요구를 손쉽게 충족할 수 있다.
- 디스크에 메시지 저장
- 디스크에 메시지를 저장하고 유지한다.
- 컨슈머가 메시지를 읽어가더라도 보관 주기 동안 디스크에 메시지를 저장해둔다.
- 확장성
- 카프카는 확장이 매우 용이하도록 설계되어 있다. 하나의 카프카 클러스터는 3대의 브로커로 시작해 수집 대의 브로커로 확장 가능하다.
- 확장 작업은 카프카 서비스의 중단 없이 온라인 상태에서 작업이 가능하다.
- 높은 성능
- 고성능을 유지하기 위해 카프카는 내부적으로 분산 처리, 배치 처리 등 다양한 기법을 사용하고 있다.
Kafka 구성 요소
여기까지 Kafka의 큰 프레임의 특징을 설명하였고, 이제는 Kafka의 구체적인 구성에 대해 살펴 보겠다. Kafka의 구성은 다음과 같은 그림으로 나타낼 수 있다. 그림의 용어에 대해 순차적으로 설명하겠다
Message
구성도 그림에는 등장하지 않지만 개별 데이터를 Message라고 한다. 혹은 Event이라고도 한다. message는 key와 value로 구성되어 있으며, Message는 Kafka에서 Producer와 Consumer가 데이터를 주고 받는 단위이다.
Producer
Producer는 Kafka에 이벤트를 게시(Post)하는 클라이언트 어플리케이션을 의미한다. Pub-Sub 메시징 모델의 Publisher에 해당하고, Broker에 Message를 송신한다. 실제로 Kafka와 연동하려면 API를 이용하여 통신용 애플리케이션을 만들거나 producer 기능을 가진 공개 소프트웨어(OSS)를 사용해야 한다.
Consumer
Consumer는 이런한 Topic을 구독하고 이로부터 얻어낸 이벤트를 처리하는 클라이언트 어플리케이션이다. Pub-Sub 메시징 모델의 subscriber에 해당하고, Broker로부터 message의 수신을 한다. Kafka의 송신은 Pull 형태이므로, Consumer로부터 Broker에게 요구를 송신하는 것으로 Broker로부터 Message가 도착한다. 특징에서도 언급했지만, Kafka에서는 데이터를 디스크에 기입해 영구적으로 보존하고 있기 때문에, Consumer는 임의의 타이밍부터 리퀘스트를 보낼 수가 있다. Producer와 마찬가지로 Kafka와 연동하려면 API를 이용하여 통신용 애플리케이션을 만들거나 Consumer 기능을 가진 공개 소프트웨어(OSS)를 사용해야 한다.
Broker
Producer/Consumer로부터의 요구에 따라 Message의 수신/전송을 실행한다. 고속 처리를 가능하게 하기 위해서, 그림과 같이 복수의 구성을 취하는 것이 일반적이다. 받은 메시지를 디스크에 쓰는 작업도 수행한다.
Topic
Broker내의 Message의 보관 영역을 의미하고, 같은 분류의 Message는 같은 Topic에 보존되는 구조이다. 각 Producer는 특정 topic에 대해 메시지를 보내고, 각 Consumer는 특정 Topic에서 Message를 가져와 처리한다. Topic은 파일 시스템의 폴더와 유사하며, 이벤트는 폴더안에 파일과 유사하다. Topic에 저장된 Message는 필요할 때, 다시 읽을 수 있다.
Partition
Topic는 여러 Broker에 분산되어 저장되며, 이렇게 분석된 Topic을 Partition이라고 한다. 그림과 같이 Topic 안에 담긴 Message는 Partition이라는 단위로 나뉘어져 있다. 이는 나중에 설명하게 될 컨슈머 그룹과 관련하여 중요하다. 어떤 Message가 Partition에 저장될지는 Message의 key에 의해 정해지며, 같은 키를 가지는 Message는 항상 같은 Partition에 저장된다. Kafka는 Topic의 Partion에 지정된 Consumer가 항상 정확히 동일한 순서로 Partition의 이벤트를 읽을 것을 보장한다.
Consumer group
여러 Consumer가 조합되어 Consumer Group을 형성한다. 같은 Consumer group에 속하는 Consumer는 같은 Topic으로부터 Message를 수신한다. 반면 소스 파티션은 각 Consumer마다 다르다. 이런 방식으로 Kafka는 메시지의 분산 처리를 가능하게 한다. 여기가 앞서 설명한 Pub-Sub 메시징 모델과의 차이점으로 Pub-Sub 메시징 모델에서 “각 Subscriber는 특정 Topic으로부터 메시지를 수신한다"라고 되어 있었지만, 특정 Topic에서 메시지를 받는 Subscriber는 모두 같은 메시지를 받는다.
ZooKeeper
Topic, Partition 등 Message의 분산 처리에 관련된 정보를 보존/관리하기 위한 도구이다. 그림에서는 하나 밖에 없지만, 여러개를 이용하는 경우가 일반적이다.
Kafka cluster
ZooKeeper와 Broker로 구성된 Message 중계 시스템을 Kafka cluster라고 한다.
Kafka 주요 개념
- Producer와 Consumer의 분리
- Producer와 Consumer는 완전 별개로 동작한다.
- Producer는 Broker의 Topic에 메시지를 게시하기만 한다.
- Consumer는 Broker의 특정 Topic에서 메세지를 가져와 처리하기만 한다.
- Producer와 Consumer는 완전 별개로 동작한다.
- Push와 Pull 모델
- 소비된 메세지 추적(Commit과 Offset)
- Consumer Group
- 메시지(이벤트) 전달 컨셉