관리 메뉴

피터의 개발이야기

분산 시스템에서 데이터를 전달하는 효율적인 방법은? (feat. Kafka란) 본문

DevOps/kafka

분산 시스템에서 데이터를 전달하는 효율적인 방법은? (feat. Kafka란)

기록하는 백앤드개발자 2024. 3. 18. 12:31
반응형

ㅁ 들어가며

  마이크로서비스를 구축하면서 서비스 간의 통신을 비동기로 원활하게 처리하고, 확장성이 보장되는 아키텍처를 고민하게 된다. 트래픽을 소화하기 위한 아키텍쳐 구성도 중요하지만, 어떻게 분산 시스템에서 데이터를 효율적으로 전달하는 방법을 찾는 것도 중요하다. 그 방법으로 마이크로서비스의 패턴 중 EDA(Event Driven Architecture)패턴 있는데, 서비스간의 데이터 전송의 버퍼 역할을 하는 Redis, RabbitMQ, Kafka라는 대표적인 어플리케이션이 있다. 이들은 크게 메시지 브로커와 이벤트 브로커로 구분되는데, 이번 글에서는 카프카를 설명하며 메시지/ 이벤트 브로커의 차이를 알아야 한다. 

  Kafka는 높은 처리량, 빠른 응답 속도, 안정성 때문에 많은 기업들이 도입하고 있다. 어떠헥 높은 처리량을 갖고, 카프카의 특성이 무엇인지 알아보자.

 

ㅁ EDA의 필요성

  음식점의 주문과정을 예로 들어보자. 소규모 식당에서는 홀서빙과 주방의 조리자가 한명이다. 혼자서 주문을 받고, 주문에 맞게 조리를 한다. 하지만 식당 규모가 커지면, 더 많은 사람들을 고용하여 주문과정을 분업화 하게 된다. 주문을 받고, 주문을 주방에 순서대로 정리하면, 주방에 요리사들은 순차적으로 요리를 하게 된다. 주문이라는 이벤트를 받아, 주문 대기 보드판에 정리를 하고, 주방에서는 주문 대기 보드판을 보고 주문을 하게 된다. 분업화는 이벤트를 비동기화 형태로 받게 되면서, 주문을 받는 홀서핑자와 요리를 하는 조리사를 상황에 따라 인원을 조정할 수 있게 된다. 키워드는 이벤트 - 비동기화 - 확장성이다. 주문을 처리하는 과정은 고속도로 휴게소의 키오스크 시스템에서 볼 수 있다. 

 휴게소 키오스크는 복잡한 주문을 처리하는 방식은 kafka의 구성요소와 흡사하다. 주문자는 키오스크로 주문을 하고 주문내역은 키오스크에 저장되며, 개별 음식점에 전달된다. 음식점은 이 주문을 받아 순차적으로 처리하고, 요리가 완료 이벤트를 입력하면, 키오스크 시스템이 전광판에  표시하여 고객에게 알린다. Event Driven Architecture는 비동기성과 확장성, 확실정을 기반으로 고성능 분산처리를 가능하게 한다.

 

ㅁ 메시지 브로커와 이벤트 브로커 차이는?

https://youtu.be/H_DaPyUOeTo?si=jTQo9lxZNoERa87z

Event Driven Architecture를 위해 RabbitMQ와 Redis, kafka를 사용하는데, 이들의 차이는 메시지 브로커와 이벤트 브로커의 특징으로 구분된다.

  카프카, 레빗엠큐, 레디스 큐의 큰 차이점! 이벤트 브로커와 메시지 브로커에 대해 알아봅시다.이 영상에 차이점을 잘 소개되어 있었다. 이벤트 브로커는 메시지 브로커의 역할을 수행할 수 있지만, 메시지 브로커는 이벤트 브로커의 역할을 수행할 수 없다. 메시지 브로커는 큐를 잠시 보관하고 큐의 작업이 완료되면 삭제되지만, 이벤트는 하나의 메시지 혹 이벤트를 삭제하지 않고 일정시간 보관한다. 

 

ㅁ 메시지 브로커

  메시지 브로커는 대규모 메시지 기반 미들웨어 아키텍처로 사용되었다. 미들웨어는 서비스하는 애플리케이션들을 보다 효율적으로 아키텍처들을 연결하는 요소로 작동하는 소프트웨어를 뜻한다. 메시지 브로커에 있는 큐에 데이터를 보내고 받는 프로듀서와 컨슈머를 통해 메시지를 통신하고 네트워크를 맺는 용도로 사용된다. 이러한 기술을 Message Quere, MQ라고 한다.

 

ㅁ Message Queue, MQ란?

  메시지 큐(Message Queue, MQ)는 메시지 지향 미들웨어를 구현한 시스템으로 프로그램 간의 데이터(Queue)를 교환할 때 사용하는 기술이다. 휴게소 주문 시스템처럼 다량의 주문이 발생 시 키오스크가 빠르게 주문을 수용하여 임시 보관하였다가 음식점의 속도에 맞추어 주문을 순차적으로 처리할 수 있는 버퍼역할을 한다. 여기서 중요한 부분은 주문(Queue) 인데, MQ에서 주문은 Producer와 Consumer가 직접적으로 통신하지 않고, 중간에 저장된다는 점이다. 이러한 구조를 보통 pub/sub 구조라고 하며 대표적으로는 Redis, RabbitMQ가 있다. 이들 메시지 브로커는 큐를 pop해서 가져가면 큐에서 데이터가 없어지게 된다.


