Kafka & rabbitmq
kafka
Producer:消息生产者,将消息 push 到 Kafka 集群中的 Broker。
Consumer:消息消费者,从 Kafka 集群中 pull 消息,消费消息。
Consumer Group:组团消费,每个 Consumer 都属于一个 Consumer Group。
- 消费者组在逻辑上是同一个订阅者。
- 消费者组内每个消费者负责消费不同分区(Partition)的数据,一个分区只能由一个组内消费者消费;
- 消费者组之间互不影响。即每条消息只能被 Consumer Group 中的一个 Consumer 消费;
- 但是可以被多个 Consumer Group 组消费。这样就实现了单播和多播。
Broker:一台 kafka 服务器就是一个 broker。一个集群由多个 broker 组成。一个 broker 可以容纳多个 topic。
Partition 追加写log,副本存到多个Broker,可指定副本数量,分区内可保证顺序
TOPIC 分为多个Partition,指定Partitionkey
Broker == kafka
Kafka不主动退给消费者,游标推进是Consumer的事
集群 broker * n
TOPIC 多分区Partition
Partition 多副本 replica
ZooKeeper 分布式,机器多,配置不能一台一台搞
ZooKeeper 本质上是一个分布式的小文件存储系统。提供基于类似于文件系统的目录树方式的数据存储,并且可以对树种 的节点进行有效管理。从而来维护和监控你存储的数据的状态变化。将通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。
注册 Broker
Topic 和 Broker 的对应关系都由 ZooKeeper 进行维护。
producer,broker,consumer
RabbitMQ:以broker为中心,有消息的确认机制(这里的确认机制指的是客户端消费消息的时候)
kafka:以consumer为中心,无消息的确认机制(这里的确认机制指的是客户端消费消息的时候)
kafka和rabbitMQ都有发送到Broker的确认机制(全部 or 大多数)。
发送+确认
Producer -> msg hash mod make number -> get leader from zk -> send (不等 等leader 等所有ack)
Hash消息得到number到ZooKeeper获取leader,然后发送
收到保存
savemsg -> .log(data).index(offset) 数据放在data 索引稀疏索引**timeindex文件:**时间索引文件
命字是offset,可以配置存储大小
每个Kafka主题(topic)都有一个对应的目录,其中包含多个分区(partition)。在每个分区目录下,会有多个日志段文件(log segment file),每个日志段文件都包含了一定范围的消息。
数据查找
找到对应分区partion ->2分查找对应的文件->在index文件找(稀疏索引)->对应log找
3、吞吐量方面
RabbitMQ:支持消息的可靠的传递,支持事务,不支持批量操作,基于存储的可靠性的要求存储可以采用内存或硬盘,吞吐量小。如果需要持久化,会采用实时存储。
kafka:内部采用消息的批量处理,数据的存储和获取是本地磁盘顺序批量操作,消息处理的效率高,吞吐量高。定时持久化存储,非实时持久化储存
4、集群负载均衡方面
RabbitMQ:本身不支持负载均衡,需要loadbalancer的支持。即指定存到哪个broker就是哪个broker。
kafka:采用zookeeper对集群中的broker,consumer进行管理,可以注册topic到zookeeper上,通过zookeeper的协调机制,producer保存对应的topic的broker信息,可以随机或者轮询发送到broker上,producer可以基于语义指定分片,消息发送到broker的某个分片上。即如果不指定分片,就会默认存到master的分片上,然后再同步到其他的分片。
1、队列同步发起方(Rabbit使用的镜像集群,非默认的主从集群)
RabbitMQ:镜像队列同步时,由主队列向镜像队列发起。
kafka:副本同步时,副本分片由副本分片向主分片发起同步。
2、副本同步限制
RabbitMQ:副本队列可以落后主队列很多。
kafka:副本分片只能落后replica.lag.time.max.ms的时间内(ISR),如果超过这个时间,副本分片会被删除掉。
3、副本同步对性能的影响(Rabbit使用的镜像集群,非默认的主从集群)
RabbitMQ:新节点加入时,如果ha-sync-mode=manual,则不会手动同步镜像到新节点。如果ha-sync-mode=automatic时,会自动同步到新节点中。在同步新节点时,主节点不会再接收生产者的消息,也不会push消息到消费者,就是一种stop-the-world的状态。如果存量消息过多,则会导致生产者和消费者请求超时,可以使用设置重试规则解决。
kafka:新的节点加入,会主动从主分区拉取数据,等待数据拉取完成(不包含未提交的,只包含所有已提交数据)后才把该节点加入到集群中。
- Rebalance:
触发条件:Partition 或ConsumerGroup 内的Consumer 数量发生变化
分配逻辑:range- 先均分,除不尽的部分按照字典序从前到后分配,所以4 个partition 分给3 个consumer 为:2 1 1 - Offset维护逻辑:
ConsumerGroup 中的每个Partition 的offset 维护在*_consumer_offset* 这个topic 中
该Topic 的每个Partition 维护固定的ConsumerGroup 中的所有数据(一对多)
提交Offset 时是作为Producer 向该Topic发送消息 - High Watermark:为leader+ISR中的最大offset的最小值,用于确保故障转移时多副本之间的数据一致性
HW 由Leader 维护和更新,Consumer 最大可拉取到HW ,其后内容不可见
故障转移时,Leader+ 所有的Follower 会舍弃HW 之后的内容,所有消息从HW重新开始累加
不同点:
-
数据处理方式:RabbitMQ是基于消息队列的中间件,它将消息存储在队列中,并使用消费者从队列中拉取消息。而Kafka是基于发布/订阅的消息系统,消息被发布到主题(topic)中,然后消费者订阅这些主题并消费消息。
-
数据持久化:在RabbitMQ中,消息可以持久化到磁盘,以确保即使在服务器故障时也不会丢失消息。而Kafka使用持久化日志(log)的方式来存储消息,可以持久化存储大量的消息。
-
数据分发方式:RabbitMQ使用预先定义的路由规则将消息发送到特定的队列。而Kafka使用分区(partition)将消息分发到不同的消费者组。
-
实时处理:Kafka通常用于实时数据流处理,可以处理大规模的实时数据。而RabbitMQ更适合于传统的消息队列应用,如任务分发、通知等。 综上所述,RabbitMQ和Kafka都是强大的消息传递系统,但在设计和使用时需要考虑到它们的不同特点和适用场景。选择合适的系统取决于具体的需求,例如数据处理方式、可靠性要求、实时性要求等。
* (星号) 用来表示一个单词 (必须出现的) # (井号) 用来表示任意数量(零个或多个)单词
生产者 消费者 中间是broker queue是载体
连接服务端,创建信道 配置队列和exchang,binding 路由规则routingkey
连接到RabbitMQ 创建一个通道 声明一个队列(可以声明交换机,配置routingkey*#与队列绑定 )发送消息到队列
连接到RabbitMQ 创建一个通道 声明一个队列
注意
手动ack,限制重试,失败记录
模式 发布订阅 直连(不想被所有绑定的队列消费,加入路由)