kafka入坑

高级消费者

提供消费消息的方法而屏蔽底层细节;高级消费者在zk特点分区存储最后的偏离(kafka启动时准备完毕),全局kafka集群消费群体,任何老逻辑的消费者应该被关闭然后运行新的代码,当一个新的进程拥有相同的消费者群的名字,kafka新增进程的线程来消费topic且引发“重新平衡”:分配现有分区到all可用线程

  • 如果你提供比在topic分区多的线程数量,一些线程将永远不会看到消息。
  • 如果你提供的分区比你拥有的线程多,线程将从多个分区接收数据。
  • 如果你每个线程上有多个分区,对于你以何种顺序收到消息是没有保证的。举个例子,你可能从分区10上获取5条消息和分区11上的6条消息,然后你可能一直从10上获取消息,即使11上也拥有数据。
  • 添加更多的进程线程将使kafka重新平衡,可能改变一个分区到线程的分配。
     

清理和异常处理:

 kafka每次处理不会立即更新zk的偏移值,这段时间内消费者可能已经消费些消息但未提交到zk:重复消费

broker失败重新选举leader也导致重复消费

作者:半兽人
链接:http://www.orchome.com/553
来源:OrcHome
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

震惊了!原来这才是kafka!https://www.jianshu.com/p/d3e963ff8b70

kafka对外使用topic的概念,生产者往topic里写消息,消费者从读消息。为了做到水平扩展,一个topic实际是由多个partition组成的,遇到瓶颈时,可以通过增加partition的数量来进行横向扩容。单个parition内是保证消息有序。

每新写一条消息,kafka就是在对应的文件append写,所以性能非常高

流程

produce都是批量请求,会积攒一批,然后单独线程一次性发送,不是调send()就进行立刻进行网络发包。

  有key则哈希key,相同key去一个partition(扩展了partition量则不能保证),无key则round-robin选partitioin

high level api 做了很多事,offset 路由都不用管,想自力更生的用simple api,自己动手 自己负责

partition:选举分配

多个副本,kafka为partition选leader,该partition请求的实际操作均是leader,leader歇菜后,所在的broker上的partitiion重新选举leader(不会自动复制保存副本数)

 kafka使用zk在broker选出controller,用于partition分配和leader选举

分配:

1.n个broker和待分配的partition排序

2.第i个partition分配到第(i mod n)个broker上(leader)

3.第i个partition的第j个replica分配到第(i+j)mod n个broker上

leader容灾

controller在zk的/brokers/ids节点上注册watch,broker宕机后controller为受影响的partition选出新leader,controller从zk的/brokers/topics/[topic]/partitions/[partition]/state中,读取对应的partition的ISR(in-sync-replica已同步副本)列表,选出leader

更新zk,发送LeaderAndISRRequest给受影响的broker,让他们改变

如果ISR列表空,据配置随便选个replica做leader,或干脆partition歇菜,如果ISR列表有机器但也歇了,等ISR活过来

多副本同步

服务端follower从leader批量领取数据同步,生产者觉得具体的可靠性

acks what happen
0 发送over,不关心结果,may丢数据
1 写leader成功返回,其他replica通fetcher同步,所以kafka是异步的,主备切换可能丢数据
-1 等isr里all机器同步成功才返回成功,强一致,不丢数,ISR<min.insync.replicas,返不可以

ISR列表中机器会变,据配置replica.lag.time.max.ms 指定时间没有同步,ISR列表剔除

ISA选出leader,follower把日志中上一个高水位后的记录去掉,从leader取新数据,因为新的leader选出来后 follower上数据may比leader新so要截取

    高水位:对于partition和leader,all的ISR中都有最新一条记录,消费者最多只能读到高水位

    从leader角度说高水位的更新会延迟一轮,新写入一条新信息,ISR中broker都fetch了,单ISR的leader只在下一轮的fetch中才告诉leader:某些情况下,kafka会丢数据 so和主备数据不一致 0.11使用leader epoch代替高水位

消费

订阅topic以消费组来订阅,一个partition只能被组内一个消费者消费,但可同时被多个组消费,组内消费者如果比partition多,个别消费者一直空闲

offset

组消费partition,保存offset记录消费到哪了,0.10后kafka把offset保存在_consumeroffsets topic的topic中,写进消息的key由groupid,topic,partition组成,value是偏移量offset,清理策略是compact,保留最新的key其余删掉,一般每个key的offset缓存在内存,查时不遍历partition,无缓存 第一次遍历partition建立缓存,查询返回

确定comsumer group位移信息写入_consumers_offsets的哪个partition,具体计算:

__consumers_offsets partition =
           Math.abs(groupId.hashCode() % groupMetadataTopicPartitionCount)   
//groupMetadataTopicPartitionCount由offsets.topic.num.partitions指定,默认是50个分区。

分配partition-reblance

生产过程中broker要分配partition,消费过程也要分配partition给消费者

   broker中选了一个controller,消费也要从broker选一个coordinator,用于分配partition

1,选coordinator

     看offset保存在哪个partition

     该partition leader所在broker便是被选定的coorinator

2,交互流程

     consumer启动或coordinator宕机,consumer任意请求一个broker,发送consumermetadaterequest请求,broker选出该consumer对应coordinator地址

     consumer发送heartbeat请求给coordinator,返回illegalgeneration说明consumer信息是旧的需重新加入,进行reblance,返成功那么consumer从上次分配的partition继续执行

3,reblance

      consumer给coordinator发送joinGrouprequest请求

      其他consumer发heartbeat,coordinator告诉他们要reblance,其他consumer发送joingrouprequest

      all记录在册的consumer发了joingrouprequest后,coordinator在consumer随便选leader,会joingrouprespone,告诉consumer的身份,leader会把follower的信息带给她,根据这些信息分配partition

      consumer向coordinator发送syncgrouprequest,leader的syncgrouprequest包含分配情况

      coordinator回包,把分配情况告诉consumer,包含leader

当partition或消费者数据变化时,进行reblance



作者:123archu
链接:https://www.jianshu.com/p/d3e963ff8b70
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

发布了431 篇原创文章 · 获赞 155 · 访问量 44万+

猜你喜欢

转载自blog.csdn.net/ma15732625261/article/details/88666475
今日推荐