京东6.18大促主会场领京享红包更优惠

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 774|回复: 0

【架构设计的艺术】Kafka如何通过精妙的架构设计优化JVM GC问题

[复制链接]

17

主题

0

回帖

10

积分

新手上路

积分
10
发表于 2019-7-13 20:05:05 | 显示全部楼层 |阅读模式 来自 中国
欢迎关注头条号:石杉的架构笔记, d& N8 Z* }0 b8 V0 U* P1 f1 y
周一至周五早八点半!精品技术文章准时送上!!!
9 o' u* M- F* v4 L9 a1 n. X% v精品学习资料获取通道,参见文末
3 q, Z/ y: P5 N; k: q3 ^& V目录
( v4 x, F; E$ h: M5 J1、Kafka的客户端缓冲机制
" k( v& J1 e# T" R2、内存缓冲造成的频繁GC问题) F* l& ]/ ], J  i4 z
3、Kafka设计者实现的缓冲池机制: z) q' g; A$ G0 z$ n6 ^! U! F
4、总结一下
( ~3 k/ V) E5 h) B# N这篇文章,同样给大家聊一个硬核的技术知识,我们通过Kafka内核源码中的一些设计思想,来看你设计Kafka架构的技术大牛,是怎么优化JVM的GC问题的?
! \: F% S& |4 `+ g% Q4 q1、Kafka的客户端缓冲机制
: l' P! q' {1 P* O$ K0 x$ V
1 a( d. f% z$ M) b4 h' J首先,先得给大家明确一个事情,那就是在客户端发送消息给kafka服务器的时候,一定是有一个内存缓冲机制的。; m, Q$ I3 W! q: [" X  _5 w
也就是说,消息会先写入一个内存缓冲中,然后直到多条消息组成了一个Batch,才会一次网络通信把Batch发送过去。
3 z. C9 q$ B# l整个过程如下图所示:; g3 Q2 N6 g# d) P$ n. \, R
, s$ D. W3 v: Y0 o

5 g* N7 @8 G1 d' C: w: l
: w  ?0 O$ `, y- L+ h& O; N2、内存缓冲造成的频繁GC问题% a$ o8 u9 O: ?3 [! X" @1 s6 D' W; h
* q; }& [  g- V  f/ s* e( y
那么这种内存缓冲机制的本意,其实就是把多条消息组成一个Batch,一次网络请求就是一个Batch或者多个Batch。
( j# V" R6 `+ r% G) @这样每次网络请求都可以发送很多数据过去,避免了一条消息一次网络请求。从而提升了吞吐量,即单位时间内发送的数据量。% w' u. {$ S# L
但是问题来了,大家可以思考一下,一个Batch中的数据,会取出来然后封装在底层的网络包里,通过网络发送出去到达Kafka服务器。2 H, _8 y9 M6 B2 |$ I
那么然后呢?这个Batch里的数据都发送过去了,现在Batch里的数据应该怎么处理?
1 @) c2 @# Y5 V' Y) t( ?$ [# O你要知道,这些Batch里的数据此时可还在客户端的JVM的内存里啊!那么此时从代码实现层面,一定会尝试避免任何变量去引用这些Batch对应的数据,然后尝试触发JVM自动回收掉这些内存垃圾。
9 n+ F! B' P& c3 Q6 b这样不断的让JVM回收垃圾,就可以不断的清理掉已经发送成功的Batch了,然后就可以不断的腾出来新的内存空间让后面新的数据来使用。/ r6 c: p$ u: @
这种想法很好,但是实际线上运行的时候一定会有问题,最大的问题,就是JVM GC问题。$ ~4 e. a2 n2 ?* S% m# f  C2 b! @
大家都知道一点,JVM GC在回收内存垃圾的时候,他会有一个“Stop the World”的过程,也就是垃圾回收线程运行的时候,会导致其他工作线程短暂的停顿,这样可以便于他自己安安静静的回收内存垃圾。' n2 @' V+ F( Y
这个也很容易想明白,毕竟你要是在回收内存垃圾的时候,你的工作线程还在不断的往内存里写数据,制造更多的内存垃圾,那你让人家JVM怎么回收垃圾?5 T3 k* {2 J2 i! d% Y/ K
这就好比在大马路上,如果地上有很多垃圾,现在要把垃圾都扫干净,最好的办法是什么?大家都让开,把马路空出来,然后清洁工就是把垃圾清理干净。6 v  W# n: w$ U; K* W3 Q0 ^- b6 }
但是如果清洁工在清扫垃圾的时候,结果一帮人在旁边不停的嗑瓜子扔瓜子壳,吃西瓜扔西瓜皮,不停的制造垃圾,你觉得清洁工内心啥感受?当然是很愤慨了,照这么搞,地上的垃圾永远的都搞不干净了!
/ H& n* r# \- M. r! \/ d* S( H' v" D通过了上面的语言描述,我们再来一张图,大家看看就更加清楚了
, M  Z# C4 O+ i5 h( d- A9 `) T7 o, g. t' ~- L% \! I. h' H
现在JVM GC是越来越先进,从CMS垃圾回收器到G1垃圾回收器,核心的目标之一就是不断的缩减垃圾回收的时候,导致其他工作线程停顿的时间。! z6 j/ G/ Z* O: k1 F
所以现在越是新款的垃圾回收器导致工作线程停顿的时间越短,但是再怎么短,他也还是存在啊!$ A( x# S) @+ u- K8 `' @1 Q
所以说,如何尽可能在自己的设计上避免JVM频繁的GC就是一个非常考验水平的事儿了。
- E* [9 w: H5 c* j3、Kafka设计者实现的缓冲池机制
3 [$ S# g, y. ?/ N) g% c0 t  ]6 E, n$ |# b
在Kafka客户端内部,对这个问题实现了一个非常优秀的机制,就是缓冲池的机制
, [; C7 x  C2 s6 P
; U/ {( ^9 m! s5 W+ p
4 _( }. ~# c2 h" b9 ]! ^; D简单来说,就是每个Batch底层都对应一块内存空间,这个内存空间就是专门用来存放写入进去的消息的。- t8 L' `! B% E+ _3 @1 q
然后呢,当一个Batch被发送到了kafka服务器,这个Batch的数据不再需要了,就意味着这个Batch的内存空间不再使用了。" f; Q; e8 A# [: a5 U7 f
此时这个Batch底层的内存空间不要交给JVM去垃圾回收,而是把这块内存空间给放入一个缓冲池里。: q/ g' X4 v6 H( N% L4 o
这个缓冲池里放了很多块内存空间,下次如果你又有一个新的Batch了,那么不就可以直接从这个缓冲池里获取一块内存空间就ok了?9 t4 O+ b6 R8 c8 k! \' s
然后如果一个Batch发送出去了之后,再把内存空间给人家还回来不就好了?以此类推,循环往复。
6 m" H5 Z' h+ t1 i同样,听完了上面的文字描述,再来一张图,看完这张图相信大伙儿就明白了:
. x- |- J, n- Z6 t7 F3 a, A, X6 ]$ W
一旦使用了这个缓冲池机制之后,就不涉及到频繁的大量内存的GC问题了。
$ Y# b7 W9 ?5 O" p! h/ y% t为什么呢?因为他可以上来就占用固定的内存,比如32MB。然后把32MB划分为N多个内存块,比如说一个内存块是16KB,这样的话这个缓冲池里就会有很多的内存块。
9 b- {$ d5 I/ P' Z  ?+ d5 L然后你需要创建一个新的Batch,就从缓冲池里取一个16KB的内存块就可以了,然后这个Batch就不断的写入消息,但是最多就是写16KB,因为Batch底层的内存块就16KB。' b: _( M% u* E" X; `+ W' {
接着如果Batch被发送到Kafka服务器了,此时Batch底层的内存块就直接还回缓冲池就可以了。
/ m; S7 e2 P4 z' a$ {; y& y下次别人再要构建一个Batch的时候,再次使用缓冲池里的内存块就好了。这样就可以利用有限的内存,对他不停的反复重复的利用。因为如果你的Batch使用完了以后是把内存块还回到缓冲池中去,那么就不涉及到垃圾回收了。
1 u4 r8 Z- v# p/ _/ H( R2 O如果没有频繁的垃圾回收,自然就避免了频繁导致的工作线程的停顿了,JVM GC问题是不是就得到了大幅度的优化?/ }3 \# V' y2 ?. t' T# u. v, I
没错,正是这个设计思想让Kafka客户端的性能和吞吐量都非常的高,这里蕴含了大量的优秀的机制。0 G% X! [* q. Q% s) q4 V
那么此时有人说了,如果我现在把一个缓冲池里的内存资源都占满了,现在缓冲池里暂时没有内存块了,怎么办呢?
3 _( |* T( L& X4 q1 ]% x, }$ T! V) H很简单,阻塞你的写入操作,不让你继续写入消息了。把你给阻塞住,不停的等待,直到有内存块释放出来,然后再继续让你写入消息。
, {& q; M7 T* ~4、总结一下
5 u+ I- i! C0 n* l6 D. n  r9 g( M; p+ H( m1 Y
这篇文章我们从Kafka内存缓冲机制的设计思路开始,一直分析到了JVM GC问题的产生原因以及恶劣的影响。
* h1 O* Z- S& B; v$ U% x接着谈到了Kafka优秀的缓冲池机制的设计思想以及他是如何解决这个问题的,分析了很多Kafka作者在设计的时候展现出的优秀的技术设计思想和能力。$ a5 b$ d/ n1 B& o
希望大家多吸取这里的精华,在以后面试或者工作的时候,可以把这些优秀的思想纳为己用。
! \3 _. ~" T9 l( {2 y2 _) VEnd
/ U+ T% P% \1 d# |9 [5 ?3 {一大波微服务、分布式、高并发、高可用的原创系列文章正在路上,
9 n" o. m/ T7 z. l2 F  }欢迎关注头条号:石杉的架构笔记: G+ u( S* v1 H
周一至周五早八点半!精品技术文章准时送上!!!
! ~6 q$ C4 g( S0 h& a十余年BAT架构经验倾囊相授
5 t% M4 J# A  h$ Z. R& h  Y1 P2 Q
推荐阅读
9 E; {$ w' {( C6 y1、拜托!面试请不要再问我Spring Cloud底层原理!
8 ]5 X2 h' |$ K/ T& Z8 a: b2、微服务注册中心如何承载大型系统的千万级访问?
' P4 Z) k3 U- J- S, d! G3、「性能优化之道」每秒上万并发下的Spring Cloud参数优化实战
* l) {' k* X+ i: N7 ^4、「“剁手党”狂欢的背后」微服务架构如何保障99.99%的高可用?
  D: z' L' S  {1 h5 o5、兄弟,用大白话告诉你小白都能看懂的Hadoop架构原理
) w7 V& d' D1 a+ ^. t# @' ]6、大规模集群下Hadoop NameNode如何承载每秒上千次的高并发访问: [4 O9 ]+ @4 R+ B# F, _
7、「性能优化的秘密」Hadoop如何将TB级大文件的上传性能优化上百倍3 o8 l8 b1 Y2 V0 v
8、拜托,面试请不要再问我TCC分布式事务的实现原理!
) k) O; P; }) A0 `* n9、最终一致性分布式事务如何保障实际生产中99.99%高可用?
$ E4 g5 s" n  Y/ z9 g  ^5 |6 H10、拜托,面试请不要再问我Redis分布式锁的实现原理
, k) T" ^2 Q8 o- \11、Hadoop底层算法如何优雅的将大规模集群性能提升10倍以上?
( I" D  H. H5 O0 n12、亿级流量系统架构之如何支撑百亿级数据的存储与计算
2 O5 P2 @4 n3 V  M% B3 O3 v13、亿级流量系统架构之如何设计高容错分布式计算系统) H0 c9 a3 P' T3 A5 a' r) Y
14、亿级流量系统架构之如何设计承载百亿流量的高性能架构
* ~4 T/ V0 N( c& O; P  M15、亿级流量系统架构之如何设计每秒十万查询的高并发架构
9 I( s9 q) A3 R5 Z- G9 q; \' N16、亿级流量系统架构之如何设计全链路99.99%高可用架构
' h: l6 K, m& y0 S0 B9 }17、七张图彻底讲清楚ZooKeeper分布式锁的实现原理% r8 f3 p0 m) J/ y
18、大白话聊聊Java并发面试问题之volatile到底是什么?& d2 k7 j. f0 }) W4 V( n+ _: f0 O
19、大白话聊聊Java并发面试问题之Java 8如何优化CAS性能?
1 [6 F4 H0 i2 i& }) |$ t20、大白话聊聊Java并发面试问题之谈谈你对AQS的理解?; s* ]  K( T4 m( R5 W" w) D% P
21、大白话聊聊Java并发面试问题之微服务注册中心的读写锁优化
$ w1 Y9 l: ?0 j7 i22、互联网公司的面试官是如何360°无死角考察候选人的?(上篇)
; V8 z$ ]2 }, k0 o2 v( B23、互联网公司面试官是如何360°无死角考察候选人的?(下篇)! [0 C2 d6 v" H/ R5 ?9 b4 F0 u
24、「Java进阶面试系列之一」你们系统架构中为何要引入消息中间件?
; A% d8 S+ O  \2 J7 `25、「Java进阶面试系列之二」系统架构引入消息中间件有什么缺点
6 ?) m3 F) u' c+ T/ Z26、「行走的Offer收割机」一位朋友斩获BAT技术专家Offer的面试经历
9 x7 S% Q3 @& y7 X( d4 A27、「Java进阶面试系列之三」消息中间件在你们项目里是如何落地的?' N, a0 T% k# I$ s+ x# [
28、扎心!线上服务宕机时,如何保证数据100%不丢失?" ~2 C: j; {. r7 h  h  V; d
29、 一次JVM FullGC的背后,竟隐藏着惊心动魄的线上生产事故!
4 B  t$ T) t0 \* _3 B2 M30、「高并发优化实践」10倍请求压力来袭,你的系统会被击垮吗?
2 X# h8 C" \( t0 g31、消息中间件集群崩溃,如何保证百万生产数据不丢失?
4 L# }; n9 e3 ?) z  o32、亿级流量系统架构之如何在上万并发场景下设计可扩展架构(上)?/ c% g1 i% ]) f' t  o* L
33、亿级流量系统架构之如何在上万并发场景下设计可扩展架构(中)?
9 v2 t  {& G; E5 x; ^, Q34、亿级流量系统架构之如何在上万并发场景下设计可扩展架构(下)?3 t5 g0 |" A8 e
35、亿级流量架构第二弹:你的系统真的无懈可击吗?* `# B: d4 Z" `5 ~) Z- I
36、亿级流量系统架构之如何保证百亿流量下的数据一致性(上)/ A# r/ k. T5 d5 n, c
37、亿级流量系统架构之如何保证百亿流量下的数据一致性(中)?$ [. B+ D7 t! J
38、亿级流量系统架构之如何保证百亿流量下的数据一致性(下)?
5 x; V0 c$ q' U) Y1 k# N! [$ E39、互联网面试必杀:如何保证消息中间件全链路数据100%不丢失(1): ~  W- ~+ N. e$ N) s
40、互联网面试必杀:如何保证消息中间件全链路数据100%不丢失(2)8 M; U3 `; l2 [! e' L3 l
41、面试大杀器:消息中间件如何实现消费吞吐量的百倍优化?
. k- K$ S  N" H; c! h" `( G42、兄弟,用大白话给你讲小白都能看懂的分布式系统容错架构3 {! Y7 H6 C  D. @) }
43、从团队自研的百万并发中间件系统的内核设计看Java并发性能优化
* X1 S3 O" ~6 P9 A8 }" ^2 ]1 s44、如果20万用户同时访问一个热点缓存,如何优化你的缓存架构?
% B7 N, p4 f& \9 U) V45、「非广告,纯干货」英语差的程序员如何才能无障碍阅读官方文档?# R0 X) o. c6 i5 ^
46、面试最让你手足无措的一个问题:你的系统如何支撑高并发?; E$ S" \0 o+ c) O  Z, C6 b# j
47、Java进阶必备:优雅的告诉面试官消息中间件该如何实现高可用架构
0 x6 X6 t5 }- B" X+ Q- m5 Y1 m48、「非广告,纯干货」中小公司的Java工程师应该如何逆袭冲进BAT?
) V" S6 T9 o8 B9 l6 L49、拜托,面试请不要再问我分布式搜索引擎的架构原理!
/ }8 W( x1 B& S' X: n3 u. X50、互联网大厂Java面试题:使用无界队列的线程池会导致内存飙升吗?
; k/ ~$ c$ U7 q$ n6 S; o51、「码农打怪升级之路」行走江湖,你需要解锁哪些技能包?1 g$ ^* p& o+ Q0 y1 s9 x/ z
52、「来自一线的血泪总结」你的系统上线时是否踩过这些坑?( H+ k; G  ?. J6 {
53、【offer收割机必备】我简历上的Java项目都好low,怎么办?
. |& H( ?# v( v- t1 t54、【offer去哪了】我一连面试了十个Java岗,统统石沉大海!
! x' z7 C  M' `, f, v2 E/ M1 B55、支撑日活百万用户的高并发系统,应该如何设计其数据库架构?
+ V6 K6 n0 L6 Z56、高阶Java开发必备:分布式系统的唯一id生成算法你了解吗?; D9 m% w$ P! O2 ]9 G% ~9 z  o
57、尴尬了!Spring Cloud微服务注册中心Eureka 2.x停止维护了咋办?
8 e8 [0 I+ p2 {7 g8 ~! y3 o( F58、【Java高阶必备】如何优化Spring Cloud微服务注册中心架构?
1 k6 d# L0 k+ t. a& e2 Y; T59、面试官:消息中间件如何实现每秒几十万的高并发写入?6 J. q4 s0 ~, \/ a# o9 N
60、【非广告,纯干货】三四十岁大龄程序员,该如何保持职场竞争力?$ M+ j2 X/ ]/ h$ V3 W
61、面试官:请谈谈写入消息中间件的数据,如何保证不丢失?1 y9 Z# q( ]2 n$ T( m; A- k& u1 z
62、【生产实践总结】支撑百万连接的系统应该如何设计其高并发架构?
/ [7 @1 T. u. Z5 Q5 v63、面对BAT大厂的竞争对手时,小公司Java工程师是如何败北的?1 u- _4 D8 ]2 K1 s4 H5 L* O
64、【纯干货分享】小公司出身的我,是如何拿下知名独角兽公司offer5 S& e; P$ j  A1 Y3 p
65、用小白都能看懂的大白话告诉你:什么是分布式计算系统?. k/ r5 ?2 t" H6 ~- \7 F2 Z$ |
66、老司机生产实践经验:线上系统的JVM内存是越大越好吗?8 x9 J9 H- I/ ~8 H
67、Java同学找工作最懵圈的问题:到底啥是分布式系统开发经验?1 V# x% [$ `# \1 l; Q! p% B
67、尴尬的面试现场:说说你们系统有多大QPS?系统如何抗住高并发?
5 O" H( ]) J) X: x* a( m68、分享一套GitHub上stars 10000+的Java面试题(含解析)% d5 q# \" N6 N
69、小公司面试10连挂之后,我拿到了互联网一线大厂offer!- w. w& f/ Y( k: @
70、【架构设计之道】这波操作,会把你的中间件架构带到另一个Level
% |0 P  l2 |1 A7 ^9 [71、三年努力,梦归阿里!
) B8 E9 J6 V+ R# @9 K; L72、阿里三面,P9面试官是如何360°无死角考察候选人的?" a4 o. M: w, o' o
73、如果让你设计一个消息中间件,如何将网络通信性能优化10倍以上?
) ]$ Z, d6 b- f6 X74、简历写Kafka,面试官大概率会让你讲acks参数对消息持久化的影响
# M6 f  c0 s9 S: N: ~/ M75、【嗅探底层】深入揭秘Synchronized在JVM是如何实现的?
4 _& u9 ]$ u' r7 z: o3 l76、面经分享:斩获7枚offer,入职阿里平台事业部!
, s. t* s+ k' O# N0 B5 k

; ~% x2 ]* h: [& b! h4 b+ q8 U: q来源:https://www.toutiao.com/a6687543307867783691/4 j0 z8 |" n3 @1 w/ x
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

帖子地址: 

梦想之都-俊月星空 优酷自频道欢迎您 http://i.youku.com/zhaojun917
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /6 下一条

QQ|手机版|小黑屋|梦想之都-俊月星空 ( 粤ICP备18056059号 )|网站地图

GMT+8, 2025-7-14 12:49 , Processed in 0.051809 second(s), 28 queries .

Powered by Mxzdjyxk! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表