Kafka与ZooKeeper分手,真相令人震惊!

Kafka原先是强依赖于ZooKeeper的,没有ZooKeeper的话Kafka都无法运行。ZooKeeper为Kafka提供了元数据的管理,例如一些Broker的信息、主题数据、分区数据等等。在每个Broker启动的时候,都会和ZooKeeper进行交互,这样ZooKeeper就存储了集群中所有的主题、配置、副本等信息。

然而,Kafka后来抛弃了ZooKeeper,原因可能是多方面的。首先,ZooKeeper本身的设计就存在一定的问题。比如,ZooKeeper在选举时整个ZooKeeper无法对外提供服务,这在异常情况下可能导致选举服务失效。其次,软件架构都是演进的,之所以要变更那肯定是因为出现了瓶颈。具体到Kafka和ZooKeeper的关系,可能是Kafka在规模扩大之后,遇到了无法克服的性能瓶颈,因此选择了替换ZooKeeper。

Java基础面试题【分布式】Kafka

简述Kafka架构设计

  • Consumer Group:消费者组,消费者组内每个消费者负责消费不同分区的数据,提高消费能力。逻 辑上的一个订阅者。
  • Topic:可以理解为一个队列,Topic 将消息分类,生产者和消费者面向的是同一个 Topic。
  • Partition:为了实现扩展性,提高并发能力,一个Topic 以多个Partition的方式分布到多个 Broker 上,每个 Partition 是一个 有序的队列。一个 Topic 的每个Partition都有若干个副本(Replica),一个 Leader 和若干个 Follower。生产者发送数据的对象,以及消费者消费数据的对象,都是 Leader。 Follower负责实时从 Leader 中同步数据,保持和 Leader 数据的同步。Leader 发生故障时,某个 Follower 还会成为新的 Leader。
  • Offset:消费者消费的位置信息,监控数据消费到什么位置,当消费者挂掉再重新恢复的时候,可以从 消费位置继续消费。
  • Zookeeper:Kafka 集群能够正常工作,需要依赖于 Zookeeper,Zookeeper 帮助 Kafka 存储和管理 集群信息。

Kafka在什么情况下会出现消息丢失及解决方案

消息发送

  1. ack=0,不重试

producer发送消息完,不管结果了,如果发送失败也就丢失了。

  1. **ack=1,leader crash **

producer发送消息完,只等待lead写入成功就返回了,leader crash了,这时follower没来及同步,消 息丢失。

  1. unclean.leader.election.enable 配置true

允许选举ISR以外的副本作为leader,会导致数据丢失,默认为false。producer发送异步消息完,只等待 lead写入成功就返回了,leader crash了,这时ISR中没有follower,leader从OSR中选举,因为OSR 中本来落后于Leader造成消息丢失。

解决方案

  • 配置:ack=all / -1,tries > 1,unclean.leader.election.enable : false

producer发送消息完,等待follower同步完再返回,如果异常则重试。副本的数量可能影响吞吐量。

不允许选举ISR以外的副本作为leader。

  • 配置:min.insync.replicas > 1

副本指定必须确认写操作成功的最小副本数量。如果不能满足这个最小值,则生产者将引发一个异常(要么是 NotEnoughReplicas,要么是
NotEnoughReplicasAfterAppend)。

min.insync.replicas和ack更大的持久性保证。确保如果大多数副本没有收到写操作,则生产者将引发异 常。

  • 失败的offset单独记录

producer发送消息,会自动重试,遇到不可恢复异常会抛出,这时可以捕获异常记录到数据库或缓存,进行 单独处理。

消费:

先commit再处理消息。如果在处理消息的时候异常了,但是offset 已经提交了,这条消息对于该消费者来 说就是丢失了,再也不会消费到了。

broker的刷盘:

减小刷盘间隔

Kafka中zk的作用

/brokers/ids:临时节点,保存所有broker节点信息,存储broker的物理地址、版本信息、启动时间 等,节点名称为brokerID,broker定时发送心跳到zk,如果断开则该brokerID会被删除

/brokers/topics:临时节点,节点保存broker节点下所有的topic信息,每一个topic节点下包含一个固 定的partitions节点,partitions的子节点就是topic的分区,每个分区下保存一个state节点、保存着当 前leader分区和ISR的brokerID,state节点由leader创建,若leader宕机该节点会被删除,直到有新的 leader选举产生、重新生成state节点

**/consumers/[group_id]/owners/[topic]/[broker_id-partition_id]**:维护消费者和分区的注册关系

**/consumers/[group_id]/offsets/[topic]/[broker_id-partition_id]**:分区消息的消费进度Offset

client通过topic找到topic树下的state节点、获取leader的brokerID,到broker树中找到broker的物理 地址,但是client不会直连zk,而是通过配置的broker获取到zk中的信息

简述Kafka的rebalance机制

consumer group中的消费者与topic下的partion重新匹配的过程 何时会产生rebalance:

  • consumer group中的成员个数发生变化
  • consumer消费超时
  • group订阅的topic个数发生变化
  • group订阅的topic的分区数发生变化

coordinator:通常是partition的leader节点所在的broker,负责监控group中consumer的存活, consumer维持到coordinator的心跳,判断consumer的消费超时

  • coordinator通过心跳返回通知consumer进行rebalance
  • consumer请求coordinator加入组,coordinator选举产生leader consumer
  • leader consumer从coordinator获取所有的consumer,发送syncGroup(分配信息)给到 coordinator
  • coordinator通过心跳机制将syncGroup下发给consumer
  • 完成rebalance

leader consumer监控topic的变化,通知coordinator触发rebalance

如果C1消费消息超时,触发rebalance,重新分配后、该消息会被其他消费者消费,此时C1消费完成提 交offset、导致错误

解决:coordinator每次rebalance,会标记一个Generation给到consumer,每次rebalance该 Generation会+1,consumer提交offset时,coordinator会比对Generation,不一致则拒绝提交

Kafka的性能好在什么地方

Kafka不基于内存,而是硬盘存储,因此消息堆积能力更强

顺序写:利用磁盘的顺序访问速度可以接近内存,kafka的消息都是append操作,partition是有序的, 节省了磁盘的寻道时间,同时通过批量操作、节省写入次数,partition物理上分为多个segment存储, 方便删除

传统

  • 读取磁盘文件数据到内核缓冲区
  • 将内核缓冲区的数据copy到用户缓冲区
  • 将用户缓冲区的数据copy到socket的发送缓冲区
  • 将socket发送缓冲区中的数据发送到网卡、进行传输

零拷贝

  • 直接将内核缓冲区的数据发送到网卡传输
  • 使用的是操作系统的指令支持

Kafka不太依赖JVM,主要理由操作系统的pageCache,如果生产消费速率相当,则直接用pageCache 交换数据,不需要经过磁盘IO

kafka对于Java开发很重要,这里本人整理了一份完整详细的资料,如果有需要的小伙伴,在下方留下评论!

UP整理文档不易!

有需要资料小伙伴,点赞三联!

评论区留言”求分享“

up会第一时间联系你哦!

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值