|
|
欢迎关注头条号:石杉的架构笔记
+ R. ]2 q- L/ ~ s3 h& |周一至周五早八点半!精品技术文章准时送上!!!$ o: a5 y1 q, t* z5 Y
精品学习资料获取通道,参见文末: G) M6 A3 n% g/ Z" w, y! J' Y; ]7 V
目录$ B: `' g, L3 c" q: x. i0 n! F
1、Kafka的客户端缓冲机制
- J2 M* A8 Z: M) t7 }2、内存缓冲造成的频繁GC问题
8 p2 F6 F& N- |4 g0 r" e; C1 y3、Kafka设计者实现的缓冲池机制0 D, ~, F' ~/ ^* z$ Q; p. d$ j9 p
4、总结一下
3 e; f, q$ E0 {& G$ v& t“ 这篇文章,同样给大家聊一个硬核的技术知识,我们通过Kafka内核源码中的一些设计思想,来看你设计Kafka架构的技术大牛,是怎么优化JVM的GC问题的?% E* ?& N8 M, s, B
1、Kafka的客户端缓冲机制2 o6 W5 Z9 {. E3 Q
) {6 S5 U( u. O3 z/ Z- t
首先,先得给大家明确一个事情,那就是在客户端发送消息给kafka服务器的时候,一定是有一个内存缓冲机制的。2 I" P3 g$ ^+ q/ c; {9 N
也就是说,消息会先写入一个内存缓冲中,然后直到多条消息组成了一个Batch,才会一次网络通信把Batch发送过去。
' I- y! Z- e9 A/ t+ c7 v, m) T整个过程如下图所示:* n; \5 g) ~ h! J% p, j& d- G! u
6 z0 Q! S& c9 A* x/ I2 R
, ]& h% T0 w. R$ m# }( L8 e
9 I4 y- G" T3 T2、内存缓冲造成的频繁GC问题
/ ~# N! |; |% a
, p1 W6 F) j% G$ N0 T那么这种内存缓冲机制的本意,其实就是把多条消息组成一个Batch,一次网络请求就是一个Batch或者多个Batch。4 t5 q: _5 e- m
这样每次网络请求都可以发送很多数据过去,避免了一条消息一次网络请求。从而提升了吞吐量,即单位时间内发送的数据量。
8 d2 F0 A: U* ?5 ?但是问题来了,大家可以思考一下,一个Batch中的数据,会取出来然后封装在底层的网络包里,通过网络发送出去到达Kafka服务器。$ i0 N9 ^+ B0 z# d: R
那么然后呢?这个Batch里的数据都发送过去了,现在Batch里的数据应该怎么处理?
) `) n5 s' }/ F你要知道,这些Batch里的数据此时可还在客户端的JVM的内存里啊!那么此时从代码实现层面,一定会尝试避免任何变量去引用这些Batch对应的数据,然后尝试触发JVM自动回收掉这些内存垃圾。: @& K, z1 {8 d/ h$ m, \+ Y
这样不断的让JVM回收垃圾,就可以不断的清理掉已经发送成功的Batch了,然后就可以不断的腾出来新的内存空间让后面新的数据来使用。4 T& d0 Z# q1 ~' w" c$ O
这种想法很好,但是实际线上运行的时候一定会有问题,最大的问题,就是JVM GC问题。0 w# R4 p2 c5 U3 H K
大家都知道一点,JVM GC在回收内存垃圾的时候,他会有一个“Stop the World”的过程,也就是垃圾回收线程运行的时候,会导致其他工作线程短暂的停顿,这样可以便于他自己安安静静的回收内存垃圾。/ W5 |& I4 w: F! A( x! E; E, a$ v
这个也很容易想明白,毕竟你要是在回收内存垃圾的时候,你的工作线程还在不断的往内存里写数据,制造更多的内存垃圾,那你让人家JVM怎么回收垃圾?2 w X$ h: ^4 b/ D/ T4 \
这就好比在大马路上,如果地上有很多垃圾,现在要把垃圾都扫干净,最好的办法是什么?大家都让开,把马路空出来,然后清洁工就是把垃圾清理干净。
1 H( U$ K/ r; s5 [0 q但是如果清洁工在清扫垃圾的时候,结果一帮人在旁边不停的嗑瓜子扔瓜子壳,吃西瓜扔西瓜皮,不停的制造垃圾,你觉得清洁工内心啥感受?当然是很愤慨了,照这么搞,地上的垃圾永远的都搞不干净了!, D& d8 {& ^2 A
通过了上面的语言描述,我们再来一张图,大家看看就更加清楚了1 t+ A" m% c1 T; e( D# V1 [
! K! c+ v% G& n
现在JVM GC是越来越先进,从CMS垃圾回收器到G1垃圾回收器,核心的目标之一就是不断的缩减垃圾回收的时候,导致其他工作线程停顿的时间。
x0 _4 S: ~. x1 p所以现在越是新款的垃圾回收器导致工作线程停顿的时间越短,但是再怎么短,他也还是存在啊!$ g7 w5 H- g7 j+ n! g f
所以说,如何尽可能在自己的设计上避免JVM频繁的GC就是一个非常考验水平的事儿了。
. k( Q' D/ Y, N, C3、Kafka设计者实现的缓冲池机制' I% r( m- w. w
/ p- Y, I" N1 o
在Kafka客户端内部,对这个问题实现了一个非常优秀的机制,就是缓冲池的机制3 R0 h4 J' ]2 T3 E) U1 F
7 J. r5 D+ y' R8 |* e9 K+ i# _: D6 {- x6 w
简单来说,就是每个Batch底层都对应一块内存空间,这个内存空间就是专门用来存放写入进去的消息的。& e }- {& I- g6 b' r' L+ _0 B: T
然后呢,当一个Batch被发送到了kafka服务器,这个Batch的数据不再需要了,就意味着这个Batch的内存空间不再使用了。0 W+ [' N' o& `9 |" \. J( t) y
此时这个Batch底层的内存空间不要交给JVM去垃圾回收,而是把这块内存空间给放入一个缓冲池里。; a T$ F1 l4 }2 Q
这个缓冲池里放了很多块内存空间,下次如果你又有一个新的Batch了,那么不就可以直接从这个缓冲池里获取一块内存空间就ok了?
6 d+ H2 }) ^2 C* x4 y然后如果一个Batch发送出去了之后,再把内存空间给人家还回来不就好了?以此类推,循环往复。
, c s4 |& ~" q$ K同样,听完了上面的文字描述,再来一张图,看完这张图相信大伙儿就明白了:5 ^0 @. g# q4 z
3 U. E9 \+ a. a- S0 x6 ]
一旦使用了这个缓冲池机制之后,就不涉及到频繁的大量内存的GC问题了。" w1 M3 S, r8 ?# o+ {8 w6 Q
为什么呢?因为他可以上来就占用固定的内存,比如32MB。然后把32MB划分为N多个内存块,比如说一个内存块是16KB,这样的话这个缓冲池里就会有很多的内存块。" L7 m, W- F7 K
然后你需要创建一个新的Batch,就从缓冲池里取一个16KB的内存块就可以了,然后这个Batch就不断的写入消息,但是最多就是写16KB,因为Batch底层的内存块就16KB。
4 Q: o7 h7 j# q5 z( v* u接着如果Batch被发送到Kafka服务器了,此时Batch底层的内存块就直接还回缓冲池就可以了。
, D7 q' I( o$ c; A4 S! q' A下次别人再要构建一个Batch的时候,再次使用缓冲池里的内存块就好了。这样就可以利用有限的内存,对他不停的反复重复的利用。因为如果你的Batch使用完了以后是把内存块还回到缓冲池中去,那么就不涉及到垃圾回收了。, [' T H) i$ }! h* O
如果没有频繁的垃圾回收,自然就避免了频繁导致的工作线程的停顿了,JVM GC问题是不是就得到了大幅度的优化?2 m) t6 S% ?5 ]9 Y1 n. Y
没错,正是这个设计思想让Kafka客户端的性能和吞吐量都非常的高,这里蕴含了大量的优秀的机制。
' `7 Q2 C* J2 _6 W7 w那么此时有人说了,如果我现在把一个缓冲池里的内存资源都占满了,现在缓冲池里暂时没有内存块了,怎么办呢?- H1 q5 l& p; D: j/ G" P% B
很简单,阻塞你的写入操作,不让你继续写入消息了。把你给阻塞住,不停的等待,直到有内存块释放出来,然后再继续让你写入消息。3 q% {4 \( E9 [, j$ c
4、总结一下2 c9 U3 a# u% c7 s: f6 S9 h
; w, ~& c( u5 k. ^
这篇文章我们从Kafka内存缓冲机制的设计思路开始,一直分析到了JVM GC问题的产生原因以及恶劣的影响。9 ^& `2 @- l' s( o- ^
接着谈到了Kafka优秀的缓冲池机制的设计思想以及他是如何解决这个问题的,分析了很多Kafka作者在设计的时候展现出的优秀的技术设计思想和能力。* W. U, l1 \6 z6 b. r
希望大家多吸取这里的精华,在以后面试或者工作的时候,可以把这些优秀的思想纳为己用。* x, Y5 @! p3 S+ x6 D O" a! T
End
- S% U Q# b+ @4 ^2 S一大波微服务、分布式、高并发、高可用的原创系列文章正在路上,2 P' o7 v5 m1 D
欢迎关注头条号:石杉的架构笔记( T" z1 N" I. r# Y) G" a6 L9 E
周一至周五早八点半!精品技术文章准时送上!!!4 ?8 r. C! N$ y7 u' C4 \9 w
十余年BAT架构经验倾囊相授# a- w9 U! a: \ l1 B: F
推荐阅读
+ O, |* t2 B# O" }% l2 `4 d7 T& n. X1、拜托!面试请不要再问我Spring Cloud底层原理!
9 O. t8 N/ n8 Z; m5 h2 I2、微服务注册中心如何承载大型系统的千万级访问?& A% p* H$ _, G9 o# X
3、「性能优化之道」每秒上万并发下的Spring Cloud参数优化实战6 _( w1 q. V( I8 I5 E8 T
4、「“剁手党”狂欢的背后」微服务架构如何保障99.99%的高可用?
0 M( b6 j5 p0 t: @5、兄弟,用大白话告诉你小白都能看懂的Hadoop架构原理1 P1 u3 p ]. ~1 |2 y
6、大规模集群下Hadoop NameNode如何承载每秒上千次的高并发访问) m5 ?5 p5 A; f$ w
7、「性能优化的秘密」Hadoop如何将TB级大文件的上传性能优化上百倍5 O n4 L8 [" o8 i. q+ d5 x6 J
8、拜托,面试请不要再问我TCC分布式事务的实现原理!7 C! ^0 X+ b2 r' _
9、最终一致性分布式事务如何保障实际生产中99.99%高可用?& ]% D J# i1 ?+ ]
10、拜托,面试请不要再问我Redis分布式锁的实现原理
+ {4 B, f7 \9 _( @11、Hadoop底层算法如何优雅的将大规模集群性能提升10倍以上?
7 B6 v5 m6 K: O+ k/ p) x12、亿级流量系统架构之如何支撑百亿级数据的存储与计算
! s1 d' d8 }& l2 R: `4 _/ e13、亿级流量系统架构之如何设计高容错分布式计算系统; a6 \: F8 x0 \% U/ D6 f
14、亿级流量系统架构之如何设计承载百亿流量的高性能架构8 W; ?6 N- o6 N1 i9 b% V. M
15、亿级流量系统架构之如何设计每秒十万查询的高并发架构
8 v8 @: T. u* `, \3 r* @16、亿级流量系统架构之如何设计全链路99.99%高可用架构% |8 Z, h% _, w& r
17、七张图彻底讲清楚ZooKeeper分布式锁的实现原理
& P$ r( P/ c: n g18、大白话聊聊Java并发面试问题之volatile到底是什么?
. v# b) I4 h( t! i7 b2 m" S( _6 W$ v# B19、大白话聊聊Java并发面试问题之Java 8如何优化CAS性能?
, p4 Q# G, q: _, i+ p; Q. Z% L20、大白话聊聊Java并发面试问题之谈谈你对AQS的理解?
- P7 X) J6 X8 z$ {21、大白话聊聊Java并发面试问题之微服务注册中心的读写锁优化
4 h A H- z% z2 y; j/ J! ]22、互联网公司的面试官是如何360°无死角考察候选人的?(上篇)+ w. R& v, U1 V+ N$ t, s3 Q' I8 c
23、互联网公司面试官是如何360°无死角考察候选人的?(下篇)
3 Z/ N1 a) u; n+ o* b24、「Java进阶面试系列之一」你们系统架构中为何要引入消息中间件?
% S; I- D8 M+ }6 z- y% U25、「Java进阶面试系列之二」系统架构引入消息中间件有什么缺点; M n R) Q" B# [/ S; r* m, d
26、「行走的Offer收割机」一位朋友斩获BAT技术专家Offer的面试经历$ V! C8 u( f2 l% D7 }
27、「Java进阶面试系列之三」消息中间件在你们项目里是如何落地的?
5 Q+ _4 h- ]% i% _$ {) J! @$ L28、扎心!线上服务宕机时,如何保证数据100%不丢失?# Q( v. y d2 U3 u3 g8 n
29、 一次JVM FullGC的背后,竟隐藏着惊心动魄的线上生产事故!
' _3 \# I6 h( W2 h4 u30、「高并发优化实践」10倍请求压力来袭,你的系统会被击垮吗?
+ U$ ]( p) C q+ h3 `! X% E- T9 h31、消息中间件集群崩溃,如何保证百万生产数据不丢失?
2 l7 i' g# P0 Y! U32、亿级流量系统架构之如何在上万并发场景下设计可扩展架构(上)?
& y$ n0 H, m6 }4 b o% I# e33、亿级流量系统架构之如何在上万并发场景下设计可扩展架构(中)?
. g7 X# A4 h/ E1 ~$ u34、亿级流量系统架构之如何在上万并发场景下设计可扩展架构(下)?( M* ], g3 ]# @' `' W
35、亿级流量架构第二弹:你的系统真的无懈可击吗?
5 k5 ]/ z, c% h+ b. }. s* X% G$ _36、亿级流量系统架构之如何保证百亿流量下的数据一致性(上)2 z" B( e9 @' ^1 R
37、亿级流量系统架构之如何保证百亿流量下的数据一致性(中)?. p4 g0 L. ?% h0 i8 H% c
38、亿级流量系统架构之如何保证百亿流量下的数据一致性(下)?
4 Y0 c) t0 c" M" w% v. N2 c0 N39、互联网面试必杀:如何保证消息中间件全链路数据100%不丢失(1)
2 W, [- b/ }/ c1 U40、互联网面试必杀:如何保证消息中间件全链路数据100%不丢失(2)
; N) x8 _% P1 u8 }8 ~41、面试大杀器:消息中间件如何实现消费吞吐量的百倍优化?
f7 T& X% |; O! M" j9 [$ e42、兄弟,用大白话给你讲小白都能看懂的分布式系统容错架构9 g8 Q1 d0 M% W+ }$ M
43、从团队自研的百万并发中间件系统的内核设计看Java并发性能优化2 M4 `5 ?" n7 U$ P2 N3 a* q
44、如果20万用户同时访问一个热点缓存,如何优化你的缓存架构? ^! ?- K' i, A8 f$ g# B0 T( O
45、「非广告,纯干货」英语差的程序员如何才能无障碍阅读官方文档?/ r8 a/ q2 M5 ^: f
46、面试最让你手足无措的一个问题:你的系统如何支撑高并发?
& N. v+ O# O" O1 t4 X- o: p47、Java进阶必备:优雅的告诉面试官消息中间件该如何实现高可用架构% ^6 J) H- h9 `. {; i, N, b9 ~
48、「非广告,纯干货」中小公司的Java工程师应该如何逆袭冲进BAT?4 J) x5 u" N0 d1 i7 R2 \
49、拜托,面试请不要再问我分布式搜索引擎的架构原理!
- ?. ~% K! \# J: v$ d50、互联网大厂Java面试题:使用无界队列的线程池会导致内存飙升吗?2 v& z. B, T# x7 ]
51、「码农打怪升级之路」行走江湖,你需要解锁哪些技能包?# X" k5 c8 V$ N5 n% B5 ?
52、「来自一线的血泪总结」你的系统上线时是否踩过这些坑?- ?0 p2 g* \9 z v+ `* a( u+ S c
53、【offer收割机必备】我简历上的Java项目都好low,怎么办?
e% ^6 u. j' {: N3 i4 p$ M54、【offer去哪了】我一连面试了十个Java岗,统统石沉大海!' K$ k" U0 H! v' ~- {/ _1 ~
55、支撑日活百万用户的高并发系统,应该如何设计其数据库架构?
5 `% d+ R% x, S56、高阶Java开发必备:分布式系统的唯一id生成算法你了解吗?. W- T& m9 \+ x* [
57、尴尬了!Spring Cloud微服务注册中心Eureka 2.x停止维护了咋办?
2 G/ X9 s" H, c1 F) P' }7 _; ~+ Y2 _$ o58、【Java高阶必备】如何优化Spring Cloud微服务注册中心架构?
8 k; Z% w7 o0 v0 m5 x5 s59、面试官:消息中间件如何实现每秒几十万的高并发写入?. ^: R7 m/ y; J, n3 t
60、【非广告,纯干货】三四十岁大龄程序员,该如何保持职场竞争力?
- N/ ]* L6 V5 K0 m6 S! e4 ]61、面试官:请谈谈写入消息中间件的数据,如何保证不丢失?
9 l x& p P( ~2 o62、【生产实践总结】支撑百万连接的系统应该如何设计其高并发架构?/ q1 r' H8 U; b7 n. D" s) V
63、面对BAT大厂的竞争对手时,小公司Java工程师是如何败北的?
$ [0 ]7 D0 ^# ^64、【纯干货分享】小公司出身的我,是如何拿下知名独角兽公司offer
$ h7 H. k1 j; o) ~$ T. F* T2 I4 {% b, T65、用小白都能看懂的大白话告诉你:什么是分布式计算系统?
) K8 C% Z2 ? O+ W- I' Y66、老司机生产实践经验:线上系统的JVM内存是越大越好吗?
R, f. h, h t9 q! p2 O3 p67、Java同学找工作最懵圈的问题:到底啥是分布式系统开发经验?- u- K$ @8 P) ?7 O# t% Q
67、尴尬的面试现场:说说你们系统有多大QPS?系统如何抗住高并发?
; i) k$ k$ i* A& h- B6 A( \3 Q" Y( f68、分享一套GitHub上stars 10000+的Java面试题(含解析)9 `! G0 e- Z+ J( V( \6 s
69、小公司面试10连挂之后,我拿到了互联网一线大厂offer!
2 A! l) F. L$ m( e; X" Z' z70、【架构设计之道】这波操作,会把你的中间件架构带到另一个Level* L+ e: l0 i7 Q6 a, K2 E! {
71、三年努力,梦归阿里!; V P6 K i! w+ ^8 o0 E Q; y
72、阿里三面,P9面试官是如何360°无死角考察候选人的?- o" S' h: B+ n) p. b8 h0 g
73、如果让你设计一个消息中间件,如何将网络通信性能优化10倍以上?/ k2 o/ E* o( L/ ]0 B6 a0 f
74、简历写Kafka,面试官大概率会让你讲acks参数对消息持久化的影响
0 `) H) m+ F( u, W7 q, T75、【嗅探底层】深入揭秘Synchronized在JVM是如何实现的?! [# X1 E/ G9 I% \2 S2 ~( _
76、面经分享:斩获7枚offer,入职阿里平台事业部!6 Z! K" o1 m* @$ O: P
: H, p0 C4 p; `6 j& ]来源:https://www.toutiao.com/a6687543307867783691/& \, M0 n6 K D/ {
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|