kafka学习(第二部分)

  1. 问题:producer将消息提交给kafka集群后,是在什么时候完成消息删除的?

答:producer将消息提交给kafka集群后,kafka集群会向producer发送ack信息。然后producer会依据配置的acks判断是否删除消息。

acks属性可以配置的值是:all、-1、0、1。

以下为猜测内容,没看过具体源码。

  • producer将消息发给leader的请求,会直接返回一个ack=0的通知。

  • leader将消息完成本地持久化后,会向producer发送一个ack=1的通知。

  • leader判断所有follower副本也完成持久化后,会再次向producer发送一个ack=-1的通知。

  • producer删除数据的时机就是以上三个时刻,依据acks的配置执行删除。

  • 当producer在指定时间没有收到ack的话,会启动重新发送流程。

  1. 问题:producer向kafka集群提交的过程中,集群是如何保证一致性的?

答:broker启动配置中有一项:min.insync.replicas,是配置多少副本完成持久化后,可以向producer发送ack=-1通知的。

合理配置该属性可以优化以下两方面的内容:

  • 当副本数比较多时,可以降低集群一致性要求,加快消息的传输速度。

  • 当出现极端情况,没有足够的副本时,通知生产者集群不能接收数据,防止出现数据丢失。

但需要注意可能出现的问题:

  • 如果你只有2个副本,而这个值配置了3会造成producer生产的消息一直推送不成功。提示副本数不够。

  1. 问题:acks=-1时判断的副本是所有副本吗?

答:不是,是所有在ISR中的副本。这里涉及到两个在kafka中的概念ISR和OSR。

  • ISR,in sync replicas,是可以同步副本集合,就是可以及时从leader副本复制信息的副本,包括leader自己。

  • 及时有两种判断方式:数据差距条数和数据同步延迟时间,超过阈值就会将副本放到OSR中。

  • 数据同步延迟时间,是比较leader数据接收时间和follower请求leader获取数据的时间。因为集群内部各副本之间的同步是通过follower向leader发送fetch请求完成的。

  • 该值得配置项是replica.lag.time.max.ms,单位是ms,默认值是10000。

  • OSR,OSR是out sync replicas,可以理解为不在ISR中的副本。

  • ISR在kafka中是一个重要的集合,leader也是从ISR中选出来的。

  • 可以通过在服务器中查看主题信息看到。

  • 命令如下:

bin/kafka-topics.sh --zookeeper zookeeper:2181 --describe --topic test
  • 响应结果如下:

  • 其中第一行是Topic信息,包括名称、ID和分区数量。

  • 下面的表格信息,写的是各个分区的情况。

  • Leader表明的是,leader分区所在的broker。

  • Replicas表明各分区副本所在的broker。

  • ISR,in sync replicas,可以同步副本集合。

  1. 问题:可不可创建超过broker数量的副本数?

答:建议小于等于broker数量,保证每一个broker有最多一个副本,存在多个没意义。

  1. 问题:数据是如何从leader同步到follower的?

答:follower会定时从leader中同步(FETCH)数据。

  • 这里需要先说明3个概念,LEO、HE、Remote LEO。

  • partition中的数据储存可以理解为一个数组+三个指针。一个是可以开始写的位置,一个是可以读的最后位置。当然还有当前位置。

  • LEO,是last end offset,是最后一个结束的偏移量,也就是可以继续写的位置,这个每写入一个数据会自动+1。

  • HW,是high watermark,就是可以读的最后位置。

  • Remote LEO,就是在leader中储存的follower中的LEO。

  • 同步数据的过程按照如下进行的:

  • follower先向leader发出一个FETCH请求,请求中会带自己的LEO。

  • leader接到请求后,会完成两个操作。

  • 其一是完成HW的更新,将follower的LEO储存在Remote LEO中,然后比较自己的HW和Remote LEO,较小的就是leader的HW。

  • 其二是完成数据同步,比较follower的LEO和leader自己的LEO,如果一致表明数据一致,如果不一致将多的一部分数据返回给follower。

  • follower接到响应后,会完成两个操作。

  • 其一是完成数据同步,这里有个问题,如果leader的HW比follower的LEO小,follower的LEO会变更为leader的HW,相应的数据会视为丢失。

  • 其二是完成HW的同步。

  • 按照上述流程不断重复,follower每fetch一次都会同步一次数据和HW,但HW的完全同步需要在没有数据更新的下一次同步过程中完成。

  1. 问题:数据同步的过程中可能出现那些问题?新版是如何解决的?