MQ의 장점은 다음과 같이 정리할 수 있다.


비동기처리: quere는 브로커에 임시 저장되기 때문에 나중에 처리할 수 있다. 
확장성: 주문을 받는 쪽이든, 식당의 규모든 서비스를 원하는대로 확장이 가능하다.
탄력성: consumer가 다운되더라도 애플리케이션이 중단되지 않고 빠르게 복구 된 후 quere를 지속적으로 처리할 수 있다.
보장성: MQ에 저장돤 quere는 유실없이 consumer에게 확실히 전달을 보장한다. 

  메시지 브로커는 음식 주문처럼 순차적 배치 작업에 적합하다. 주문 접수와 음식 조리라는 연관된 작업에서 비동기 형태로 메시지 브로커가 버퍼의 역할을 하여 작업간의 병목현상을 예방 및 장애에 대해서 지속성을 보장할 수 있다. 이벤트 브로커는 마이르코서비스처럼 다양한 서비스들간의 커뮤니테이션에 적합하다.

 

ㅁ 이벤트 브로커

 ㅇ 이벤트 또는 메시지라고 불리는 레코드를 딱 하나만 보관하고 인덱스를 통해 개별 액세스를 관리한다.

 ㅇ 업무상 필요한 시간동안 이벤트를 보존한다.

 

 이벤트 브로커는 마치 데이터베이스처럼 이벤트를 저장하여 데이터의 일관성을 보장할 수 있게 된다. 이벤트라는 말자체에서 정보의 주체가 정보를 발행하고 수신하는 이를 특정하지 않는다. 

  예를 들어, 배민이나 쿠팡에서 고객의 정보에 변경이 발생하면, 알람서비스, 배송서비스, 결제 서비스에 변경된 정보가 전파되어야 한다. 개인 정보라는 데이터는 데이터의 일관성이 보장되어야 하지만, 성능적 이슈로 인해 데이터를 분산 처리 및  중복하게 되면 데이터의 일관성을 보장하기 어렵게 된다. 이 부분에 대해서는 [MSA] 마이크로서비스 - 분산 트랜잭션 처리를 위한 Saga 패턴에 정리한 적이 있다. 요약하여 설명하면, 고객정보를 담당하여 서비스에서 kafka를 통해 고객정보 변경 이벤트를 Producer하면, 다른 서비스들은 필요에 따라 이 이벤트를 구독하여, 분산된 데이터를 업데이트하게 된다. 이처럼 이벤트 브로터는 다양한 서비스가 생성되고 변경되는 마이크로서비스 생태계에서 다양한 서비스들간의 결합도를 낮추어 원활한 커뮤니케이션을 가능하게 한다.

 

 kafka의 위치는 마이크로서비스의 EDA 패턴 중, 서비스들간의 데이터 일관성 및 서비스 지속성을 보장하기 위한 이벤트 브로커에 속해 있다.

 

ㅁ 카프카(Kafka)란?

https://www.confluent.io/blog/event-streaming-platform-1/

  카프카(Kafka)는 아파치 재단이 스칼라로 개발한 오픈 소스 메시지 브로커이다. 실시간 데이터 피드를 관리하고, 통일되고, 높은 처리량, 낮은 지연시간으로 설계된 고성능 분산 이벤트 스트리밍 플랫폼이다. Pub-Sub 모델의 메시지 큐 형태로 동작하며 분산환경에 특화되어 있다. Kafka는 링크드인에서 처음 개발되어 현재는 아파치 재단에서 관리하는 오픈소스이다. 다음은 카프카를 적용한 후 링크드인의 데이터 처리 시스템이다.

 

ㅁ 카프카의 구성요소

  주문자(주문 생산), 키오스크(주문 브로커), 식당(주문 처리)이 휴게소 주문처리의 핵심 구성요소이듯, Kafka 생산자(Producer), 브로커(Broker), 소비자(Consumer)가 있다.

 

 Producer:  Kafka로 메시지를 보내는 클라이언트

 Brokers: Kafka가 설치된 서버 또는 노드로 메시지를 임시 저장소, kafka 자체

 Consumer: Kafka에서 메시지를 꺼내어 작업을 수행하는 클라이언트

 

 Kafka Pub-Sub 모델의 메시지 큐 형태로 동작하며 분산환경에 특화되어 있다. Kafka는 메시지 브로커의 역할을 수행할 수 있지만, 근본적으로 구조화된 이벤트 브로커이다. 카프카는 전통적인 메시지 큐 시스템인 RabbitMQ, ActiveMQ 와 같은 메시징 시스템과 비교할 때 처리량과 처리 속도, 가용성과 확장성이 월등히 앞서 있다. 데이터 생산자는 레코드 스트림을 전송하며, 소비자 수에 관계없이 밀리초의 시간 안으로 업데이트를 지속적으로 스트리밍할 수 있다.

 

