Kafka(二)配置,offset维护,消息索引和选举

生产者配置

首先我来说一下Kafka在Java代码中的配置,通过这些配置就能够更好得理解Kafka的原理。我们在使用是需要对Producer和Consumer添加Properties配置。对于Producer,最开始当然是我们要连接的Kafka的IP了,这个IP其实无所谓是否是自己今天的主题的那台,因为最终都是要找zk要topic的分区信息的,但在集群下,最好还是把所有IP都写进去,防止挂了。然后是设置消费者的ACK机制,他有4个选项,分别是0,1,-1,all。他的含义是等待几台Kafka将消息持久化完写入日志才发下一条消息。若为0那么此时的Kafka的性能是最高的,但是也最容易丢失消息,因为不会管broker是否收到,这种在我们记录日志的时候可以使用,因为丢几条消息无伤大雅。若为-1或all,那么此时Kafka性能最差,但可靠性最高,因为需要等到分区的所有副本都持久化完才发下一条,这种适合涉及到金额时使用。若为1那么是折中方案,针对有多个broker的集群情况,至少等待leader副本将消息持久化完。若leader刚写完并发送ack,还没来得及同步到副本时就挂,新的副本成为leader后就会消息丢失。除此之外,我们还可以通过参数来自定义等几台后发ack,联想一下zk,zk只有一种方案,那就是等半数以上的副本节点同步成功就会告诉客户端ack。下一个参数是重发配置,是用来发送失败的重试,可以保证消息发送的可靠性,但也可能造成消息重复发送,比如网络抖动,其实已经发到了,却认为没有发到。消息重复会在以后总结。关于重试需要设置重试的间隔,重发之间也是要等待的。然后是消息的本地缓存,我们的消费者在不可能每次产生一条消息就往partition发一条消息,虽然是长连接,但是IO次数太多了,所以我们在本地会有一个Buffer,我们产生的消息都会放在Buffer中,Buffer的大小也可以设置,Buffer只是用来存产生的消息,真正的发消息是靠的Batch,一个Buffer设置多个batch,当batch满后,才一次性发送,batch不满就不发。不满不发会带来一个问题,消息特别少,装不满,会一直等,此时我们就需要设置一个参数叫batch的等待超时时间,设置为10ms,那么,就算batch不满,也还是会发送。至此,我们的Producer就设置好参数了,我们可以用它的send方法来发送消息了,而消息也是被封装过的,封装为ProducerRecord,他里面除了常规的topic,partition,value外,还有一个key属性。key是干啥用的呢?他是用来在没有指定partition的情况下,来确定分发到哪个partition的,类似于我们的redis的槽位slot机制,底层就是hash后对partition数取余。若没有key,也没有partition,那么就轮询给分区发消息。关于Producer的发送,我们是有两种同步和异步两种方式的,其中同步用的不同,而在异步中,我们肯定要有回调函数,回调参数是不分成功回调和失败回调的,回调函数的参数有元信息和异常信息,我们可以从其中的元信息拿到消息发往的topic,partition和offset偏移量。对于异常信息,若他为null,说明没有异常,用他来区分成功和失败。

消费者消费者

对于消费者,肯定也是先IP,然后就要配置消费者的消费者组名了,就是用来控制单播和多播的。消息者在消费完消息后,肯定是需要告诉partition消费后的offset的,而offset有两种方式,要么是我们在消息执行完后调用commitSync这个api来发offset,要么是配置为自动提交,配置好自动提交的间隔时间,但自动提交也是有问题的,若消费者挂了,那么两次提交之间的消息会被重复消费。提到了offset,就来说说他的维护,所谓的提交,其实就是将offset发送到kafka的_consumer_offset主题上,他也就是一个普通的主题,默认给了50给分区,且平均在多个broker上,所以能支持高并发。写入的时候,提交过去的时候,key是consumerGroupId+topic+分区号,value就是当前offset的值,用他来维护offset,这里也体现了不同的Group是多播的,因为他的key中是包含GroupId的,所以多个Group消费同一个消息是互不干扰的,体现在各自维护不同的offset,单播就不行了。接着说客户端的参数,因为consumer和broker之间是长连接,所以理所因当有心跳机制,自然要配置心跳的频率和心跳多少秒不发就认为挂掉的时间。我们还能配置poll的时间参数,如果两次poll操作间隔超过了这个时间,broker就会认为这个consumer处理能力太弱,会将其踢出消费组,将分区分配给别的consumer消费。至此,消费者配置完了,我们在使用时,如果订阅的是topic,那么就是轮询其分区来消费,如果订阅的是partition,那么就是定分区来消费。且消费时还能回溯消费,从0消费,或者指定offset来消费。甚至还能指定时间点来消费,用途是查特定时间的日志。他的拉取消息poll还是挺复杂的。

消息存储结构

再来说一下消息的存储结构,当我们打开kafka的某个分区目录是,可以看到三个文件,分别是.log,.index和.timeindex文件。其中.log文件就是用来存offset和消息体的,而index文件就是用来存索引的,但和mysql的索引不一样,因为offset是有顺序的,所以可以用二分,其索引的机制是.log文件每满4k,就存一个offset到index文件中,然后用他来二分查找到一个范围,然后逐条找消息。而.timeindex就是还记录了时间戳,用来支持消费者按时间消费的api的。

选举

最后来说一下contoller和replication的选举。什么是controller呢?controller相当于是broker集群中的leader,作用是帮助replication副本来选举出leader和扶着管理整个集群中的副本的状态,比如当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有broker更新其元数据信息。那Controller是怎么选举的呢?当多个broker启动时会在zk中创建一个目录controller,谁执行该命令成功,谁就是controller,且是临时节点,也就能做到检测下线,下线后自动删除,启动时还会监听/brokers/ids,一旦controller节点挂了,就被其他节点感知,再都发送创建controller的命令,谁成功,谁是新的controller。

最后说一下副本怎么选举出leader,靠controller来选举,这个controller能够感知到挂了的broker的leader(zk告诉他的),在zk类元数据知道他的副本,然后选举。结合该分区的Replicas和Isr信息从副本中找,第一个没有挂掉的节点,就是新的leader。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值