TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
在Zen And The Art Of Scaling - A Koan And Epigram Approach中,Russell Sullivan提出了一个非常有趣的总结:软件开发常见的20个传统的系统瓶颈,这听起来像是说有20个故事情节,并且依赖于你如何策划这些故事,或许都是真的,但唯有实践才知道它们带给我们的酸甜苦辣。
# e3 _; N3 g, _8 {0 U! l/ ?+ f- }6 W$ k# I7 h+ A0 ?
有一天,Aurelien Broszniowski给我发了一份电子邮件,把这些瓶颈用列表的方式展示出来。在接下来的交谈过程中,我又把该列表抄送给了Russell,Russell对此列表进行了整理。
; A) ~$ ?" O# M4 a5 Q
: t4 G2 @1 Z' v
& y" A1 a' o& |6 v& D7 M
7 g6 B5 \; d: w
: i' n4 W$ G q9 T$ i: pRussell说:“我真希望在年轻时看到这样的一份列表”。伴随着经验的增长、项目的增多、解决各种不同类型的问题和不断总结各种经验教训,你会在这份列表上添加更多的东西。所以,当你在阅读该份列表时就像是在回顾一个个故事片段。' @- L K" v) X( Z
- d1 l# V6 q$ `0 |" X, q数据库8 g6 U! g5 s& P [) z& p
' F+ y6 |% V6 C: O
工作任务内存超过可用的RAM内存' b$ e4 `# K& x! E5 b: M1 H! q( g. G! e
长/短查询3 f# C4 h& q1 m" l
写入冲突# P) e) G# A' D# v
大连接(join)占用内存 Q* u E" h9 P4 n, m: G. ^
虚拟化
3 Q) ^ I+ |; s" l) V! Y6 m' k* _4 M# W F" P1 e. A; _
共享一个HDD、磁盘寻死(disk seek death)3 k9 V% G3 \! R f, E4 T( w* o
在云端网络I/O波动
: c. g; s, B9 g4 H+ J9 l* Y编程5 J5 Q* X# L* s
3 M( M( P9 p0 ~! d L线程:死锁、调试、非线性扩展等
: |# m6 L3 p9 W+ i2 r4 l& f2 W事件驱动编程:callback()过于复杂、如何在函数调用中存储有状态等# V- @5 I i5 M: I
缺乏调优、跟踪、日志等 u- f1 g0 y& o5 b7 V% ~
单模块不可扩展、单点故障(SPOF:Single Point Of Failure)、非横向扩展等1 ^- R1 H8 Z. D, R/ @
有状态应用程序
) R4 o. h+ q! ~' G, S设计问题:开发的应用程序只在自己的机器行运行正常,或者只是在几个人测试的时候正常(没有经历压力测试)。
% [% J9 F7 q ^ {! H2 ~算法过于复杂4 C0 P" m) F6 t7 P+ n1 H$ u
相关服务,例如DNS查找以及其他可能屏蔽的服务
$ \* X2 y; _, \: l8 l/ o# a; R5 R堆栈空间3 Q9 Q' T4 s) L6 E4 Z/ u
磁盘
4 x" J t7 L2 y' ?; _, R; D4 z7 n4 Y6 _, l
访问本地磁盘
, _. |+ {8 |' Z9 }; Z! b( g随机访问磁盘I/O
' C r7 O+ n" w磁盘碎片
2 W! Y" C$ \* k9 R当SSD写入的数据大于SSD容量时,性能会下降; [+ c- {/ t3 J$ B2 j
OS1 U0 l+ K9 e9 h, c; E
' J R7 a2 y5 X+ L6 fFsync饱和,Linux缓冲区填塞(Fsync flushing, linux buffer cache filling up)% t7 _5 w" y+ {2 |" z( G
TCP缓冲区太小0 [1 b/ g8 a+ x. y4 \
文件描述符限制 X+ M3 r+ m( h0 c* @' V2 r
功率分配(Power budget)
; j6 x) R9 k Y) E( E- D缓存
, L% f; u" s7 j6 [6 u6 j3 s$ X# v; M' S! U
没使用memcached(数据库崩溃)& e+ r/ d s3 J+ J* E( f- k. B
HTTP中:headers、etags、没有使用gzip压缩等。
$ U( ?) ]2 {0 [没有充分利用浏览器缓存. Q& C1 q; m) D6 F
字节码缓存(如PHP)0 [6 ~: R0 g3 S# p" E
L1/L2缓存:这是个令人头疼的大瓶颈。把关键并且经常访问的数据存储在L1/L2中。这涉及到很多:snappy网络I/O,列数据库直接在压缩数据上运行算法等。利用一些技术不销毁你的TLB。最重要的思想是紧紧的抓住计算机的体系结构,涉及多核CPU,L1/L2,共享的L3,NUMA RAM,从DRAM到芯片数据传输带宽/延迟,DRAM缓存的DiskPages,DirtyPages,流经CPU<->DRAM<->NIC的TCP包。. W2 d' e% |; c$ G0 B5 Y. N
CPU: ?9 n8 S: N( \1 V% |
* a4 k& h# ?& M$ O, m3 g" U3 u& XCPU过载) v, l( i- j/ X& n' _3 `- t
内容切换—>单核上开启的线程过多、Linux调度器、系统调用太多等
7 ^" Y7 G+ r; YIO等待—>所有的CPU在同速等待
/ N& R) Z8 }/ U. s ], ECPU缓存:缓存数据是一个细粒度进程,为了在多个实例与不同的值数据之间找到正确的平衡,来保持缓存数据的一致性和繁重同步。# q% z& m" L7 y# c& }) S5 a, s3 T
底板吞吐量(Backplane throughput)7 O* a# t; W Y6 N; Z: z) Q
网络! W7 E* v0 a- U
w( e) z" K: Z8 S1 h% }
NIC刷爆、IRQ饱和、软中断占用掉了100%CPU& V1 `! |6 S0 g) h
DNS查询, E4 ]- z% o2 Q
数据包丢失
. d3 s3 |3 K. l, z9 e6 Q网络中存在预期外的路由
9 c6 }/ W8 G! C2 r访问网络磁盘
- L& \2 @' M( S共享SAN2 u- K4 w% ~8 ^: P i
服务器故障—>无法从服务处得到响应
7 `1 a' d2 p- m3 e4 R进程3 U+ f. E* ]; c5 H. Y6 y2 W$ u
3 ^3 I [5 o; s/ ^测试时间$ o1 @, ?0 R0 n \, P$ W. y4 ]
开发时间
3 F$ m0 r: I3 ~; e/ L7 T团队规模
8 e" q" K& @: M( }. t预算# _- o" T1 }; K0 D1 b
代码债务
6 F- g1 C4 }$ J, z6 X1 h; b4 _2 \1 l内存
5 c9 m/ U7 I( m/ m, k, W
3 r4 S/ ~* ]; N4 Y* ]% s) B内存不足—>杀死进程,切换到swap,挂起/ I4 K' k2 u& Y( g% z/ ^
内存不足导致磁盘交换(与swap相关)$ v: n5 W$ Z$ V: C B+ K" G& V
记忆库开销过大(Memory library overhead)
* r3 x) w9 s0 U1 v$ v; M内存分片(在java中需要会因为内存回收而停顿;在C中,malloc总是开始分配内存)- v, F, W$ x4 w$ o
1 E0 `1 E }1 \) G4 J原文:http://highscalability.com/blog/ ... on-bottlenecks.html
" y1 o' A1 n0 j
e' Q1 ^8 o% y8 J6 } |
|