17 个方面,综合对比 Kafka、RabbitMQ、RocketMQ、ActiveMQ 四个分布式消息队列(3)
Kafka:极大 Kafka按批次发送消息和消费消息。发送端将多个小消息合并,批量发向Broker,消费端每次取出一个批次的消息批量处理。 rabbitmq:比较大 zeromq:极大 rocketmq:大 rocketMQ接收端可以批量消费消息,可以配置每次消费的消息数,但是发送端不是批量发送。 activemq:比较大 十二、订阅形式和消息分发 Kafka:基于topic以及按照topic进行正则匹配的发布订阅模式。 【发送】 发送端由topic和key来决定消息发往哪个分区,如果key为null,那么会使用轮询算法将消息均衡地发送到同一个topic的不同分区中。如果key不为null,那么会根据key的hashcode取模计算出要发往的分区。 【接收】 1>consumer向群组协调器broker发送心跳来维持他们和群组的从属关系以及他们对分区的所有权关系,所有权关系一旦被分配就不会改变除非发生再均衡(比如有一个consumer加入或者离开consumer group),consumer只会从对应的分区读取消息。 2>kafka限制consumer个数要少于分区个数,每个消息只会被同一个 Consumer Group的一个consumer消费(非广播)。 3>kafka的 Consumer Group订阅同一个topic,会尽可能地使得每一个consumer分配到相同数量的分区,不同 Consumer Group订阅同一个主题相互独立,同一个消息会被不同的 Consumer Group处理。 rabbitmq:提供了4种:direct, topic ,Headers和fanout。 【发送】 先要声明一个队列,这个队列会被创建或者已经被创建,队列是基本存储单元。 由exchange和key决定消息存储在哪个队列。 direct>发送到和bindingKey完全匹配的队列。 topic>路由key是含有"."的字符串,会发送到含有“*”、“#”进行模糊匹配的bingKey对应的队列。 fanout>与key无关,会发送到所有和exchange绑定的队列 headers>与key无关,消息内容的headers属性(一个键值对)和绑定键值对完全匹配时,会发送到此队列。此方式性能低一般不用 【接收】 rabbitmq的队列是基本存储单元,不再被分区或者分片,对于我们已经创建了的队列,消费端要指定从哪一个队列接收消息。 当rabbitmq队列拥有多个消费者的时候,队列收到的消息将以轮询的分发方式发送给消费者。每条消息只会发送给订阅列表里的一个消费者,不会重复。 这种方式非常适合扩展,而且是专门为并发程序设计的。 如果某些消费者的任务比较繁重,那么可以设置basicQos限制信道上消费者能保持的最大未确认消息的数量,在达到上限时,rabbitmq不再向这个消费者发送任何消息。 zeromq:点对点(p2p) rocketmq:基于topic/messageTag以及按照消息类型、属性进行正则匹配的发布订阅模式 【发送】 发送消息通过轮询队列的方式发送,每个队列接收平均的消息量。发送消息指定topic、tags、keys,无法指定投递到哪个队列(没有意义,集群消费和广播消费跟消息存放在哪个队列没有关系)。 tags选填,类似于 Gmail 为每封邮件设置的标签,方便服务器过滤使用。目前只支 持每个消息设置一个 tag,所以也可以类比为 Notify 的 MessageType 概念。 keys选填,代表这条消息的业务关键词,服务器会根据 keys 创建哈希索引,设置后, 可以在 Console 系统根据 Topic、Keys 来查询消息,由于是哈希索引,请尽可能 保证 key 唯一,例如订单号,商品 Id 等。 【接收】 1>广播消费。一条消息被多个Consumer消费,即使Consumer属于同一个ConsumerGroup,消息也会被ConsumerGroup中的每个Consumer都消费一次。 2>集群消费。一个 Consumer Group中的Consumer实例平均分摊消费消息。例如某个Topic有 9 条消息,其中一个Consumer Group有3个实例,那么每个实例只消费其中的 3 条消息。即每一个队列都把消息轮流分发给每个consumer。 activemq:点对点(p2p)、广播(发布-订阅) 点对点模式,每个消息只有1个消费者; 发布/订阅模式,每个消息可以有多个消费者。 【发送】 点对点模式:先要指定一个队列,这个队列会被创建或者已经被创建。 发布/订阅模式:先要指定一个topic,这个topic会被创建或者已经被创建。 【接收】 点对点模式:对于已经创建了的队列,消费端要指定从哪一个队列接收消息。 发布/订阅模式:对于已经创建了的topic,消费端要指定订阅哪一个topic的消息。 十三、顺序消息 Kafka:支持。 设置生产者的max.in.flight.requests.per.connection为1,可以保证消息是按照发送顺序写入服务器的,即使发生了重试。 kafka保证同一个分区里的消息是有序的,但是这种有序分两种情况 1>key为null,消息逐个被写入不同主机的分区中,但是对于每个分区依然是有序的 2>key不为null , 消息被写入到同一个分区,这个分区的消息都是有序。 rabbitmq:不支持 zeromq:不支持 rocketmq:支持 activemq:不支持 十四、消息确认 Kafka:支持。 1>发送方确认机制 ack=0,不管消息是否成功写入分区 ack=1,消息成功写入首领分区后,返回成功 ack=all,消息成功写入所有分区后,返回成功。 2>接收方确认机制 自动或者手动提交分区偏移量,早期版本的kafka偏移量是提交给Zookeeper的,这样使得zookeeper的压力比较大,更新版本的kafka的偏移量是提交给kafka服务器的,不再依赖于zookeeper群组,集群的性能更加稳定。 rabbitmq:支持。 1>发送方确认机制,消息被投递到所有匹配的队列后,返回成功。如果消息和队列是可持久化的,那么在写入磁盘后,返回成功。支持批量确认和异步确认。 2>接收方确认机制,设置autoAck为false,需要显式确认,设置autoAck为true,自动确认。 (编辑:ASP站长网) |