카프카, 데이터 플랫폼의 최강자 책을 공부하며 쓴 정리 글 입니다.
카프카(Kafka)는 파이프라인, 스트리밍 분석, 데이터 통합 및 미션 크리티컬 애플리케이션을 위해 설계된 고성능 분산 이벤트 스트리밍 플랫폼이다.
Pub-Sub 모델의 메시지 큐 형태로 동작하며 분산환경에 특화되어 있다.
Fortune 100개 기업 중 80% 이상이 Kafka를 사용한다. 국내에서도 많이 사용하는 추세다.
비즈니스 소셜 네트워크 서비스인 링크드인 (linked-in) 에서 개발했다.
다음은 카프카 개발 전 링크드인의 데이터 처리 시스템이다.
각 애플리케이션과 DB가 end-to-end 로 연결되어 있고(각 파이프라인이 파편화 되어있음), 요구사항이 늘어남에 따라 데이터 시스템 복잡도가 높아지면서 다음과 같은 문제가 발생하게 되었다.
1. 시스템 복잡도 증가 (Complexity)
2. 데이터 파이프라인 관리의 어려움
모든 시스템으로 데이터를 전송할 수 있고, 실시간 처리도 가능하며, 급속도로 성장하는 서비스를 위해 확장이 용이한 시스템을 만들자!
이렇게 모든 이벤트/데이터의 흐름을 중앙에서 관리하는 카프카를 개발하게 되었다.
다음은 카프카를 적용한 후 링크드인의 데이터 처리 시스템이다.
카프카를 적용함으로써 앞서 말했던 문제점들이 어느정도 완화되었다.
카프카는 Pub-Sub 모델의 메세지 큐 형태로 동작한다.
우선 카프카를 이해하기 위해서는 메세지/이벤트 브로커와 메세지 큐에 대한 선제적인 이해가 필요하다.
메시지 큐는 메시지 지향 미들웨어(MOM : Message Oriented Middleware)를 구현한 시스템으로 프로그램(프로세스) 간의 데이터를 교환할 때 사용하는 기술이다.
용어 정리
1. producer: 정보를 제공하는 자
2. consumer: 정보를 제공받아서 사용하려는 자
3. Queue: producer의 데이터를 임시 저장 및 consumer에 제공하는 곳
주목해야할 부분은 Queue 인데, MQ에서 메세지는 Endpoint 간에 직접적으로 통신하지 않고, 중간데 Queue를 통해 중개된다는 점이다.
MQ 장점
1. 비동기: queue라는 임시 저장소가 있기 때문에 나중에 처리 가능
2. 낮은 결합도: 애플리케이션과 분리
3. 확장성: producer or consumer 서비스를 원하는대로 확장할 수 있음
4. 탄력성: consumer 서비스가 다운되더라도 애플리케이션이 중단되는 것은 아니며 메시지는 지속하여 MQ에 남아있다.
5. 보장성: MQ에 들어간다면 결국 모든 메시지가 consumer 서비스에게 전달된다는 보장을 제공한다.
메세지 브로커
publisher가 생산한 메세지를 메세지 큐에 저장하고, 저장된 데이터를 consumer가 가져갈 수 있도록 중간 다리 역할을 해주는 브로커(broker)라고 볼 수 있다.
보통 서로 다른 시스템(혹은 소프트웨어) 사이에서 데이터를 비동기 형태로 처리하기 위해 사용한다. (대규모 엔터프라이즈 환경의 미들웨어로서의 기능)
이러한 구조를 보통 pub/sub 구조라고 하며 대표적으로는 Redis, RabbitMQ 소프트웨어가 있고, GCP의 pubsub, AWS의 SQS 같은 서비스가 있다.
이와 같은 메세지 브로커들은 consumer가 큐에서 데이터를 가져가게 되면 즉시 혹은 짧은 시간 내에 큐에서 데이터가 삭제되는 특징들이 있다.
이벤트 브로커
이벤트 브로커 또한 기본적으로 메세지 브로커의 큐 기능들을 가지고 있어 메세지 브로커의 역할도 할 수 있다.
메세지 브로커와의 가장 큰 차이점은,
이벤트 브로커는 publisher가 생산한 이벤트를 이벤트 처리 후에 바로 삭제하지 않고 저장하여, 이벤트 시점이 저장되어 있어서 consumer가 특정 시점부터 이벤트를 다시 consume 할 수 있는 장점이 있다. (예를 들어 장애가 일어난 시점부터 그 이후의 이벤트를 다시 처리할 수 있음)
또한 대용량 처리에 있어서는 메세지 브로커보다는 더 많은 양의 데이터를 처리할 수 있는 능력이 있다.
이벤트 브로커에는 Kafka, AWS의 kinesis 같은 서비스가 있다.
더 자세히 살펴보자.
Kafka 가 아닌 일반적인 형태의 네트워크 통신은 아래와 같이 구성된다.
각 개체가 직접 연결하며 통신하게 된다. 전송속도가 빠르고 전송 결과를 신속하게 알 수 있는 장점이 있는 반면에, 특정 개체에 장애가 발생한 경우 메세지를 보내는 쪽에서 대기 처리 등을 개별적으로 해주지 않으면 장애가 전파될 수 있다. 또한 참여하는 개체가 많아질 수록 각 개체를 연결해줘야 한다. (=> 시스템이 커질수록 확장성이 좋지 않아진다)
이러한 형태의 단점을 극복하고자 나온게 Pub/Sub 모델이다.
Pub/Sub 모델은 비동기 메세징 전송 방식으로, 발신자의 메세지에는 수신자가 정해져 있지 않은 상태로 publish 한다. 그리고 이를 Subscribe(구독)을 한 수신자만 정해진 메세지(topic)을 받을 수 있다. 이처럼 수신자는 발신자 정보가 없어도 원하는 메세지만 수신할 수 있으며, 이런 구조 덕분에 높은 확장성을 확보할 수 있다.
Pub/Sub 모델의 구체적인 발행/구독 방식은 각 서비스 마다 다른데, 대표적으로 Kafka, Redis, RabbitMQ 등이 존재하며 각 아키텍쳐를 간단히 비교해보도록 하겠다.
Redis 는 데이터베이스, 캐시, 메시지 브로커 및 스트리밍 엔진으로 사용되는 인메모리 데이터 구조 저장소이다.
구성요소
동작
특징
장점
단점
AMQP(Advanced Message Queuing Protocol)?
: 메세지 지향 미들웨어를 위한 개방형 표준 응용 계층 프로토콜
: Client와 Middleware broker간의 메시지를 주고받기 위한 프로토콜
| Kafka | RabbitMQ | Redis Pub/Sub |
---|---|---|---|
라우팅 | 기본기능으로 라우팅에 대해서 지원하지 않는다. Kafka Streams를 활용하여 동적라우팅을 구현할 수 있다. | Direct, Fanout, Topic, Headers의 라우팅 옵션을 제공하여 유연한 라우팅이 가능하다. | - |
프로토콜 | 단순한 메시지 헤더를 지닌TCP 기반 custom 프로토콜을 사용하기 때문에 대체가 어렵다. | AMQP, MQTT, STOMP 등 여러 메세징 플랫폼을 지원한다. | RESP (Redis Serialization Protocol) - TCP 통신 |
우선순위 | 변경 불가능한 시퀀스 큐로, 한 파티션 내에서는 시간 순서를 보장한다. 하지만 여러 파티션이 병렬로 처리할 때는 시간 순서 보장 못함 | priority queue를 지원하여 우선 순위에 따라서 처리가 가능하다. | 우선순위 처리는 커녕 이벤트가 도착할 지 보장도 못함 |
이벤트 저장 in Queue | 이벤트를 삭제하지 않고 디스크에 저장함으로 영속성(durability)이 보장되고, 재처리가 가능하다. | 메세지가 성공적으로 전달되었다고 판단될 경우 메세지가 큐에서 삭제되기 때문에 재처리가 어렵다 | 저장하지 않음. 심지어 channel에 이벤트가 도착했을 때 해당 채널의 subscriber가 존재하지 않으면 이벤트 사라짐 |
장점 |
|
|
|
단점 |
|
|
|
대용량 데이터 처리, 실시간, 고성능, 고가용성이 필요한 경우, 또는 저장된 이벤트를 기반으로 로그를 추적하고 재처리 하는게 필요한 경우 kafka를 쓰자.
복잡한 라우팅을 유연하게 처리해야하고, 정확한 요청-응답이 필요한 Application을 쓸 때 또는 트래픽은 작지만 장시간 실행되고 안정적인 백그라운드 작업이 필요한 경우 RabbitMQ를 쓰자.
이벤트 데이터를 DB에 저장하기 때문에 굳이 미들웨어에 이벤트를 저장할 필요가 없는 경우, consumer에게 굳이 꼭 알람이 도착해야한다는 보장 없이 알람처럼 push 보내는것만 중요하다면 유지보수가 편한 Redis를 사용하자.
Topic
Partition
Offset
Producer
Consumer
Broker
Zookeeper
왜 하나의 topic을 여러개의 partition으로 분산시키는가?
병렬로 처리하기 위해 분산 저장 한다.
카프카의 토픽에 메세지가 쓰여지는 것도 어느정도 시간이 소비된다. 몇 천건의 메세지가 동시에 카프카에 write 되면 병목현상이 발생할 수 있다.
따라서 파티션을 여러개 두어서 분산 저장함으로써 write 동작을 병렬로 처리할 수 있다.
다만, 한번 늘린 파티션은 절대 줄일 수 없기 때문에 운영 중에, 파티션을 늘려야 하는건 충분히 검토 후 실행되어야 한다. (최소한의 파티션으로 운영하고 사용량에 따라 늘리는 것을 권장한다)
파티션을 늘렸을 때 메세지는 Round-Robin 방식으로 쓰여진다. 따라서 하나의 파티션 내에서는 메세지 순서가 보장되지만, 파티션이 여러개일 경우에는 순서가 보장되지 않는다.
컨슈머 그룹은 왜 존재할까?
consumer의 묶음을 consumer group이라고 한다
컨슈머 그룹은 하나의 topic에 대한 책임을 갖고 있다.
즉 어떤 consumer가 down된다면, 파티션 재조정(리밸런싱)을 통해 다른 컨슈머가 해당 파티션의 sub을 맡아서 한다. offset 정보를 그룹간에 공유하고 있기 때문에 down 되기 전 마지막으로 읽었던 메세지 위치부터 시작한다
혹시IT 시스템 아키텍처에서 application view와 physical view에서 REST API, MQ, Kafka, CDC...etc들이 기본적으로 무엇인지, 이러한 개념을 설명해 주실수 있으신지..전혀 감을 못 잡아서 그렇습니다. 개인 과외 형식으로 설명 받고 싶은데 가능하실까요? 시간당 비용은 상호 협의해서 드리겠습니다.