Kafka 总结

本文详细介绍了Kafka的分布式特性,包括高可用性、主从集群、高吞吐量和分布式消息持久化。讲解了Kafka的Zookeeper注册中心、Leader容灾、Producer集群的发送机制、Broker的主从同步机制、Consumer的分区分配和拉取策略。还探讨了Kafka的性能优化、幂等性实现、消息重复与丢失的处理,以及与ES数据同步的方法。文章深入剖析了Kafka的高性能原因,如顺序读写、零拷贝、分区分段+索引等设计。
摘要由CSDN通过智能技术生成

简介:
Kafka是一个分布式系统:它以集群的方式运行,可以灵活伸缩(分区),在内部通过 复制数据提升容错能力和高可用性 ,  高可用(主从集群),高吞吐(分区分段+索引,顺序读写,0拷贝,批量写),分布式消息持久化(文件系统),集群部署的消息中间件。

0.9版本之前offset 存储在zk,0.9版本之后offset存储在本地

 

 

注册中心 zookeeper集群

 

1.注册中心,producer,broker,consumer  注册 和 心跳 ,

2.topic 和 partition 等 meta 数据;

3.还负责 broker 故障发现,partition leader 选举,负载均衡等功能

 

leader容灾
leader的节点监听:controller会在Zookeeper的/brokers/ids节点上注册Watch,一旦有broker宕机,它就能知道。
读取对应partition的ISR(in-sync replica已同步的副本)列表,选一个出来做leader。

Kafka的Leader选举是通过在ZooKeeper上创建/controller临时节点来实现leader选举,并在该节点中写入当前broker的信息 {“version”:1,”brokerid”:1,”timestamp”:”1512018424988”}
利用ZooKeeper的强一致性特性,一个节点只能被一个客户端创建成功,创建成功的broker即为leader,即先到先得原则,leader也就是集群中的controller,负责集群中所有大小事务。当leader和ZooKeeper失去连接时,临时节点会删除,而其他broker会监听该节点的变化,当节点删除时,其他broker会收到事件通知,重新发起leader选举。

 

producer 集群

 

发送消息方式:

1.直接发送消息 acks = 0

2.异步发送消息 acks = 1  这意味着producer在ISR中的leader已成功收到数据并得到确认。如果leader宕机了,则会丢失数据。

3.同步发送消息 acks = all (-1) 

配合min.insync.replicas使用,控制写入isr中的多少副本才算成功,producer需要等待ISR中的所有follower都确认接收到数据后才算一次发送完成,可靠性最高。但是这样也不能保证数据不丢失,比如当ISR中只有leader时

 

发送机制

0.有key  hash(key)% partitionSize, 没有就轮询

 

1.batch.size默认值是16KB,凑够16KB的数据才会发送

2.linger.ms  batch最大的空闲时间

但是消息并不是必须要达到一个batch尺寸才会批量发送到服务端呢,Producer端提供了另一个重要参数linger.ms,用来控制batch最大的空闲时间,超过该时间的batch也会被发送到broker端。

3.max.in.flight.requests.per.connection"这个参数设置的值(默认是5)  消息顺序性 

就是这5条消息其中的一条发送失败了,如果进行重试,那么重发的消息其实是在下个批次的,这就会造成消息顺序的错乱

发送多少条消息后,接收服务端确认,比如设置为1,就是每发一条就要确认一条,设置为5就是,发送5条消息等待一次确认

 

 

4.buffer.memory 消息缓冲池默认值32MB

sender 来不及发送,并发太快,线程阻塞 max.block.ms默认值30000ms(30秒),生产者会抛出超时异常。线程无法释放,很快tomcat就会没有线程可用

Sender线程来不及把消息发送到Kafka,当生产者的发送缓冲区已满(producer 发送消息太快),这时候就会线程阻塞。阻塞时间达到 max.block.ms默认值30000ms(30秒) 时,生产者会抛出超时异常。线程分分钟就会全部被阻塞,web容器在没有可用线程时收到的请求一般还会存放在队列中等待响应,线程得不到释放意味着内存同样无法被释放,所以很快内存就溢出了。

5.批量发送机制

Accumulator 负责 消息按照每个分区进行分批, sender线程会去遍历 分区的每个批次的消息 去发送

 

Kafka中producer的幂等是怎么实现的

kafka 会维护一个 producer 的pid 对应 partition的分区  的一个序列号,这个序列号自增

小于 就丢弃,大于直接报错(说明消息丢失)

为了实现生产者的幂等性,broker 端会在内存中为每一对 <PID,分区> 维护一个序列号,对于收到的每一条消息,只有当它的序列号的值(SN_new)比 broker 端中维护的对应的序列号的值(SN_old)大1(即 SN_new = SN_old + 1)时,broker 才会接收它。如果 SN_new< SN_old + 1,那么说明消息被重复写入,broker 可以直接将其丢弃。如果 SN_new> SN_old + 1,那么说明中间有数据尚未写入,出现了乱序,暗示可能有消息丢失,对应的生产者会抛出 OutOfOrderSequenceException,这个异常是一个严重的异常,后续的诸如 send()、beginTransaction()、commitTransaction() 等方法的调用都会抛出 IllegalStateException 的异常。

 

producer 性能优化的设计

 

1.增加batch.size

2.linger.ms(消息滞留时间),启用压缩  LZ4,关闭重试

3.buffer.memory 缓存池  避免内存溢出 发送消息线程阻塞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值