消息队列Kafka和Pulsar选型

Table of Contents

1: 业务场景

1.1 业务场景描述

  • 我们需要一个把实时的交易数据进行持久化保存,并且能快速的给其他服务提供最新的交易数据;
  • 当服务启动或者重启后,能快速提供完整的并且最新的交易数据;
  • 现有的机制是每个订单使用 go 协程直接写入 Mysql 数据库,对数据库的压力比较大,且系统的延迟比较高;

1.2 业务场景 feature

  • 解耦,降低数据数据库性能导致的整个服务延迟;
  • 数据完整的,及时地进行持久化;
  • 交易数据能,迅速的提供给其他需要数据的服务;
  • 流量消峰,减少峰值流量直接对数据库服务造成的冲击, 提高系统的稳定性;

2:消息中间件

  • 适合用消息中间件解决上述问题;
    • (1) 解耦: 将一个流程的上游和下游拆开,上游专注生产消息,下游专注处理消息;
    • (2) 广播: 一个上游生产的消息轻松被多个下游服务消费处理;
    • (3) 缓冲(流量削峰): 如果上游服务流量突然暴涨,mq 可以做一个缓冲器的作用,下游根据消费能力对消息进行消费,避免暴涨的流量直接对下游服务造成冲击;
    • (4) 异步: 生产者生产消息之后可以马上直接返回,消费者可以异步处理消息;
    • (5) 冗余: 保留历史消息,处理失败或者当出现异常的时候可以进行重试或者回溯,防止消息丢失。
  • 近几年出现了一些关注度较高的消息队列中间件选型,如 Kafka、Pulsar、RocketMQ 等,首先从宏观上做一些对比:
    常见MQ对比
    MQ特性描述KafkaPulsarRocketMQRabbitMQNSQ我们的业务场景是否需要
    推出时间2012 年(Scala 和 Java) 2016 年(Java)2012 年(Java)2007 年(Erlang)2013 年(Go)
    组织Linkin 开源,Apache Yahoo 开源,Apache 阿里开源,Apache Pivotal 开源,MozillaMIT
    功能消费模式consumer消费消息的方式pullpushpullpushpush?
    延迟队列消息投递延迟NoYesYesYesYes
    死信队列NoYesYesYesNo?
    优先级队列NoNoNoYesNo
    消息回溯YesYesYesNoNo需要
    消息持久化YesYesYesYesYes需要
    消息确认机制offsetoffset+单条offset单条单条需要
    消息TTL消息TTL表示一条消息的生存时间,如果消息发出来后,在TTL的时间内没有消费者进行消费,消息队列会将消息删除或者放入死信队列中YesYesYesYesNo需要
    多租户隔离NoYesNoNoNo?
    消息顺序性消息顺序性是指保证消息有序。消息消费顺序跟生产的顺序保持一致分区有序stream模式有序consumer加锁NoNo?
    消息查询查看MQ中消息的内容,比如通过某个MessageKey/ID,查询到MQ的具体消息NoYesYesYesNo需要
    消费模式stream模式流模式+队列模式广播模式+集群模式队列模式队列模式需要,根据场景选择消费模式
    消息可靠性以生产的消息,发送到mq,防止丢失request.required.acksAck Quorum Size(Qa)RocketMQ与Kafka类似RabbitMQ是主从架构,通过镜像环形队列实现多副本及强一致性语义的NSQ会通过go-diskqueue组件将消息落盘到本地文件中,通过mem-queue-size参数控制内存中队列大小,如果mem-queue-size=0每条消息都会存储到磁盘里,不用担心节点重启引起的消息丢失。但由于是存储在本地磁盘中,如果节点离线,堆积在节点磁盘里的消息会丢失非常重要
    性能单机吞吐量605MB/S605MB/S大概500MB/S38MB/S?重要
    消息延迟5ms5msms级us级非常重要
    支持Topics数百~千,过多会影响性能百万个百~千几千?
    运维与可靠性高可用分布式架构分布式架构Master/SlaveMaster/Slave分布式架构非常重要
    集群扩容增加node,node之间会复制数据均衡增加node,通过新增加分片进行负载均衡增加节点增加节点增加节点
    异地容灾

3: Kafka 特性

4: Pulsar 特性

5: Kafka 和 Pulsar 对比