티스토리 뷰
Apache Kafka는 아파치 소프트웨어 재단이 스칼라로 개발한 오픈 소스 메시지 브로커 프로젝트로 pub/sub 모델의 메시지 큐를 지원한다.
마이크로서비스 아키텍처에서 메시지 브러커는 Message Backing Service로써 동작하며, 메시지의 처리를 통해 비동기 애플리케이션, DB 동기화, 보상트랜잭션 구현, PUB/SUB 구현 등 다양한 형태의 애플리케이션으로 응용될 수 있다.
Kafka는 대표적인 메시지 브로커로써, RabbitMQ와 많이 비교된다.
일반적으로 RabbitMQ는 대표적인 신뢰성 높은 메시지 브로커로써 각광받는다. 장애 발생 시에도 데이터 복원이 쉽고, 반드시 한번의 전송을 보장한다. 다만 성능면에서 Kafka 보다 떨어진다.
Kafka는 대용량 실시간 처리에 특화되어 있다. 특히 대량의 Batch Job을 일괄 처리하는데 적합하다.
지금부터는 Kafka 아키텍처와 구축 단계, Kafka를 이용한 메시지 브로커 애플리케이션 개발 과정에 대해 살펴보도록 하자.
Queue & Pub/Sub
기존 JMS로 대표되는 Message Backing Service 모델은 Queue, Pub/Sub 구조로 구분된다. 이 중 Kafka는 Pub/Sub 구조를 구현하였으며, 강력한 대용량 처리 성능과 실시간 처리을 위한 스트리밍 데이터를 전송할 수 있도록 구조를 설계하였다. Kafka는 Queue, Pub/Sub의 기본 컨셉을 그대로 구현하면서 각 모델의 단점을 극복하고 동시에 두 가지 방법론을 모두 통합 할 수 있는 유연성을 제공한다.
Queues 방식은 단일 송신자가 단일 수신자에게 데이터를 전송하는 방식이다. 큐에 저장된 메시지는 한명의 수신자에 의해 한번만 읽을 수 있으며, 읽혀진 메시지를 큐에서 제거한다. Queue 방식은 한번 읽고 지워지는 Event-Driven 방식에 적합하다.
Pub/Sub 구조는 여러 송신자가 메시지를 발행하고 여러 수신자가 구독하는 방식이다. 모든 메시지는 Tipic을 구독하는 모든 수신자들에게 전송이 가능하도록 되어있다. 사실 전송이 아닌 수신자가 Polling하는 방식으로 구성되어 있다고 볼 수 있다.
이와 같이 Message Backing Service는 생산자와 소비자 간의 결합도를 낮추지만, 확장성은 한계가 있다. 또한 Pub/Sub 구조의 낮은 결합도는 메시지의 신뢰도를 낮추는 영향을 주기도 한다. 모든 메시지가 모든 수신자에게 전송되도록 하기 위한 메커니즘이 설계되어야 하고, 이는 메시지를 제공하는 Broker에 따라 다른 기능으로 존재하게 된다.
Kafka 컨셉
Kafka는 앞서 살펴본 Queue와 Pub/Sub의 장점을 가지고 만들어졌다. 일반적인 구조는 Pub/Sub을 구현하지만, Queue 구조를 동시에 표현할 수 있다.
먼저 여러 소비자가 Consumer Group에 소속되고 topic을 구독할 때 오직 하나의 소비자만 그룹내에서 토픽의 메시지를 읽는다. 그리고 메시지는 broker 내부 토픽에서 사라지지 않고 보유되는데 이는 일반적인 Queue와 다른점이다.
이와 같은 특징은 Queue와 Pub/Sub의 구조를 동시에 구현할 수 있게 한다. 일반적인 Queue 방식을 구현하고 싶을 경우 하나의 Consumer Group에 모든 소비자가 들어있도록 구성하면 된다. 이렇게 구성하면 메시지는 하나의 소비자에게만 발행되기 때문이다.
즉 다음과 같은 구분점으로 Kafka를 설계할 수 있다.
Kafka Queue
위는 Queue를 설계한 방식이다. Producer는 메시지를 전송하고, 하나의 Consumer Group에 여러 소비자를 구성한다. 이때 소비자는 하나 또는 그 이상이어도 동일한 결과를 갖게된다.
Kafka Topic
위는 Topic을 설계한 방식이다. 일반적인 방식이자, Consumer Group이 두개 이상 존재할 경우 Pub/Sub 형태를 띈다. Kafka의 메시지 유지 방식에 의해 모든 그룹에서 메시지를 가져갈 수 있다.
Kafka 아키텍처
Kafka는 크게 Kafka와 Zookeeper로 구분할 수 있다.
두 모듈은 독립적인 모듈로써 Zookeeper는 분산 애플리케이션의 데이터 관리 용도 여기서는 메시지 큐의 데이터 관리라고 볼 수 있으며, Kafka는 메시지를 TCP로 전송하기 위한 브로커를 제공하는 메시지 브로커이다.
1) Message Broker (Kafka Server)
Kafka 클러스터는 일반적으로 로드밸런싱과 가용성을 유지하기 위해 3 Node Message Broker로 구성한다.
Kafka 브로커는 상태 비 저장이므로 ZooKeeper를 사용하여 클러스터 상태를 유지해야한다.
하나의 Kafka 브로커 인스턴스는 초당 수십만 번의 읽기 및 쓰기를 처리 할 수 있으며 각 브로커는 성능에 영향을주지 않고 메시지를 처리 할 수 있다. Multi Node Kafka 브로커는 ZooKeeper에서 선택하여 Producer 및 Consumer에게 정보를 전달한다.
2) Topic
Kafka에서 메시지를 주고 받기 위해 사용되는 Key이다. 각 Topic에는 대용량 처리를 위해 여러개의 Partition으로 나뉘어 질 수 있다. 이는 메시지를 병렬로 처리하여 성능을 향상시킨다. 이때 각 Partition에는 메시지가 누적되어 쌓이고 메시지의 정보를 offset(현재 위치)과 비교하여 메시지 수진 여부를 결정한다.
이때 Kafka partition과 consumer의 관계를 파악하고 이해해야 한다.
- partition과 consumer는 1:1 매핑됨. 따라서 동일 수로 구성을 권고함.
- partition이 여러개일 경우 순서 보장이 중요함. 따라서 hash key와 같은 순서 보장을 위한 API를 사용하여 동일 파티션에 쌓이도록 하여 동일 consumer가 메시지를 받도록 해야함
- Producer는 Zookeeper를 통해 Multi Node Message Broker의 ID를 전달 받는다.
- 전달 받은 Message Broker로 Message를 전송한다. 이때 Topic / Partition / Message 단위로 나뉘어지며, 병렬 처리를 위해 하나 이상의 Partition으로 나뉘어 진다.
- Consumer는 Offset 정보를 Zookeeper로부터 전달받는다. 누적된 OffSet 만큼 해당 Topic의 Partition으로부터 메시지를 구독한다. 이때 메시지 수신 만큼 OffSet을 감소시킨다.
3) Zookeeper
ZooKeeper는 Kafka 브로커를 관리하고 조정하는데 사용된다. Kafka Message Broker와 1:1로 구성된다. 즉 3 Node Message Broker를 구성할 경우 마찬가지로 3 Node Zookeeper를 구성한다.
ZooKeeper 서비스는 주로 생산자와 소비자에게 Kafka Message Broker의 신규 생성 여부 또는 Kafka Message Broker의 실패를 알리는데 사용된다. 브로커의 존재 또는 실패와 관련하여 Zookeeper가 받은 알림에 따라 생산자와 소비자는 결정을 내리고 다른 브로커와 작업을 조정한다.
4) Producer
생산자는 데이터를 브로커에 Push한다. 새 브로커가 시작되면 모든 생산자는 이를 검색하고 자동으로 해당 새 브로커에 메시지를 보낸다. Kafka 생산자는 브로커의 승인을 기다리지 않고 브로커가 처리할 수 있는 한 빨리 메시지를 보낸다.
5) Consumer
Kafka 브로커는 상태 비 저장이므로 소비자는 파티션 오프셋을 사용하여 소비 된 메시지 수를 유지해야 한다. 소비자가 특정 메시지 오프셋을 확인하면 소비자가 이전의 모든 메시지를 사용했음을 의미한다. 소비자는 사용할 준비가 된 바이트 버퍼를 갖도록 브로커에 비동기 Pool을 발생한다. 소비자는 단순히 오프셋 값을 제공하여 파티션의 어느 지점으로든 되감거나 건너 뛸 수 있다. 소비자 오프셋 값은 ZooKeeper에서 알려준다.
결론
일반적인 Kafka Pub/SUb 아키텍처 이외에 DB to DB로의 동기화 역시 가능하다.
Kafka Connector를 지원하는 데이터베이스는 Kafka를 통해 준 실시간 증분 데이터를 Kafka Topic에 전송하고, 이를 구독하는 DB에서 데이터를 수집할 수 있다.
다음 포스팅에서는 Kafka를 구축하고 실행하는 방법에 대해 알아보자.
'③ 클라우드 > ⓜ MSA' 카테고리의 다른 글
Kafka(Zookeeper) Pub/Sub SpringBoot Application 개발가이드 (0) | 2020.09.30 |
---|---|
Kafka(Zookeeper) 구축 (0) | 2020.09.29 |
Event-Driven Architecture (0) | 2020.05.07 |
[OpenSource API Gateway] Tyk Gateway (4) | 2019.07.13 |
[스프링 마이크로서비스] Spring Boot로 마이크로서비스 구축 (개발자 편) (0) | 2019.03.17 |
- Total
- Today
- Yesterday
- Architecture
- JEUS7
- 오픈스택
- 아키텍처
- git
- aws
- openstack tenant
- apache
- openstack token issue
- Docker
- OpenStack
- Da
- SWA
- 마이크로서비스
- kubernetes
- SA
- nodejs
- node.js
- 쿠버네티스
- 마이크로서비스 아키텍처
- wildfly
- TA
- JBoss
- API Gateway
- aa
- JEUS6
- MSA
- webtob
- k8s
- jeus
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |