kafka是apache开源的消息队列顶级项目之一,在大数据场景下使用较多,由linkedin开源,目前社区活跃,全球较多组织开始使用kafka来进行数据交换
RabbitMQ是流行的开源消息队列系统,用erlang语言开发。RabbitMQ是AMQP(高级消息队列协议)的标准实现。
对比项 | kafka | rabbitmq |
开发语言 | scala,Java | erlang |
是否支持多租户 | 2.x.x支持多租户 | 支持多租户 |
是否支持topic优先级 | 不支持 | 支持 |
是否支持消息全局有序 | 不支持 | 支持 |
是否支持消息分区有序 | 支持 | 支持 |
是否内置监控 | 无内置监控 | 内置监控 |
是否支持多个生产者 | 一个topic支持多个生产者 | |
是否支持多个消费者 | 一个topic支持多个消费者 | |
是否支持一个分区多个消费者 | 不支持 | 不支持 |
是否支持JMX | 支持 | 不支持(非java语言编写) |
是否支持加密 | 支持 | 支持 |
消息队列协议支持 | 仅支持自定义协议 | 支持AMQP、MQTT、STOMP协议 |
客户端语言支持 | 支持多语言客户端 | 支持多语言客户端 |
是否支持消息追踪 | 不支持消息追踪 | 支持消息追踪 |
是否支持消费者推模式 | 不支持消费者推模式 | 支持消费者推模式 |
是否支持消费者拉模式 | 支持消费者拉模式 | 支持消费者拉模式 |
是否支持广播消息 | 支持广播消息 | 支持广播消息 |
是否支持消息回溯 | 支持消息回溯,因为消息持久化,消息被消费后会记录offset和timstamp | 不支持,消息确认被消费后,会被删除 |
是否支持消息数据持久化 | 支持消息数据持久 | 支持消息数据持久 |
是否支持消息堆积 | 支持消息堆积,并批量持久化到磁盘 | 支持阈值内的消息对接,无法支持较大的消息堆积 |
是否支持流量控制 | 支持控制用户和客户端流量 | 支持生产者的流量控制 |
是否支持事务性消息 | 支持 | 不支持 |
元数据管理 | 通过zookeeper进行管理 | 支持消息数据持久 |
默认服务端口 | 9200 | 5672 |
默认监控端口 | kafka web console 9000;kafka manager 9000; | 15672 |
网络开销 | 相对较小 | 相对较大 |
内存消耗 | 相对较小 | 相对较大 |
cpu消耗 | 相对较大 | 相对较小 |
在实际生产应用中,通常会使用kafka作为消息传输的数据管道,rabbitmq作为交易数据作为数据传输管道,主要的取舍因素则是是否存在丢数据的可能;rabbitmq在金融场景中经常使用,具有较高的严谨性,数据丢失的可能性更小,同事具备更高的实时性;而kafka优势主要体现在吞吐量上,虽然可以通过策略实现数据不丢失,但从严谨性角度来讲,大不如rabbitmq;而且由于kafka保证每条消息最少送达一次,有较小的概率会出现数据重复发送的情况;
1.kafka
名词 解释
Producer
消息的生成者
Consumer
消息的消费者
ConsumerGroup
消费者组,可以并行消费Topic中的partition的消息
Broker
缓存代理,Kafka集群中的一台或多台服务器统称broker.
Topic
Kafka处理资源的消息源(feeds of messages)的不同分类
Partition
Topic物理上的分组,一个topic可以分为多个partion,每个partion是一个有序的队列。partion中每条消息都会被分 配一个 有序的Id(offset)
Message
消息,是通信的基本单位,每个producer可以向一个topic(主题)发布一些消息
Producers
消息和数据生成者,向Kafka的一个topic发布消息的 过程叫做producers
Consumers
消息和数据的消费者,订阅topic并处理其发布的消费过程叫做consumers
在 Kafka 集群中有 3 个分区,每个分区有 3 个副本,正好均匀地分布在 3个 broker 上,灰色阴影的代表 leader 副本,非灰色阴影的代表 follower 副本,虚线表示 follower 副本从 leader 副本上拉取消息。当生产者写入消息的时候都写入 leader 副本,对于图 8-23 中的 情形,每个 broker 都有消息从生产者流入;当消费者读取消息的时候也是从 leader 副本中读取 的,对于图 8-23 中的情形,每个 broker 都有消息流出到消费者。
我们很明显地可以看出,每个 broker 上的读写负载都是一样的,这就说明 Kafka 可以通过 主写主读实现主写从读实现不了的负载均衡。上图展示是一种理想的部署情况,有以下几种 情况(包含但不仅限于)会造成一定程度上的负载不均衡:
(1)broker 端的分区分配不均。当创建主题的时候可能会出现某些 broker 分配到的分区数 多而其他 broker 分配到的分区数少,那么自然而然地分配到的 leader 副本也就不均。
(2)生产者写入消息不均。生产者可能只对某些 broker 中的 leader 副本进行大量的写入操 作,而对其他 broker 中的 leader 副本不闻不问。
(3)消费者消费消息不均。消费者可能只对某些 broker 中的 leader 副本进行大量的拉取操 作,而对其他 broker 中的 leader 副本不闻不问。
(4)leader 副本的切换不均。在实际应用中可能会由于 broker 宕机而造成主从副本的切换, 或者分区副本的重分配等,这些动作都有可能造成各个 broker 中 leader 副本的分配不均。
对此,我们可以做一些防范措施。针对第一种情况,在主题创建的时候尽可能使分区分配 得均衡,好在 Kafka 中相应的分配算法也是在极力地追求这一目标,如果是开发人员自定义的 分配,则需要注意这方面的内容。对于第二和第三种情况,主写从读也无法解决。对于第四种 情况,Kafka 提供了优先副本的选举来达到 leader 副本的均衡,与此同时,也可以配合相应的 监控、告警和运维平台来实现均衡的优化。
在实际应用中,配合监控、告警、运维相结合的生态平台,在绝大多数情况下 Kafka 都能 做到很大程度上的负载均衡。总的来说,Kafka 只支持主写主读有几个优点:可以简化代码的 实现逻辑,减少出错的可能;将负载粒度细化均摊,与主写从读相比,不仅负载效能更好,而 且对用户可控;没有延时的影响;在副本稳定的情况下,不会出现数据不一致的情况。为此, Kafka 又何必再去实现对它而言毫无收益的主写从读的功能呢?这一切都得益于 Kafka 优秀的 架构设计,从某种意义上来说,主写从读是由于设计上的缺陷而形成的权宜之计。
offsets.topic.replication.factor=3
设置副本数量为3,这样当一台消费者宕机时,其他消费者也可以进行消费