Message Broker

...·2024년 7월 2일

system design

목록 보기
3/3

일반적으로 네트워크로 연결된 컴퓨터들 사이의 통신은 한 쪽이 다른 쪽에게 직접, 그리고 동기적으로 데이터를 전달하는 형식이다.
만약 클라이언트가 서버에게 데이터를 전달하는 시점에 서버가 데이터를 받을 수 없는 상황이라면 해당 데이터는 전달되지 못하고 유실될 수 있다.

또한, MSA에서는 한 쪽이 여러 대상에게 데이터를 보내야 하는 경우가 많다. 이때, 받는 쪽마다 필요로 하는 데이터가 다르다면 그에 맞춰 구현이 복잡해질 수 있고, 받는 쪽이 추가되거나 작업이 변경되면 보내는 쪽도 그에 맞춰 대응해야 할 수 있다.
추가적으로 보내는 쪽이 많아진다면 구조가 더욱 복잡해진다.

Message Broker

Message Broker 방식은 보내는 쪽과 받는 쪽을 서로로부터 자유롭게 만들어준다.

해당 시스템에서 보내는 쪽은 producer, 받는 쪽은 consumer라고 불린다. 그리고 Message Broker는 이들 사이를 중개해주는 역할을 맡는다.

producer는 전달한 데이터가 있으면 message broker에 보낸다. 이때 producer는 consumer가 이 데이터를 받았는지 신경쓸 필요가 없다.
동시에 consumer는 가능할 때마다 message broker에서 필요한 데이터를 찾아간다. 데이터는 지정된 시점까지 보관하기 때문에 consumer가 바로 찾아가지 않더라도 데이터가 유실될 걱정을 하지 않아도 된다.

producer와 consumer의 수가 많아지더라도 모든 전달이 message broker를 통해 이뤄지기 때문에 설계가 수월해진다.

이를 바탕으로 message broker를 활용한 설계는 보내는 쪽과 받는 쪽의 소통을 유연하게 만들고, 데이터의 유실을 방지하며, 수평적 확장이 용이하도록 만들어준다.
때문에 빠른 응답보다는 안전한 메시지 전달, 노드 간의 독립성, 확장성을 필요로 하는 서비스들에 활용된다.

RabbitMQ와 Kafka

Message Broker는 특징에 따라 크게 2개의 종류로 나뉘고, 각각의 대표격으로 RabbitMQ와 Kafka가 존재한다.

message broker는 일반적으로 producer와 consumer와는 다른 서버에서 구동된다.
또한 producer와 consumer에도 RabbitMQ 또는 Kafka의 클라이언트가 설치되어서 가운데의 broker 서버와 통신하게 된다.
RabbitMQ의 경우 producer와 message broker, message broker와 consumer 사이의 통신으로는 AMQP라는 프로토콜을 사용한다.
Kafka의 경우는 TCP를 기반으로 한 자체적인 프로토콜을 사용한다.

메시지를 다루는 차이

RabbitMQ는 메시지들을 queue 형태로, Kafka는 이들을 로그 형태로 저장한다.

RabbitMQ

producer가 보낸 순서대로 메시지들을 queue 형태로 저장한 다음 consumer가 이들을 요청하는대로 이들을 queue에서 빼내어 전송하게 된다.

즉 RabbitMQ에서는 broker는 producer로부터 메시지를 받아와 저장하는 일 뿐 아니라, consumer가 메시지를 받아갈 때마다 이를 queue에서 제거하는 일도 담당하게 된다. 이때 consumer는 다른 것을 고려할 필요 없이 broker에게 메시지를 요청하기만 하면 된다. (smart broker, dumb consumer)

RabbitMQ에서 메시지들은 주로 메모리에 저장되기 때문에 처리가 빠르지만 유실의 위험성도 있다.

RabbitMq에서는 consumer가 받아간 메시지가 삭제되는 것까지 다른 노드들에 실시간으로 적용되어야 하기 때문에 클러스터링이 까다롭다.

RabbitMQ는 시간이 걸리는 작업을 여러 워커들이 분산 처리하는 작업 큐를 지원한다. consumer의 위치에 있는 워커들이 작업을 하나씩 가져간 다음, 작업이 완료되는대로 broker에 신호를 보내 해당 메시지가 제거되도록 할 수 있다. 때문에 여러 이미지 파일을 업로드 받아 그래픽 처리를 해 주는 서비스에 유용하게 사용될 수 있다.

또한 RabbitMQ는 메시지를 특정 카테고리로 전달하는 방식이 보다 다양하다.
kafka에서는 메시지들은 topic이라는 그룹으로, RabbitMQ에서는 queue라는 그룹으로 묶인다.
RabbitMQ는 조건에 따라 각 메시지를 특정 큐로 보내기 위한 다양한 방식들을 제공하기 때문에 복잡한 메시지 라우팅이 필요한 서비스의 경우 kafka보다 유리하다.

RabbitMQ는 consumer가 메시지를 성공적으로 처리했는지 여부를 broker에게 전달함으로써 신뢰성 있는 전달을 보장할 수 있다.
이 방식은 broker가 메시지의 처리 여부를 확인할 수 있기 때문에 트랜잭션과 같이 안정적인 처리가 필요한 작업에 적합하다.

메시지의 우선순위를 두는 기능과, 메시지가 일정 시간 후 자동 만료되도록 설정하는 기능 또한 RabbitMQ에서는 기본적으로 제공된다.

Kafka

Kafka는 메시지들을 디스크에 로그 형태로 저장한다. 이 메시지들은 consumer가 받아간다고 해서 로그에서 지워지지 않는다.

로그 안의 메시지들은 배열 안의 요소들이 인덱스를 갖는 것처럼 각각의 오프셋을 갖는데, consumer들은 각자 자기가 받아간 마지막 오프셋을 기억함으로써 중복 없이 다음 메시지를 요청하게 된다. 때문에 이 방식에서는 consumer를 구현하는 일이 RabbitMQ에 비해 까다로워질 수 있다. (dumb broker, smart consumer)
하지만 broker의 경우에는 consumer의 요청에 따른 작업이 필요 없기 때문에 부담이 줄어들고, 메시지들을 디스크에 저장하기 때문에 유실로부터도 안전하다.
필요에 따라 consumer가 특정 메시지를 여러 번 받아갈 수 있고, 장애가 발생했을 시 문제가 있었던 부분부터 다시 받아갈 수도 있다.

디스크는 메모리보다 속도가 느리지만, kafka와 같이 순차적으로 저장하면 성능을 극대화할 수 있다.
또한 kafka는 기본적으로 batch 기능을 제공하기 때문에 메시지들을 여럿씩 받아오거나 보내주는 일도 RabbitMQ에 비해 빠르고 간편하게 처리된다.

무엇보다, Kafka의 방식은 broker를 여러 서버에 분산하여 운영하는 클러스터링에 보다 유리하다.
consumer가 offset을 사용해서 메시지들에 접근하기 때문에, 각 노드는 받아온 메시지들만 제 때 동기회되면 되기 때문이다.

이런 점들로 인해, kafka와 같은 부류의 제품들은 분산 시스템의 높은 처리량을 필요로 하는 대용량 실시간 스트리밍, 데이터 파이프라인, 로그 집계 및 분석 등에 유리하다.

참고: 얄팍한 코딩사전

profile
주니어 백엔드 개발자

0개의 댓글