kafka 什么事kafka kafka是一个多分区多副本,依托于zookeeper搭建建的消息处理系统 特点 高吞吐 可持久化 水平扩展 结构 zookeeper 管理kafka的元数据,已经控制器选举等 topic kafka的消息存放以主题左区分,生产者将消息发送到特定的topci,consumer订阅此topic就可以小芬 consumer 消费者 consumer group 消费者组,消费者在消费kafka消息时候都会指定加入特定的消费者组,消费者组管理组内消费者消费topic的那些分区,一个分区只能由组内一个消费者消费 partation 分区,一个topic可以分未多个分区,当消息发送到topic的时候,具体落在哪个分区由一定的算法可得,消费者也可以指定消息落在哪个分区,或者自定义分区算法,分区在存储层可以看作一个追加的log,消息在追加到分区的时候都会分配一个表示offset,一次来保证消息在分区的顺序性,但是offset不能跨分区,也就是说kafka是保证分区消费的有序性,但不是主题有序 recilpac 对分区引入了副本机制,保证了高可用,副本会选举除leader,leader负责读写,副本负责fllowleader的数据 consumer 业务概念 AR 所有副本 OSR 消息为同步leader的副本 ISR 已经同步leader的副本 HW 高水位 LEO 带写入的吓一跳消息offset groupcoordinator 消费者组内的消费者消费对应的topic时候只会分配一对应的分区,其他同组消费者不能在消费这些分区,那么kafka是怎么动态的在消费者增加或者减少的情况下来分配同步这些分区应该由哪些消费者消费了,就是靠这个gruopconndior 如何选择groupcoordinato kafka内部维护了一个cunsumer_offesrt的topic,记录了gropu的小芬情况,默认是50个分区,3个副本,grooup记录的分区的leader在哪太broker,那么这个broker就是这个group的 rebalace 当消费者中心加入或者推出消费者组的时候,会发生在均衡,重新消费者分配分区的订阅关系 时机 消费者加入或者退出 消费者宕机 groupcondir重新选举 任意主题或者分区发生变化 策略 范围分配 轮询分配 尽量均匀以及jing'liang 消费者可以指定分区的分配策略给服务端,由一个参数 消费者可以指定消费哪个分区,consumer。seek 步骤 1:找到gruopconndior 2:消费者发送join、group请求 3:condrioton找到消费组中的leader并返回分区信息,cunsumerleader根据分区策略分配各个消费者的订阅情况,然后通过syncgroup请求同步给各个cunsumer 转让左使得消费者的分区订阅更加灵活,不由boker统一确定,同时如果让server分配,一旦需要新的分配策略,server集群要重新部署,这对于已经在线上运行的集群来说,代价是很大的;而让client分配,server集群就不需要重新部署了。 消费者可以指定消费哪个分区,consumer。seek Rebalance Generation 理解为版本号,每次rebalancegroup的版本号都会加一。当consumer由于网络原因或者延迟组设,group发生在均衡,然后consumer又正常接入提交offset,此时group发现consumer的版本号不对,那么consumer提交的offset相当与无效的数据 心跳机制 offset管理 cunsumer_offesrt存着hw,分区的last offset,consumer的消费lastoffset情况等,又consumer_offset这个主题管理 controller 其实相当于是分布式系统的中的细条这, 做哪些工作 集群broker管理 通过zooker的watch机制,每个borkerid都会在zookler注册节点,宕机或者增加时候,zoo客人会感知到,然后通知borekercontor做分区的冲平衡,或这leader重新分配 存在一个问题:初始leader跟分区是均匀的分配在集群中的,保证最大的复杂均衡跟分区可用性,当有集群下线的时候,分区leader跟副本可能会分配在同一台集群上,这个时候会给个broker增加二外的负担同时影响可用性等。当集群重新加入的时候需要对leader重新分配,有一个参数auto.leader.rebalance.enabled默认未true,kafka定期会对topci的分区进行选举,保证精良平衡,但是重新选举是leader然后副本重新fllow是有恨到的消耗的,所以该参数是否开启可以评估 创建主题删除主题,增加分配分区 选举分区leader 脑裂 对于分布式期系统中存在选举机制的情况下基本都会存在脑裂的问题 什么是脑裂:其实简单理解可以未,当某个节点被选举未leader,但是由于网络原因,跟其他几点有断站的端连,导致其他节点以为leader已经下线,并且重新选举了B未leadr,此时leaderA又重新加入,这个时候leaderA并不知道他已经不在是leadr,此时就会又两个leadr同时向集群中发送leadr的作用 如何避免脑裂:kafka是增加contorller的版本号,当每个borker作为contoorlepoch会递增,如果存在脑裂,那必有一方的epoch比较旧 ISR控制,延时多少内默认是同步的 有一个参数,max,lag producer发送原理 new KafkaProducer() new之后回创建一个kafakThread,kafkaThread是对sender的封装,实际运行sender,扫描reacodAccmutor是否有消息 调用send方法实际是RecordAccumulator的batchs中塞消息。核心数据结构是一个currentHashMAP,相同主题相同分区回被保存在一个batch里面 当sender扫描到recordAccmulator中有消息,则会通过kafkaadminclient发送消息到kafka集群中 发送成功则会返回一个recordMETAdATA,包含了返回的分区以及消息的偏移量等 如何保证kafka的幂等 发送方的幂等 有序发送 有序性的发送方 存在配置max.in.flight.requests.per.connection,表示客户端允许能够存在多个发送未响应的请求,发送方一般都会设置发送失败重试,当多个bacth发送,当发送失败后,消息会重新进入recod收集器,重新入recordAccumutator,的batch,此时可能会破坏消息的有序性,kakafa新增了一个enable.idempotence=true,当重发的时候会动态的将允许发送未响应的请求改为1同时让bacth需要较小的重新发送。只有按顺序发完,后续新增的批次才能发送 幂等 如果是单个生产者 客户端 在new proudcer,内部会为每个生成一个pid,对应的生产者发送的消息到对应的批次,都会生成一个序列号,类似于《pid,分区序列号》每次发送消息,序列号有序每次发送都是序列号jiayi 服务端 也会维护一个《pid,发到你去的数据结构》每次commit都会将序列号jia1。每次提交消息的时候只有sn_nwa=sn+old+1kfaka才会接收,如果sn_new



