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个故事情节,并且依赖于你如何策划这些故事,或许都是真的,但唯有实践才知道它们带给我们的酸甜苦辣。
+ c/ U; l' T! t4 H/ U8 x3 l8 l, ]; [
有一天,Aurelien Broszniowski给我发了一份电子邮件,把这些瓶颈用列表的方式展示出来。在接下来的交谈过程中,我又把该列表抄送给了Russell,Russell对此列表进行了整理。
8 O. ~0 ?5 X# O1 ~$ p6 Y( L. { J( X; a8 P1 n: u0 ]
2 l* k/ R# f# _$ p9 C
; R7 I0 f" l: Z2 r. f9 S
/ Q% \" z; Z c4 x# ]3 zRussell说:“我真希望在年轻时看到这样的一份列表”。伴随着经验的增长、项目的增多、解决各种不同类型的问题和不断总结各种经验教训,你会在这份列表上添加更多的东西。所以,当你在阅读该份列表时就像是在回顾一个个故事片段。
- ~* ]+ g; ^0 |9 b2 Y4 }+ P6 ^1 x \+ S- g* w! v5 F
数据库
' {! E, V7 O6 c( p+ j
5 z$ R' T1 Y6 f+ H/ F4 v工作任务内存超过可用的RAM内存
% v( ^' Y/ T! X0 Q: r- a% m长/短查询
2 j/ K8 H! C( M# X写入冲突. l9 A e. X& W" q/ }
大连接(join)占用内存2 h; t- m" _0 k& o& B2 z% c) y9 r E# }
虚拟化
* E! h" ?5 D$ r8 C! T
2 T4 u8 l7 n0 g2 n! ^共享一个HDD、磁盘寻死(disk seek death), R4 q W8 K# m
在云端网络I/O波动
/ ], E; K4 [* q( d编程
0 V' ^" I8 f3 c6 e: }" Y
; f. i# b# _: x, k线程:死锁、调试、非线性扩展等' h* m+ Y/ y+ G' F; f8 t2 S! ~
事件驱动编程:callback()过于复杂、如何在函数调用中存储有状态等; x4 ~( q8 g; @: _! P, O" t! L
缺乏调优、跟踪、日志等
3 y6 l) E9 V$ E9 e* l; u单模块不可扩展、单点故障(SPOF:Single Point Of Failure)、非横向扩展等$ K# `$ r' U+ A u4 ?, q4 T
有状态应用程序9 q9 {+ {$ n5 r
设计问题:开发的应用程序只在自己的机器行运行正常,或者只是在几个人测试的时候正常(没有经历压力测试)。! a' f$ ^% f0 L% X- e
算法过于复杂1 U, M$ E6 S: g3 S# e2 c1 }0 S
相关服务,例如DNS查找以及其他可能屏蔽的服务2 J7 U( s3 |4 b7 S" r" r; T/ ?- o J7 L
堆栈空间
" b1 E8 ?) Y. m- o$ R" i2 I, E磁盘
; b- v! g; J( \0 _0 \" t
' M; r) ]9 l$ p5 n( {0 p访问本地磁盘$ a* H q( [8 I, Z0 [
随机访问磁盘I/O p2 @; H, `" X3 V( q K
磁盘碎片& \! ]1 L) c* p+ \* l6 U
当SSD写入的数据大于SSD容量时,性能会下降
6 [8 c; c: \0 y6 _6 g' AOS) R* [% X8 q! L) O' a6 R* d+ ]6 j. B/ e
( p9 p' c: C1 ~- A: D% T
Fsync饱和,Linux缓冲区填塞(Fsync flushing, linux buffer cache filling up)
* g& r8 J; Z' z- ]1 j/ s" {TCP缓冲区太小
+ j$ A7 t& B4 p T- ?- H/ Q0 w9 _# a文件描述符限制/ ?4 z0 Z! Y" b1 A9 P4 K. e
功率分配(Power budget)' C; ? x% |/ q
缓存1 m9 ]( e5 K3 j0 P- M
1 g; `3 o! N: A/ w没使用memcached(数据库崩溃)
$ ^3 W m# [( z% ?& Q+ u# u" }) YHTTP中:headers、etags、没有使用gzip压缩等。% p8 x1 I* a0 P0 _# ]
没有充分利用浏览器缓存
/ H- ^1 H3 V/ X2 X* L字节码缓存(如PHP)! H2 Q( w# m% w( f+ r" J
L1/L2缓存:这是个令人头疼的大瓶颈。把关键并且经常访问的数据存储在L1/L2中。这涉及到很多:snappy网络I/O,列数据库直接在压缩数据上运行算法等。利用一些技术不销毁你的TLB。最重要的思想是紧紧的抓住计算机的体系结构,涉及多核CPU,L1/L2,共享的L3,NUMA RAM,从DRAM到芯片数据传输带宽/延迟,DRAM缓存的DiskPages,DirtyPages,流经CPU<->DRAM<->NIC的TCP包。! b! Q6 T/ S' `- ?6 X1 S/ N
CPU* \4 u ?1 x l6 B) N
" V6 q4 d/ X" m! tCPU过载" [+ h8 r/ G' f6 v& @
内容切换—>单核上开启的线程过多、Linux调度器、系统调用太多等" h6 o- e4 O. h+ J/ l2 j* E9 O
IO等待—>所有的CPU在同速等待
, x6 l: R y; HCPU缓存:缓存数据是一个细粒度进程,为了在多个实例与不同的值数据之间找到正确的平衡,来保持缓存数据的一致性和繁重同步。
, ]. `) u V- O! ?底板吞吐量(Backplane throughput)
9 m9 f; H) f! F' k网络4 {+ o, r5 _/ _( \8 j5 P3 d2 _
1 `0 y9 i& D: c& A; _- `: d
NIC刷爆、IRQ饱和、软中断占用掉了100%CPU
6 D- O4 Q- `/ f% G+ J7 F3 M9 HDNS查询
5 O+ T2 i- e# z E& M8 I" J/ Q数据包丢失% ~3 ~5 h( n' l
网络中存在预期外的路由- `3 p/ l) {8 y# H: t& t$ k, t1 p
访问网络磁盘* k* k" B) {3 K% r4 }3 V
共享SAN
. w! K* A$ F! M O+ }) a, Q% u服务器故障—>无法从服务处得到响应
' I) s( \" X; G: L& H进程% k8 i1 m Y) V
* L7 x7 f. v0 l9 }+ f
测试时间
/ B. ` Q* f( K开发时间
% ~) i. O6 z( ]5 c' q+ `团队规模
5 P+ ~& Q' p: ^1 F预算0 |5 b( f( @) c
代码债务! w. T6 q% E% R
内存
# Q+ a# C7 e {4 R2 S% S Q
! j& a2 u! ]6 \( i% G/ i内存不足—>杀死进程,切换到swap,挂起( f; j1 U' `; a( ?5 C
内存不足导致磁盘交换(与swap相关)6 }% v4 X ]1 @6 g
记忆库开销过大(Memory library overhead)) g/ \! d* S' N D
内存分片(在java中需要会因为内存回收而停顿;在C中,malloc总是开始分配内存)
6 x8 \2 D6 ]3 T3 `) l) C$ Y0 ^5 d
% ^- k# t1 b' j+ v1 `+ B原文:http://highscalability.com/blog/ ... on-bottlenecks.html$ I, T$ N3 g1 C. O
e, d, L( Q* {2 D7 Q/ \ |
|