Kafka的几个问题
上一篇文章简要介绍了Kafka的基本架构以及核心概念(初识Kafka),今天聊一聊Kafka的几个问题。
1. 选举问题
-
控制器选举
-
分区leader选举
**2. 可靠性
**
**3. 为什么Kafka快
**
4. 选择Kafka还是RabbitMQ?
**1 选举问题
**
控制器选举
控制器是Kafka 的核心组件,它的主要作用是在ZooKeeper的帮助下管理和协调整个 Kafka 集群。
在Kafka集群中会有一个或多个Broker,其中一个Broker会被选举为控制器,它负责管理整个集群中所有分区和副本的状态等工作。比如当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本。
Kafka的选举是依赖Zookeeper来实现的,在Kafka集群中成功创建/controller临时节点的Broker就会被选举为Kafka控制器。
**分区leader选举
**
当分区中leader副本下线,此时分区需要选举一个新的leader上线来对外提供服务,这时需要执行leader的选举动作。基本思路是按照AR集合中副本的顺序查找第一个存活的副本,并且这个副本在ISR集合中。
**2 可靠性
**
Kafka发送端的可靠性主要靠acks来保证,其中牵涉到副本,ISR相关的概念可以查看这篇文章(初识Kafka)。
acks=0
生产者将消息发送之后就返回,不管Kafka是否能收到,这种情况消息可能会丢失。
acks=1
生产者将消息发送之后等待leader副本收到消息且落盘才返回。当leader副本刚收到消息,follower还没来得及同步,leader副本所在Broker就宕机了,此时消息就丢失了。
acks=all
生产者将消息发送出去之后,ISR列表中的所有副本(包括leader)都同步到,生产者才会任务消息发送成功。
**3 为什么Kafka快
**
数据分区
不同的分区可位于不同机器(Broker),因此可以充分利用集群优势,实现机器间的并行处理。
顺序写
Kafka 采用了顺序写磁盘(每一个分区里面消息是有序的),顺序写磁盘相对随机写,减少了寻地址的耗费时间。
内存文件映射(Memory Mapped File)
即便是顺序写入硬盘,硬盘的访问速度还是不可能追上内存。Kafka的数据并非实时地写入硬盘,它充分利用了操作系统分页存储来利用内存提高I/O效率。
零拷贝(sendfile)
Kafka中存在大量的网络数据持久化到磁盘(生产者->Broker)和磁盘文件通过网络发送(Broker->消费者)的过程。这一过程的性能直接影响 Kafka 的整体吞吐量。
传统模式下需要在内核空间与用户空间来回切换
图片来源于网络
零拷贝(Zero-copy)技术指在计算机执行操作时,CPU 不需要先将数据从一个内存区域复制到另一个内存区域,从而可以减少上下文切换以及 CPU 的拷贝时间。
Linux 2.4+ 内核通过sendfile系统调用,提供了零拷贝,零拷贝模式下网卡与文件的数据传输可以在内核空间完成。
图片来源于网络
4 选择Kafka还是RabbitMQ?
消息顺序
RabbitMQ和Kafka都可以处理按顺序消费消息
-
一个队列对应一个消费者,消费者端关闭autoack,每次只消费一条信息(prefetchCount=1),处理过后进行手工ack,然后接收下一条消息。
-
消息发送到同一个分区,一个消费者,内部单线程消费。
消息路由
根据消息内容或者某种规则,将消息发送到不同的队列。RabbitMQ交换机和队列的绑定,通过配置很容易在服务层面实现这样的功能。但对于Kafka来说,不得不在业务层面来实现这样的功能,成本会高很多。
延时队列
RabbitMQ间接支持延时队列,可以通过死信交换机来实现,详细可以参考消息队列之RabbitMQ
Kafka不支持延时队列
保持消息
RabbitMQ消息被消费后会被删除,Kafka的消息会被持久化一个专门的日志文件里,不会因为被消费了就被删除,可以多次重复消费。
吞吐量
Kafka的吞吐量是每秒几十万条消息,RabbitMQ的吞吐量是每秒几万条,但Kafka的配置,维护比较复杂,相对RabbitMQ来说就简单很多,同样满足需求的前提下,RabbitMQ是不错的选择。
消息队列选型时,需要特别关注两件事:
-
业务最重要的几个特点
-
比较消息队列的细节
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通