知识卡片

排查法识别复杂度:用峰值TPS/QPS估算与后果严重性代替直觉判断

普通读书笔记卡

内容

原始需求里通常不会明确写出”这里有一个高性能复杂度”,识别复杂度必须靠架构师自己分析;经验不足时可以用”排查法”——从高性能、高可用、可扩展性等维度逐一定量核实,而不是凭直觉拍脑袋。判断是否需要高性能的关键技巧是:不要被一天的总量数字唬住,而要换算成每秒的峰值TPS/QPS。以书中”前浪微博”消息队列案例为例,假设每天产生1000万条消息、平均每条被10个子系统读取(约1亿次读取),换算到每秒平均写入约115条、平均读取约1150条;但设计目标不能按平均值算,要按峰值算(峰值一般取平均值的3倍),再考虑业务增长要留一定容量余量(可取峰值的若干倍,书中案例取4倍,不同业务可以是2倍或8倍,但一般不宜超过10倍,更不要一上来就按100倍预留),最终案例中的设计目标是TPS 1380、QPS 13800——这里TPS不算高但QPS已经偏高,因此判定高性能是复杂度之一。判断某个复杂度”算不算高”离不开对常见系统性能量级的经验参照(如Nginx负载均衡约3万、Memcache读取约5万、Kafka号称百万级、ZooKeeper读写2万以上),但更重要的是要针对具体业务实测建立自己的性能基线,而不是套用别人的数字,因为不同业务的复杂度差异巨大,有的系统每秒500个请求就已经是高性能场景了。判断是否需要高可用则要看”出问题的后果有多严重”:消息队列案例里,审核子系统丢消息可能导致触犯法规,后果非常严重;等级子系统丢消息只是VIP用户体验受损、可能导致用户流失,后果相对较轻但依然关键——两者共同结论是这套消息队列的写入、存储、读取都需要高可用。判断是否需要可扩展性则要看功能本身未来是否有变更预期:案例中消息队列的功能边界很明确、基本不需要扩展,因此可扩展性不构成这个系统的复杂度重点。三个维度逐一排查后再综合,比笼统地问”这个系统复杂不复杂”要可靠得多。

参考来源

- 位置:《从零开始学架构》第10讲《架构设计流程:识别复杂度》"识别复杂度实战"(源文件:_epub-src/OEBPS/text00000.html) - 结论依据:原文给出前浪微博消息队列的峰值换算过程"峰值一般取平均值的 3 倍……我们将设计目标设定为峰值的 4 倍,因此最终的性能要求是:TPS 为 1380,QPS 为 13800",并分别用审核子系统与等级子系统丢消息的后果severity对比来判断高可用必要性,用"消息队列的功能很明确,基本无须扩展"判断可扩展性不是复杂度重点,作者回复中补充"nginx负载均衡性能是3万左右,mc的读取性能5万左右,kafka号称百万级,zookeeper写入读取2万以上"作为经验参照,直接支撑本卡片结论。 - 原始内容:峰值一般取平均值的 3 倍,那么消息队列系统的 TPS 是 345,QPS 是 3450……我们将设计目标设定为峰值的 4 倍,因此最终的性能要求是:TPS 为 1380,QPS 为 13800……综合来看,消息队列需要高可用性,包括消息写入、消息存储、消息读取都需要保证高可用性……消息队列的功能很明确,基本无须扩展,因此可扩展性不是这个消息队列的复杂度关键。