ㅁ Kafka Cluster 구성

분산 시스템을 위한 Kafka cluster 구조

 Kafka는 고가용성과 분산 시스템을 위해 클러스터로 구성된다. kafka를 다중 브로커(노드)의 형태로 구성하면 장애에 따른 지속성과 성능 향상을 위한 확장성을 가지게 된다. 일반적으로 3개 이상의 Kafka로 Broker를 생성하며, 일부 장애가 발생하더라도, Fail over되어 새로운 리더가 선택되고, 지속적인 서비스는 운용된다. 초기 소규모로 운영을 하였지만, 트래픽의 증가로 인해 kafka의 노드를 쉽게 증설할 수 있는 장점이 있다. 


ㅇ Topic: 메시지 피드들을 토픽으로 구분하고, 각 토픽의 이름은 Kafka 내에서 고유하다.
ㅇ Partition: 병렬 처리 및 고성능을 얻기 위해 하나의 Topic을 여러 개로 분산하였다.
ㅇ message or record: Producer가 브로커의 기본 데이터 조각을 말한다.

ㅇ Offset: Partition에 있는 데이터의 고유 번호를 뜻하며, consumer가 offset을 수정하여 장애 시 재시작점부터 다시 메시지를 읽을 수 있다.

ㅇ Zookeeper: 

 - 분산 애플리케이션 관리를 위한 코디네이션 시스템이다.
 - 분산 메시지큐의 메타 정보를 중앙에서 관리하는 역할을 한다.

 

ㅁ 리플리케이션

 리플리케이션(replication)이란 각 메시지들을 여러 개로 복제하여 Kafka Cluster의 Broker들에 분산하는 동작이다. Cluster의 분산 작업은 일부 브로커가 장애가 발생하여도 안정성을 유지할 수 있다.

 

$ docker exec -it kafka101 \
kafka-topics \
--create \
--partitions 3 \
--replication-factor 1 \
--topic demo-topic \
--bootstrap-server kafka101:29092

[kafka] kafka 모니터링 docker 환경 세팅에서 kafka-topics라는 토픽을 생성했던 구문이다. 

ㅇ partitions 3개이고, 원본을 포함하여 1개의 replication을 설정하였다.

ㅇ replication-factor의 값이 높아지면 안정성은 높아지지만, 복제에 따른 오버헤드가 발생하여 disk IO에 병목이 발생할 수 있다.

ㅇ 메시지의 유실 허용 여부에 따라 개발 및 테스트는 1, 로그성 운영데이터는 2, 중요 데이터의 경우 3으로 설정하는 것이 좋다.

ㅇ 4이상으로 팩터 수를 높일 경우 디스크 공간이 많이 사용되고, 그만큼 복제 IO에 따른 병목이 발생할 수 있다.

 

ㅁ 컨슈머 그룹

  kafka consumer는 Consumer Group에 속하게 된다. 하나의 토픽에 여러 Consumer가붙어서 같은 메시지를 가져갈 수 있다. partition에 대한 별도의 offset을 관리하고, group에 consumer의 수가 변경되면, rebalancing을 하여 group 내의 partition에 consumer을 할당하게 된다. 이를 통해 consumer에 대한 유연성을 얻게 된다. 

 병렬처리를 위해 partition을 늘리고, consumer도 늘리면 처리성능을 향상할 수 있고, consumer중에 장애가 발생하여도 rebalancing을 통해 처리 지연된 partition을 조정할 수 있다.

 

ㅁ 마무리

서비스가 다양화되면서 시스템 복잡도는 증가하기 마련이다. 분산된 시스템에서 일관된 정보를 전달하기 위한 효율적인 방법으로 kafka는 서비스간의 결합도는 낮추고 비동기처리가 가능하도록 메시지 저장 및 네트워크의 역할을 수행할 수 있었다. 복잡한 시스템 구조에 따라 능동적을 topic을 정하여 Producer와 Consumer를 연결하고 이들 간의 결합도도 낮추어 개별 장애로부터 지속적인 서비스를 가능하게 하였다. kafka의 장점을 정리하면 다음과 같다.

 ㅇ 대규모 트패픽 처리 및 비동기 분산 처리

 ㅇ 클러스터 구성으로 Replication과 Fail Over로 지속적 서비스가 가능하고, Scale out으로 서비스 유연성 제공한다.

 ㅇ Partition으로 분산 병렬처리를 통해 100Kb/sec 정도의 빠른 속도를 제공한다.

 ㅇ 디스크에 메시지를 저장하여 데이터의 영속성을 보장하며, 일관된 데이터의 정합성을 보장할 수 있다.

 

 

ㅁ 함께 보면 좋은 사이트

 [Apache Kafka] 카프카란 무엇인가?

 카프카, 레빗엠큐, 레디스 큐의 큰 차이점! 이벤트 브로커와 메시지 브로커에 대해 알아봅시다.

[Kafka] 카프카 기본 개념 구조 이해하기

https://www.youtube.com/watch?v=uk5fRLUsBfk

 

 

반응형
Comments