
백엔드
RabbitMQ
AMQP (Advanced Message Queuing Protocol) 프로토콜을 구현한 메세지 브로커
StackOverflow 질문 수: 14567
사용 기업

토스랩

드림어스컴퍼니

디셈버앤컴퍼니

마이리얼트립

와디즈

버즈빌

다노

오피지지

카카오페이

위메프

위대한상상

하이퍼커넥트

카카오모빌리티

카카오

뱅크샐러드

우아한형제들

카카오뱅크

네이버웹툰
더 보기
매드업
최적의 메시지 브로커를 찾아서
매드업에서는 프리즘이라는 시스템을 사용하여 광고 데이터를 수집하고 있습니다. 프리즘에 대해서는 여기를 참고해 주세요.프리즘은 여러 마이크로 서비스들로 이루어져 있고, 마이크로 서비스들 간의 통신을 위해 메시지 기반 비동기 통신 방식을 사용하고 있습니다. 따라서 메시지들을 안정적이고 효율적으로 전달할 수 있는 메시지 브로커를 선택하는 것은 매우 중요한 문제입니다. 이 글에서는 프리즘이 발전하는 과정에서 실제로 사용한 메시지 브로커의 변천사를 소개하고자 합니다. 어떠한 이유로 사용하던 메시지 브로커를 변경하게 되었는지 실제 경험에 기반한 내용을 이야기해 보겠습니다.프리즘을 위한 메시지 브로커가 갖춰야 할 기능 요건들메시지 브로커를 사용할 때 이상적인 동작은 “정확히 한 번”(Exactly Once) 전달일 것입니다. 하지만 현실적으로는 어렵기 때문에 “최소 한 번”(At Least Once) 전달과 “최대 한 번”(At Most Once) 전달 중에 선택을 하게 됩니다. 프리즘은 메시지를 중복으로 처리해도 문제가 없는 시스템이기 때문에 최소 한 번 전달을 현실적인 목표로 잡았습니다.프리즘에서 필요한 메시지 브로커가 갖춰야 할 기능 요건들은 다음과 같습니다.• 안정적인 메시지 전달 (최소 한 번 전달) 프리즘은 쿠버네티스 환경에서 운영되고 있습니다. 쿠버네티스 환경에서 파드의 종료는 배포나 HPA(Horizontal Pod Autoscaling) 등으로 인해 언제든 발생할 수 있기 떄문에, 파드가 종료되는 경우에도 메시지가 유실되지 않고 전달될 수 있어야 합니다.• 유연한 메시지 컨슈머(consumer) 스케일링 프리즘의 각 마이크로 서비스는 HPA를 사용하여 필요에 따라 파드 개수가 적절하게 조정됩니다. 따라서 메시지 컨슈머의 개수가 변하는 경우에도 큰 지연 시간 없이 메시지를 안정적으로 가져올 수 있어야 합니다.• 효율적인 메시지 분배 프리즘에서 수집하는 광고 데이터는 광고주에 따라 사이즈 차이가 크며, 그에 따라 소요되는 수집 시간도 차이가 큽니다. 데이터 사이즈가 작은 광고주의 경우 1분 안에 수집이 끝나기도 하지만, 사이즈가 큰 광고주는 20~30분이 걸리기도 합니다. 이처럼 메시지 처리 시간의 편차가 큰 편이기 때문에 일률적으로 메시지를 분배하는 라운드 로빈(Round Robin)과 같은 방식은 적합하지 않습니다. 여유가 있는 메시지 컨슈머에게 우선적으로 메시지를 전달할 수 있어야 합니다.실제로는 더 많은 기능 요건들이 있지만, 여기서는 이 글과 관련된 것들만 언급했습니다. 이러한 요건들에 맞는 최적의 메시지 브로커를 한 번에 찾았다면 좋았겠지만 아쉽게도 그러지 못 했습니다. 지금부터는 프리즘 운영 환경에서 실제로 사용했었던 메시지 브로커인 SQS와 카프카, 그리고 현재 사용 중인 RabbitMQ에 대해 얘기해 보겠습니다.새로운(v2) 프리즘을 만들면서 처음 사용한 메시지 브로커는 Amazon SQS(Simple Queue Service)였습니다. AWS를 사용하고 있기 때문에 쉽게 적용할 수 있었고, 다른 팀에서도 사용하고 있었기
awssqs
kafka
rabbitmq
CJ올리브영
쿠폰 발급 RabbitMQ도입기
지난 시간엔 어푸님께서 Sync 쿠폰 발급에서 Async로 전환하며 Redis Worker에 대해 포스팅 해주셨습니다.이번 시간엔 지난 Redis Worker에서 Rabbit MQ로 최종 도입하게 된 배경 및 사용 기술에 대해 작성하게 되겠습니다.얼마 전 쿠폰 발급을 Redis Worker의 도입 에 대해 포스팅 하였었습니다.도입 전 세일 대비 발급량에서 우월한 성능을 보여주었지만... Redis에겐 문제가 있었습니다. 1️⃣ 저희의 Redis의 Worker는 list를 MQ의 형태로 활용하였는데,(이전 포스팅 참고)해당 방법은 단순 처리하기엔 충분하였으나, 추후 기능의 확장을 위한 부분이 미비할 수 있었습니다.2️⃣ Redis Worker의 세일 발급 당시 과도한 요청 처리에 대해 불편한 사항이 있었습니다.일반적인 쿠폰발급에는 이상이 없었으나, 네고왕/세일과 같은 행사기간에 간혹 문제가 발생하였습니다.보다 안정적인 발급 처리와 기능적인 확장을 위해 MQ를 도입하게 되었습니다.왜 RabbitMQ를 사용했나요?개인적으로 MQ 하면 대표적으로 RabbitMQ 와 Kafka가 있다고 생각합니다.AWS sandbox를 제공해주시어, 적극적인 PoC를 통해 선정하였습니다.Aws가 제공하는 Kafka서비스입니다.어지간한건 Aws가 다 관리해줍니다. 모니터링 LOG의 제공 및 지표 확인은 유료입니다.특징으로는• 파티션 정책을 통해 분산처리가 가능합니다. 대용량 데이터 처리 지표가 우수합니다.• 메시지 영속성을 가집니다.• 수신을 보장하는 경우 사용합니다.마찬가지로 Aws Managed RabbitMQ를 사용하였습니다.관리는 위 MSK와 유사합니다.• 가장 큰 장점은 사용이 간편합니다.• 다양한 메시지 교환방식으로 유연한 구조설계가 가능합니다.• 수신을 보장하는 경우 사용합니다.둘 다 유사하지만, 내부적인 동작이 다릅니다. 메시지 영속성이라던가..분산처리방식이라던가..대용량 데이터 처리 지표는 kafka가 높은 것으로 알려져 있습니다.하지만, 저희 스쿼드는 세일기간 혹은 특정 이벤트마다 scalability한 유연한 구조로 운영이 이루어지기 때문에확장 이후 축소가 불가한 Kafka의 파티션 정책은 저희와 맞지 않았습니다.그리고 RabbitMQ는 활용도에 따라서 Kafka보다 오히려 더 다양한 처리에 유용하다고 생각하여 도입하게 되었습니다.이전 일련번호를 통해 list의 데이터를 읽어오고, 처리를 위한 비동기 구성을 한 것과 달리,RabbitMQ는 내부적으로 concurrency를 이용하기 때문에 처리가 간소화되었습니다.그리고 기존 배치로 처리하던 고객 쿠폰 대량 발급처리와세일행사 및 기타 쿠폰 발급처리에 도입하였습니다.메시지 처리(실 발급) Process는 달라지지 않았기에, 메시지 Consume을 하고 RabbitMQ Config를 코드기반으로 구성하였습니다. prefetch와 concurrency 설정 및 direct exchange 방식을 채택하였습니다. (사진은 간단한 예시입니다.)발급량은 이전 5월 네고왕이나 6월 세일만큼 총 발급량이 많지
kafka
rabbitmq
redis
카카오
카카오 개발자들을 위한 공용 Message Streaming Platform – Kafka & RabbitMQ
안녕하세요, 인프라팀 loki 입니다.오랜 시간 인프라에서 TF단위로 소소하게 제공하던 공용 Kafka와 공용 RabbitMQ의 사용량이 점점 커지고, 많은 서비스팀에서 이용해 주셔서, 운영고도화를 위해 정식 MessageQueue TF 조직이 2021년에 신설되었습니다. 이에 따라 TF에서 현재 운영하고 있는 메시지 큐 서비스의 운영 현황 및 향후 목표를 공유드리고자 합니다. 운영 현황 MessageQueue TF 2016년 경까지는 Kafka와 RabbitMQ를 모든 서비스팀에서 각각 사용하고 있었으나 사용량이 계속 늘어가고 있는 상황이었습니다. 그러던 중에 메시지 큐 시스템을 각 팀별로 각각 구성해서 사용하는 게 아니라 공동으로 사용할 수 있다면, 인프라 비용도 줄일 수 있고 서비스팀에서는 운영 리소스를 줄여 서비스 개발에 좀 더 집중할 수 있지 않을까라는 생각으로 2016년에 스터디 그룹을 만들게 되었습니다. 그 결과 최초로 모든 서비스팀이 같이 사용할 수 있는 공용 클러스터를 같은 해인 2016년에 오픈할 수 있었습니다.그 후로 여러 차례 성능 테스트와 튜닝 등을 거치면서 2018년도에 안정된 버전이라고 할 수 있는 Kafka 클러스터 공용 버전을 처음 오픈했습니다. 또한, 2020년에 최신 클러스터에서 신규 Kafka 버전으로 업그레이드한 후에는 서비스팀들이 가장 많이 사용하시는 클러스터이기도 합니다.그리고 사용량이 점점 늘어나면서 저희 TF가 지원하는 범위도 점점 확대되게 되었습니다. 얼마 전에는 메시지 큐에 대한 지원을 강화하고 운영 범위를 확대 및 안정적으로 운영하기 위해 MessageQueue TF 조직이 신설되었고, 2022년에는 새로운 신규 클러스터를 오픈할 예정입니다. Kafka 기본 구조 다음은 Kafka 도입 시의 인프라 구성도입니다. 이미지 출처 : https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying 카카오에서는 서비스 규모가 거대해지고, 서비스 인프라 또한 점점 거대해지면서 MQ의 개념이 많이 사용되고 있었습니다. 그러나 그 과정에서 각각의 데이터 플랫폼을 개발자들이 직접 운영, 관리 및 유지보수하고 메시지 손실에 대한 고민도 직접 하다보니 운영 리소스 낭비가 매우 심했습니다. 그 후 컨플루언트에서 Kafka를 오픈 버전으로 정식 발표하면서, 공통된 대용량 데이터 플랫폼 개념이 등장하게 되었습니다. Kafka를 도입하게 되면 서비스팀에서 많이 사용하시는 용도에서 굉장히 안정적으로 운영이 가능하고, 대용량 트래픽을 실시간으로 처리할 수 있다는 점에서 많은 각광을 받았습니다. RabbitMQ 기본 구조 다음은 RabbitMQ입니다. RabbitMQ의 경우 실제로 Kafka와 조금 비슷한 부분도 있고 다른 부분도 있는데요, RabbitMQ의 가장 큰 특징은 메시지 라우팅 키를 통해 메시지 라우팅을 지원하는 점입니다. 주키퍼(Zoo
kafka
rabbitmq
엔라이즈
RabbitMQ 를 이용한 서버-클라이언트 양방향 통신 구현
다양한 목적으로 인해 서버-클라이언트 간 양방향 통신(duplex communication system) 을 필요로 하는 경우가 있습니다. 엔라이즈에서 서비스 하는 WIPPY 와 MOCI 역시 서버-클라이언트 간 양방향 통신을 구현해야 하는 이슈들이 있었으며, 우리는 RabbitMQ 를 이용하여 양방향 통신을 성공적으로 구축하여 다양한 용도로 사용하고 있습니다. 우리의 사례를 소개함으로써 양방향 통신 구축을 고민하는 분들에게 작게나마 도움이 될 수 있다면 좋을 것 같습니다. 양방향 통신이 필요한 이유 서버-클라이언트 간 양방향 통신 기능이 최초로 요구되던 시기는 2016년으로 거슬러 올라갑니다. 양방향 통신은 iOS/Android 에서 지원하는 푸시 메시지를 통해서도 부분적으로 구현할 수 있겠으나, 이 경우 사용자가 푸시를 허용하지 않았을 경우 무용지물이 되는 단점이 존재합니다. 만일 Polling 형태로 구현할 경우엔 양방향 통신을 위한 중계 서버 자체는 필요 없겠지만 Polling 주기에 따라 약화되는 응답성, 트래픽의 낭비라는 문제점이 발생하며, 그로 인하여 불필요한 서버/클라이언트의 자원이 소비될 것입니다. 즉 서버-클라이언트 양방향 통신 기능이 구현된다면 클라이언트의 네트워크 상태에만 의존적이면서도 자원의 낭비를 최소화 하는 구성이 가능해 집니다. 또한 서버는 접속한 클라이언트에게 언제든지 원하는 메시지를 보낼 수 있으며, 실시간 응답이 중요시 되는 기능들의 구현을 통해 더욱 좋은 사용자 경험을 제공할 수 있게 됩니다. RabbitMQ 에 관하여 Python 으로 서버를 개발하는 분들 중 비동기 작업을 위해 Celery 를 도입해 본 경험이 있다면 RabbitMQ 라는 메시지 브로커 서버에 대해서 들어보셨을 것입니다. 생소하신 분들을 위해 간단히 설명하자면 RabbitMQ 는 Erlang 으로 작성된 메시지 브로커입니다. AMQP 를 지원하며, 다양한 라우팅 모델을 지원하는 오픈소스 소프트웨어입니다. 우리는 서버 개발 언어로 Python 을 사용하고 있으며, Celery 의 메시지 브로커 로 RabbitMQ 를 선택하여 오랜 기간 운용해 왔습니다. 많은 검토와 고민 끝에 RabbitMQ 를 서버-클라이언트 양방향 통신 수단으로 충분히 활용할 수 있겠다는 생각을 했었고, 성공적으로 적용하여 다양한 곳에서 사용할 수 있게 되었습니다. 솔루션 검토 최초 양방향 통신 시스템을 구축하기 위해 다양한 방법들을 고민해 보았습니다. WebSocket 양방향 통신 설계로써 대표적으로 생각해 볼 만한 방법은 socket.io 를 위시한 WebSocket 서버를 구축하여 서버-클라이언트 간 통신을 구현하는 것입니다. 하지만 다음 이유들로 인해 최종적으로는 WebSocket 서버를 채택하지 않기로 결정하였습니다. 당시 만족할 만한 WebSocket 서버는 Node.js 와 socket.io 를 기반으로 서버를 구현하는 방법이 주류였는데, 이 경우 Python 으로 구현되어 있는 비즈니스 로직이 여러 곳으로 분산될 수 있는 문제점이 예상 되었습니다.
python
rabbitmq
연관 기술 스택

AWS SQS

Celery

Kafka