消息队列:RabbitMQ和Kafka、redis对比
组织结构
RabbitMQ结构
RabbitMQ采用AMQP(Advanced Message Queuing Protocol高级消息队列协议)。
RabbitMQ以broker为中心,有消息的确认机制(客户端消费消息时),broker由Exchange,Binding,queue组成:
Redis消息队列:
Redis消息队列,如果从队列pop数据到worker当处理失败后数据不会回到队列中,
需要从业务中手动把失败的处理数据再push到队列中。
RabbitMQ特性:
采用push的方式,当消息到达队列后,会将消息推到消费者。
支持消息的可靠传递,支持事务,不支持批量操作,基于存储的可靠性的要求存储可以采用内存或硬盘,吞吐量小。
如果需要持久化,会采用实时存储。被消费者端确认消费了的消息会被从磁盘删除掉。
消息确认是客户端从RabbitMQ中取出消息,并处理完成之后,会发送一个ack告诉RabbitMQ,消息处理完成;
当RabbitMQ收到客户端的获取消息请求之后,或标记为处理中,当再次收到ack之后,才会标记为已完成,然后从队列中删除。当RabbitMQ检测到客户端和自己断开链接之后,还没收到ack,则会重新将消息放回消息队列,交给下一个客户端处理,保证消息不丢失,也就是说,RabbitMQ给了客户端足够长的时间来做数据处理。
kafka结构
kafka以consumer为中心,zero-copy机制,消息的消费信息保存的客户端consumer上,
consumer根据消费的点,从broker上批量pull数据;
kafka采用mq结构,broker有part分区的概念:
kafka和rabbitMQ都有发送到Broker的确认机制。
kafka特性:
采用pull的方式,当消息到达队列后,消费者端需要手动从队列拉取消息;
内部采用消息批量处理,数据存储和获取是本地磁盘顺序批量操作,具有O(1)的复杂度(与分区上存储大小无关),
消息处理的效率高,吞吐量高。定时持久化存储,非实时持久化储存;消息被消费掉依然保存在磁盘中。
集群负载均衡
RabbitMQ集群
本身不支持负载均衡,需要loadbalancer的支持。即指定存到哪个broker就是哪个broker。
支持miror的queue,主queue失效,miror queue接管。
新节点加入时,如果ha-sync-mode=manual,则不会手动同步镜像到新节点。
如果ha-sync-mode=automatic时,会自动同步到新节点中。
在同步新节点时,主节点不会再接收生产者的消息,也不会push消息到消费者,相当于停止服务的状态。
如果存量消息过多,则会导致生产者和消费者请求超时,可以使用设置重试规则解决。
kafka集群
采用zookeeper对集群中的broker,consumer进行管理,可以注册topic到zookeeper上,
通过zookeeper协调机制,producer保存对应topic的broker信息,随机或者轮询发送到broker上,broker支持主备模式。producer可以基于语义指定分片,消息发送到broker的某个分片上。
如果不指定分片,就会默认存到master的分片上,然后再同步到其他的分片。
副本分片只能落后replica.lag.time.max.ms的时间内(ISR),如果超过这个时间,副本分片会被删除掉。
新的节点加入,会主动从主分区拉取数据,等待数据拉取完成(不包含未提交的,只包含所有已提交数据)后才把该节点加入到集群中。
适用场景
RabbitMQ是由内在高并发的erlanng语言开发,用在实时对可靠性要求较高的消息传递上。
kafka是采用Scala语言开发,它主要用于处理活跃的流式数据,大数据量的数据处理上。