上一篇文章简要介绍了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 的整体吞吐量。

传统模式下需要在内核空间与用户空间来回切换

kafka选举策略 kafka主节点选举_零拷贝

图片来源于网络

零拷贝(Zero-copy)技术指在计算机执行操作时,CPU 不需要先将数据从一个内存区域复制到另一个内存区域,从而可以减少上下文切换以及 CPU 的拷贝时间。

Linux 2.4+ 内核通过sendfile系统调用,提供了零拷贝,零拷贝模式下网卡与文件的数据传输可以在内核空间完成。

kafka选举策略 kafka主节点选举_消息发送_02

图片来源于网络


4 选择Kafka还是RabbitMQ?

消息顺序

RabbitMQ和Kafka都可以处理按顺序消费消息

  • 一个队列对应一个消费者,消费者端关闭autoack,每次只消费一条信息(prefetchCount=1),处理过后进行手工ack,然后接收下一条消息。
  • 消息发送到同一个分区,一个消费者,内部单线程消费。

消息路由

根据消息内容或者某种规则,将消息发送到不同的队列。RabbitMQ交换机和队列的绑定,通过配置很容易在服务层面实现这样的功能。但对于Kafka来说,不得不在业务层面来实现这样的功能,成本会高很多。

延时队列

RabbitMQ间接支持延时队列,可以通过死信交换机来实现,详细可以参考消息队列之RabbitMQ

kafka选举策略 kafka主节点选举_消息队列_03

Kafka不支持延时队列

保持消息

RabbitMQ消息被消费后会被删除,Kafka的消息会被持久化一个专门的日志文件里,不会因为被消费了就被删除,可以多次重复消费。

吞吐量

Kafka的吞吐量是每秒几十万条消息,RabbitMQ的吞吐量是每秒几万条,但Kafka的配置,维护比较复杂,相对RabbitMQ来说就简单很多,同样满足需求的前提下,RabbitMQ是不错的选择。

消息队列选型时,需要特别关注两件事:

  • 业务最重要的几个特点
  • 比较消息队列的细节