Kafka 分布式消息队列

Kafka 分布式消息队列

Kafka 集群是一个高可用的消息队列。

对于分布式系统,满足 CAP定理 ,只能同时满足以下三项中的两个:

其中,如 Zookeeper 保证 CP (如果刚好是 master 节点网络断开 ,会触发选举,这期间是不可用的),Eureka 保证 AP (微服务查到的信息可能不是最新的)。

而 kafka 保证的是 CA,基于 ISR (In-Sync Replica)的动态复制方案,如果 follower 网络故障,那么将被 leader 从ISR中移除,除非追上数据,不然不能加入集群。

数据传输的事务定义通常有以下三种级别:

生产者 (KafkaProducer)

发送消息有三种方式

acks 参数指定了重发的行为

acks 行为 后果
0 生产者在成功写入悄息之前不会等待broker响应 可能会数据丢失
1 只要集群的 leader 节点收到消息,生产者就会收到一个来自服务器的成功响应 如果 leader 挂掉,可能会数据丢失
-1/all 会等所有的 follower 的副本受到数据后成功响应,请求会被保存在一个叫作炼狱的缓冲区里,直到首领发现所有跟随者副本都复制了消息,晌应才会被返回给客户端 保证数据不会丢失

序列化器有 Json、Avro、Thrift、protobuf 等多种方案

消费者 (KafkaConsumer)

Kafka 消费者从属于 消费者群组 。一个群组里的消费者订阅的是同一个 主题( Topic ),每个消费者 接收主题一部分 分区 ( Partition )的消息。

消费者数量不能多于消费者数量,多的消费者会闲置。多个消费者群组可以订阅同一个主题,群组独立且分开计算。

分区的所有权从一个消费者转移到另一个消费者,这样的行为被称为 再均衡 ,会造成整个群组一小段时间的不可用 。

提交偏移量有多种方式

还要注意如何优雅地退出循环的问题,以及反序列化。

分区 ( Partition )

Kafka 使用 zookeeper 来维护集群成员的信息,控制器使用 epoch 来避免 脑裂 问题。元数据可以用来分区选首领,偏移量也是元数据。

消费者只能看到已经复制到 ISR 的消息。

Kafka 使用零复制技术向客户端发送消息一一也就是说, Kafka 直接把消息从文件(或者更确切地说是 Linux 文件系统缓存)里发送到网络通道,而不需要经过任何中间缓冲区。

分区副本数量 = 分区的主题 * 复制系数 ,broker 平均分配分区副本和 leader ,同一主题的分区副本不会分到同一个 broker 上。

Partition 文件下有多个 segment (默认大小 1g)。如果达到设置大小时,会滚动一个新的 segment 并且以上一个 segment 最后一条消息的偏移

可以制定清理策略。

可靠的数据传递

需要保证ACID。

broker 通过禁止不同步的副本成为首领 ( unclean.leader.election.enable=false ),保证一致性。通过最少同步副本的设置 ( min.insync.replicas ),保证可靠性 。

生产者可以设置重试参数,在遇到可重试错误时能够保持重试 ,这里需要注意幂等性。

消费者要注意提交了偏移量却未能处理完消息。以及重试问题,可以提交最后一个处理成功的偏移量,然后把还没有处理好的消息保存到缓冲区,或者错误写入一个独立的主题。

在消费者解决最少一次和精确的一次的问题时,可以把结果写到一个支持唯一键的系统,也就是幂等性写入。

Kafka Connect 是 kafka 的一个客户端 API,可保证

Kafka Streams 可以做流式处理,事件流模型 具有以下属性