Kafka与RabbitMQ比较

WIP

背景

目前业务上都在用, 何时应该选择RabbitMQ, 何时应该选择Kafka? RabbitMQ主要是Python的celery无脑引入进来的.

首先: 业务逻辑, 没有性能扩缩/风险隔离场景的, 可以不走队列的, 不要走队列. 会导致不必要的复杂性.

队列

Kafka服务架构

装逼之问, Kafka性能为什么如此优秀?

概念

写入

消费

消费组offset管理

消费延迟计算:

RabbitMQ简介

AMQP Model

TODO Exchange的意义 ???

Kafka vs RabbitMQ

Kafka基于磁盘日志的消息代理, pull模式消费数据; RabbitMQ主要基于内存, push模式消费.

生产者/消费者分离, 写入者不用管消费者. 消费堆积不会严重影响Kafka自身服务稳定性. RabbitMQ也有消息持久化, 但是消息堆积严重时容易OOM.

Kafka可随时重放历史数据, RabbitMQ消息一旦确认就不能被再次消费.

Kafka按消息顺序处理, RabbitMQ单个消息处理确认: 顺序性缺点: 单消息处理延迟严重影响整体消费速率. 例子: 视频素材处理. 顺序性好处: 利用消费顺序性+合理分区键值做事务处理保证.

Kafka最大并行数等于分区数限制, RabbitMQ则无限制.

Kafka批处理优化消息处理的吞吐量. RabbitMQ注重单条消息的入队列到完成耗时.

Kafka适合数据量较大的, 面向批处理的场合, 如日志入库等; RabbitMQ则更适合每个消息数据量较小, 需要面向单个消息处理, 每个消息处理耗时不确定的场景.

恰好一次处理 vs 至少处理一次语义.

数据去重

Kafka可以利用日志压缩功能做数据去重, 当作数据存储, 对于数据堆积且只需要处理最近一次消息的场景有用.

RabbitMQ发消息去重一般业务实现还是要依赖一个KV来做.

TODO: 订单确认如何做?

消息层面的数据优先级

RabbitMQ支持消息层面设定优先级.

Kafka严格消息顺序性, 自然不支持. 只能通过不同的topic分开消费隔离.

消费背压

RabbitMQ队列支持淘汰策略, 包括丢弃, 转发等

Kafka的消息队列是异步清理的

Celery vs RabbitMQ

Celery: Python框架, 需要依赖具体Broker及Backend, 一般是RabbitMQ做Broker, Redis做Backend

将结果存到Backend, 实现异步的RPC方式

需要依赖Backend做消息去重

Thoughts: 数据读写接口设计

面向单条消息设计接口, 内部实现通过批量提交优化性能

type Worker interface {
    func Handle(...) error
    func Flush() error
}

Reference

HOME