Kafka vs Rabbitmq
Hermaeus Mora ·
영속성(Kafka win)
Kafka: 메시지를 로그로 보관. 소비해도 안 사라짐. retention 기간 내엔 오프셋 되감아 재생 가능. 여러 컨슈머 그룹이 각자 독립적으로 전체 스트림 소비.
RMQ: 메시지는 큐에서 소비(ack)되면 사라짐. 재생 없음. 한 번 처리하면 끝. (스트림 큐 기능이 생기긴 했지만 본질은 소비=삭제)
Head of Line Bloking (a.k.a. HOL, RabbitMQ win)
Kafka: 한 파티션은 순서대로 처리 파티션에 [30초짜리, 1초, 1초, 1초] 들어오면 → 30초짜리가 처리되는 동안 뒤 3개는 대기 (head-of-line 블로킹) → 다른 컨슈머는 자기 파티션 것만 처리, 이 밀린 거 못 도와줌
RabbitMQ (prefetch=1): 30초짜리 잡은 워커는 붙잡혀 있고 나머지 워커들이 1초짜리들 계속 집어감 → 무거운 작업이 가벼운 작업 안 막음
++ Kafka 토픽의 파티션을 늘리면 컨슈머 그룹 더 붙일 수 있어서 동시 처리량 올릴 수 있지 않나? -> 동적으로 파티션 수 조절하는 것은 불가능에 가까움. mq는 컨슈머 스케일 아웃만 하면 됨. ++ Kafka Retry + DLQ 토픽 추가하면 되지 않나? -> mq는 DLQ 기능이 내장되어 있음.
push 라우팅(RabbitMQ win)
Kafka: 모든 컨슈머가 pull 방식으로 토픽을 구독. 로직 단에서 메세지 필터링 직접 구현해야 함.
RabbitMQ: 특정 컨슈머에게만 보내는 push 방식. exchange가 알아서 필터링 해줌.
순서 보장(Kafka win)
사용자 A가 주문 생성(v1)을 한 뒤, 마음이 바뀌어 1초 만에 주문 수정(v2).
Kafka: 주문 ID(Key)를 기반으로 두 메시지는 동일한 파티션에 순서대로 쌓임. 컨슈머가 1개를 쓰든 10개를 쓰든, 그 파티션은 오직 1개의 컨슈머 스레드만 담당하므로 반드시 v1이 처리된 후 v2가 처리됨.
RabbitMQ: 컨슈머 1번이 v1 메시지를 가져가서 처리 시작(네트워크나 DB 지연으로 3초 걸림). 그 직후, 대기 중이던 컨슈머 2번이 v2 메시지를 바로 채감. (컨슈머 2번은 사양이 좋거나 DB 가벼워서 0.5초 만에 완료) -> 시스템에는 주문 수정(v2)이 먼저 반영.