答:可能出现数据丢失和数据不一致。

  • 造成的原因有两部分:

  • 其一是follower成为leader后,会将LEO同步为自己的HW。

  • 其二是当原先的leader重启,变成follower后同步数据,会将LEO和HW设定为新leader的HW。

  • 核心问题都是由于follower被选举成leader时会将LEO和HW设定为一致造成的。如果HW未及时同步,会失去HW和LEO之间的数据。

  • 解决方案是在新版本中,加入了epoch的概念。

  • 在新版本中,follower被选举成leader时不会将LEO和HW设定为一致,而是将HW和LEO设定为一致,并记录纪元信息:迭代次数和迭代的起始位置。

  • 原先的leader重新启动成为follower同步数据时不是直接将LEO和HW设为一致,而是先同步纪元信息,再判断比自己当前纪元大一的纪元的起始位置,判断自己的LEO和该起始位置,将二者的较小值设定为HW和LEO。

  • 但该解决方案仍然存在数据不一致的可能性。

  1. 问题:kafka对消息处理的承诺有那些?

答:至少一次,最多一次,精确一次。

  • 至少一次是表明消息保证消息一定可以从生产者传递到kafka集群并被持久化,但不能保证只传递了一次。也就是说保证数据不丢失,但不能保证不重复。

  • 需要通过acks=all,副本数量大于2,最小同步部分数量大于2来实现的。

  • 最多一次是表明消息从生产者发出了,但kafka不一定接到或者能够及时完成持久化。也就是数据一定不重复,但不能保证数据不丢失。

  • 设定acks=0。保证只发送一次。

  • 精确一次在至少一次的基础上保证消息只消费了一次。

  • 需要配合业务实现消息的幂等性。

  1. 问题:kafka为保证幂等性做了那些工作?是否完全保证幂等性?

答:kafka在没一个消息中存放了两个值组成的key,来保证该消息只持久化一次。但并不能保证一定幂等性。

  • kafka在producer提供了两个参数:ProducerId和Sequence Number。

  • ProducerId是没有producer启动的时候,kafka提供的。

  • Sequence Number是针对每一个分区的单调自增的值。

  • 不能完全保证幂等性。

  • 首先是这个是针对消息的,如果数据出现重复处理不了。

  • 其次当出现重分区时,消息可能发向不同的分区。

  • 最后是生产端重启,producerId会更新。

  • 幂等性配置参数是:enable.idempotence,配置端是生产者,默认是true,开启。

  1. 问题:kafka说的可以保证分区中的数据有序,是如何做到的?

答:目前是基于Sequence Number和max.in.flight.requests.per.connection。

  • broker持久化的时候是按照SeqNum来完成持久化的,也就是说如果seqNum是1的消息没有完成持久化,seqNum是2的值即使接到也不会完成持久化,一定需要等消息1不断重试到完成持久化才可以继续完成消息2的持久化。

  • 这里涉及到两个流程,一个是producer发送消息,一个是broker持久化消息。

  • producer发送消息,先将消息放到发送队列,满足发送条件后启动send发送,然后发送到网络连接器,在网络连机器上也可以缓存发送的消息,缓存数量是max.in.flight.requests.per.connection属性指定的。网络连接器会按照顺序逐个发送,如果发送失败会不断重试到发送成功,之后再继续发送下一条数据。

  • broker持久化也是按照顺序持久化的,是为了加快读取速度。

  • 其实数据从硬盘中读取和从内存中读取耗费的时间差距不大,多出来的时间主要是寻址时间。

  • 如果不是顺序持久化,而是持久化后再排序,这个储存会导致页裂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

田秋浩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值