对于一个给定的问题,你怎么判断哪个设计是最优的呢?举个例子,比如现在给你问题,需要生成一个包含30张缩略图的搜索结果页面,你会怎么做?按顺序一个一个读取图片?或者是并行读取?你会使用缓存吗?你会怎么决定?
如果你可以利用“power of the multiverse”,你可以尝试每种设计,最终确认哪个设计是最优的。但是这是不可能的,对吧?
另外一个选择是你可以考虑各种算法替代的顺序(order of various algorithm)。作为Computational Thinking黄金时代的先驱者,Google绝对会这么做,但是还可能会怎么做呢?
使用 Back-Of-The-Envelope 方法评估不同的设计
作为Google基础建设学院院长(该学院在Google的很多关键系统起到了重要的作用,包含:广告系统、Big Table、搜索、MapReduce、ProtocolBuffers),Jeff Dean 倡导使用 back-of-the-envelope 方法来评估不同的设计。他在 Stanford video presentation 该演讲里面讲述了他的完整的想法。
Back-of-the-envelope 估算法是使用思想实验和常见的性能数字组合而成的估算法,以便更好地估算哪些设计可以满足你的需求。Dr. Dean 认为有一个重要的技能是每个软件工程师都必须掌握的,那就是用 Back-of-the-envelope 估算法评估每个替代系统的性能,而不是构建好系统再去测试性能。
他在视频中给出了一个非常好的例子,但是首先……
你得知道这些数字
要评估备选设计方案,首先你得对这些典型的操作的耗时有个基本了解。Dr. Dean 给出了下面的列表:
-
L1 cache 的引用耗时 0.5ns
-
分支的错误预判的耗时是 5ns
-
L2 cache 的引用耗时 0.7ns
-
互斥的锁与解锁耗时 100ns
-
Main cache 的引用耗时 100ns
-
使用Zippy压缩 1K bytes 数据耗时 10000ns
-
使用1G 带宽的网络发送 2K bytes 数据耗时 20000ns
-
从 memory 串行读取1MB 的数据耗时 250000ns
-
从同一个数据中心往返耗时 500000ns
-
磁盘寻道耗时 10,000,000ns
-
串行从网络读取 1MB 数据耗时 10,000,000ns
-
串行从磁盘读取 1MB 数据耗时 30,000,000ns
-
从 CA到 Netherlands 再到CA,传输网络包 耗时 150,000,000ns
以下是需要注意的事项:
-
注意不同选项的性能表现的量级差异
-
各个数据中心都是相隔比较远的,因此传输数据耗时很久
-
相对来说,内存读取很快,磁盘比较慢
-
通过使用廉价的压缩算法,可以节省很多的网络带宽(2倍)。
-
写数据的代价是读数据的40倍
-
全局共享数据的代价是昂贵的。这是分布式系统的基础决定的。大量共享对象的写入操作带来的锁竞争会导致性能下降,transaction变得序列化而且缓慢。
-
支持动态扩展写操作的架构
-
对较低的写操作的竞争的优化
-
大范围的优化。尽量让写操作并行处理。
例子:生成一个包含30张缩略图的搜索结果页面
这个是视频里面提及的例子。两种设计方案被用在了设计思想实验。
第一种设计:串行
-
串行读取图片。磁盘寻道。读取一张256K的图片接着再去读取下一张。
-
性能:30 次寻道 * 10ms/seek + 30 * 256K / 30MB/s = 560ms
第二种设计:并行
-
并行读的问题
-
性能:10 ms/seek + 256K read / 30MB/s = 18ms
-
磁盘寻道的速度都不一样,所以合理估算为 30 - 60 ms
哪一种设计更好?取决于你的需求,但是使用 back-of-the-envelope 估算法你可以很快的这两种方案而不是真的去构建系统。
现在,你有了一个框架,你可以问你自己其他的设计问题,并且比较不同的设计变化:
-
有必要做缩略图的缓存吗?
-
应该在一个entry里缓存好一整套的图片吗?
-
有必要对缩略图进行预计算吗?
你必须了解你的设备的性能,才能让你的估算更贴近现实。如果过程有一个未知的变量,那么你可以快速的原型化那个变量以解决该问题。比如,你要知道缓存是否是一个好的设计,你必须了解你的缓存写入耗时是多久。
学习总结
-
通过 back-of-the-envelope 估算法你可以大致了解不同设计的变化
-
当设计你的系统的时候,你应该在大脑里不断地进行这些计算。
-
对于你的系统的模块,必须了解上文提及的 back-of-the-envelope 估算法必备的一些基本数字。了解基本的性能指标数字还不够,你还必须了解你的子系统的表现。不了解系统的运转,就不可能做好 back-of-the-envelope 估算。
-
监控并且测量你的系统的每个部分,这样你才能从实际数据中进行不同类型的projections。
我个人非常喜欢这种方法。这种方法在 end-to-end nature 系统中更加接地气( It seems much more grounded in the end-to-end nature of a system than is common.)。The practice today is to focus on the trickeration of various algorithms, which are really a researchable and pluggable part of this larger, more holistic analysis.
网友评论