kafka缓冲区,kafka补偿机制

  kafka缓冲区,kafka补偿机制

  卡夫卡为什么要设计缓冲池机制?乍一看,我觉得不知所措,我能理解。我直接跪下_wx630f055ce23fc的技术博客_博客

  在这篇文章里,我还会跟大家讲一个硬核的技术知识。通过Kafka内核源代码中的一些设计思路,来看看你设计Kafka架构的技术大牛。你是如何优化JVM的GC问题的?

  1.卡夫卡的客户端缓冲机制。首先我们要明确一点,就是客户端向Kafka服务器发送消息时,必须有内存缓冲机制。

  也就是说,消息会先被写入一个内存缓冲区,然后在一次网络通信中不会批量发送,直到多个消息形成一个批量。

  整个过程如下图所示:

  2.内存缓冲导致的频繁GC问题。所以这种内存缓冲机制的初衷其实就是把多个消息合并成一批,一个网络请求就是一批或者多批。

  这样每个网络请求都可以发送很多数据,避免一个消息一个网络请求。从而提高吞吐量,即单位时间内发送的数据量。

  但问题来了。你可以考虑一下。一批中的数据会被取出,打包在底层的网络包中,通过网络发送到Kafka服务器。

  然后呢?该批中的所有数据都已发送。现在批量的数据应该怎么处理?

  要知道,此时批处理中的数据还在客户端JVM的内存中!此时,从代码实现层面,我们会尽量避免任何变量引用这些批处理对应的数据,然后尝试触发JVM自动回收这些内存垃圾。

  这样通过不断的让JVM回收垃圾,可以不断的清理已经发送成功的那批,然后不断的腾出新的内存空间给后面的新数据使用。

  这个想法很好,但是实际上线运行的时候会出现一些问题。最大的问题是JVM GC问题。

  众所周知,JVM GC在回收内存垃圾时会有一个“停界”进程,即垃圾回收线程运行时,会导致其他工作线程短暂暂停,这样有利于他自己安静的进行内存垃圾回收。

  这个也很好理解。毕竟如果你在回收内存垃圾的时候,你的工作线程还在往内存里写数据,制造更多的内存垃圾,那你让人家的JVM怎么回收垃圾呢?

  就像在主干道上。如果地上有很多垃圾,现在最好的清理方法是什么?大家都让开,把路清干净,然后清洁工就只是清理垃圾。

  但是,如果清洁工在清理垃圾,结果一群人在吃瓜子扔瓜壳,吃西瓜扔西瓜皮,制造垃圾,你觉得清洁工内心是什么感受?当然,我很生气。如果我们这样做,地上的垃圾永远不会干净!

  通过上面的语言描述,我们再来一张图,大家看看会更清楚。

  现在JVM GC越来越高级了。从CMS垃圾收集器到G1垃圾收集器,核心目标之一是不断减少垃圾收集的时间,这导致了其他工作线程的暂停。

  所以现在,新的垃圾收集器导致工作线程停止的次数越多,时间就越短,但是不管多短,它还是存在的!

  所以,如何在自己的设计中避免JVM的频繁GC,是一件很有挑战性的事情。

  3.Kafka designer实现的缓冲池机制在Kafka客户端内部,对于这个问题是一个非常好的机制,即缓冲池机制。

  简单来说,每一批的底层对应一个内存空间,专门用来存储写入的消息。

  然后,当一个批次发送到kafka服务器时,不再需要该批次的数据,也就是说不再使用该批次的内存空间。

  此时,这批最底层的内存空间不应该给JVM进行垃圾回收,而应该把这个内存空间放到一个缓冲池中。

  这个缓冲池中有大量的内存空间。下一次,如果你有一个新的批处理,你不能从这个缓冲池中获取一个内存空间吗?

  如果发出去一批,然后把内存空间还给别人不是很好吗?等等,等等。

  同样,听完上面的文字描述,再来一张图。看完这张图,相信大家都会明白:

  一旦使用了这种缓冲池机制,就不会经常出现大内存的GC问题。

  为什么?因为他能上来,占用固定内存,比如32MB。然后把32MB分成N个内存块,比如一个内存块是16KB,那么这个缓冲池就会有很多内存块。

  然后你需要创建一个新的批次,只需要从缓冲池中取一个16KB的内存块,然后这个批次就会不停的写消息,但是最多也就16KB,因为批次底部的内存块只有16KB。

  然后,如果批处理发送到Kafka服务器,批处理底部的内存块可以直接返回到缓冲池。

  下次其他人想要构建一个批处理时,只需再次使用缓冲池中的内存块。这样就可以利用有限的内存,反复使用。因为如果您在使用批处理后将内存块返回到缓冲池,那么就不会涉及垃圾收集。

  如果没有频繁的垃圾收集,自然会避免工作线程的频繁暂停。JVM GC问题是否有了很大的优化?

  没错,正是这种设计思想使得Kafka客户端的性能和吞吐量非常高,这里有大量优秀的机制。

  那么这个时候有人说,如果我现在把一个缓冲池的内存资源全部填满,而缓冲池暂时没有内存块,怎么办?

  很简单。它会阻止您的书写操作,并阻止您书写邮件。阻塞你,等到一个内存块被释放,再继续让你写消息。

  4.总结这篇文章,我们从Kafka内存缓冲机制的设计思想入手,分析了JVM GC问题产生的原因和不良影响。

  然后,谈了卡夫卡优秀的缓冲池机制设计思想以及他是如何解决这个问题的,分析了很多卡夫卡作者在设计时所表现出来的优秀的技术设计思想和能力。

  希望你能从这里学到更多的精华,把这些优秀的想法在以后的面试或者工作中为己所用。

  版权归作者所有:原创作品来自博主小二上九8,转载请联系作者取得转载授权,否则将追究法律责任。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: