kafka在总结

首先kafka是一个消息中间件,使用kafka主要是也进行热点时间段的数据肖锋,和系统间解耦,更多的场景是用作类操作日志的记录。
那么kafka分3大块,生产者,消费者,和存储引擎broker。
首先说生产者,生产者向kafka的具体topic-partition推送数据的时候ack机制有3个级别;
如果不关心消息丢失情况则设置为0,leader-partition同步数据后发送ack则设置为1,如果要等到isr列表完全同步数据后返回ack则设置-1;
这里提到了isr队列,isr队列是用来选举leader-partition的,kafka中提到了消息同步耗费时间的配置,如果超过设置的时间阈值则直接从isr列表移除掉;
(当然在早期的0.9版本中还有一个设置消息差距值的参数,如果超过该设置的差距值则从isr移除,那么这个值实际很难掌握的,因为kafka的数据输入量其实很多场景是没法准确预估的,这样就会造成,有些partition就会频繁的移入移除,这样做既消耗了性能实际又是没有意义的,因为没办法真正的表现出有真实问题的partition)
那么在生产者中,实际有一个幂等性的ID做限制,不过这种操作是限制在session内的,而且是同一个partition为目标的。因为他是以《PID,patitionId,数据id》作为依据,一旦生产者重启该id其实是会重新计算的;
(不过话说回来了,这样做是没有意义的,因为即使生产者做好了限制,如果消费者端出现了offset提交问题,一样会出现重复数据,所以一些场景这种kafka本身的幂等效果并不明显;通常还是要根据业务情况自己在处理业务数据时进行唯一id的限制。)
那么生产者将数据推向partition,partition实际是存储在不同broker中的,而且kafka默认的分配partition策略是根据broker的标号进行取模分配的,所以partition分配后会均匀的散落在不同的机器;
说到这里kafka为什么说吞吐量比较高的呢?就是因为它能够很容易的动态增加broker节点的数量从而增加partation的数量,partition默认写数据的时候是按照segment分段写的,当触发log大小的配置阈值时,开始拆分segmentLog,那么数据写入时是按“磁盘顺序写”而非随机写,节省了寻址的开销,记得linux磁盘顺序写每秒可达600M,而随机写仅仅100k/s,而且在读写数据时使用了堆外内存的方式,减少了用户态内核态的数据copy消耗,而且在kafka使用io多路复用机制进行数据通信。(说下io多路复用的典型应用,select在内核态的表现详细介绍下)
那么刚才说到了kafka的数据segement存储,不得不说下log和index文件了。log文件相当于针对数据存储的偏移量和数据本身存储进行了描述,而且index文件存储的是数据的索引,主要存储了数据的“偏移量”也就是应该从log的哪个地方来读取,还有存储了“数据长度”,也就是需要读取多少个字节。segment的文件划分也是按照当前数据的offset进行命名的,在这可以看出topic只是逻辑上的概念而实际存储数据的是partition。新版本又增加了timeindex按照时间的文件索引。

那么broker存储数据是为了消费者用来消费的,消费者拉取数据的时候是按照消费者组去保存offset的,也就是说当你处理完数据后需要告知kafka的consumer_offset进行修改,这样消费的数据才不至于重复,说到这里说下之前遇到的一个问题吧,由于设置消费者的session阈值为1秒,但当时出现了1秒内没有处理完数据的情况,由于老版本的kafka心跳线程和数据处理线程是同一线程,所以超时后会出现消费者被下线并处rebalance,不断的发生rebalance导致数据挤压很多。
升级kafka版本后,心跳线程和任务处理线程分离,并且offset改为同步手工提交,那么这个时候不会再出现因consumer频繁变化而发生rebalance从而导致数据挤压的情况。

 

 

kafka  partation和consumer匹配策略:

设Consumer总数为c,Partition总数为p,那么RangeAssignor会根据
p / c的结果得出一个区间值a
余数值p % c,记为b
从第一个Consumer开始顺序分配,前b个Consumer分配连续的(a + 1)个Partition,后(c - b)个Consumer分配连续的a个Partition.
这种策略是按照范围来尽量平均分配Partition的,如果不能均分,那么排在前面的Consumer会被多分配1个Partition。

posted @ 2020-09-16 16:16  soft.push("zzq")  Views(145)  Comments(0Edit  收藏  举报