The mathematics behind Hadoop-based systems
我希望一年前就知道这些。现在,用一些简单的数学公式就可以表述这些了。
§ 为什么当处理能力加倍的时候工作流时间没有加倍?
§ 为什么10%的任务失败率能导致我的运行时间增长300%?
§ 为什么优化工作流的30%可以导致任务运行时间减少80%?
§ 集群里应该有多少机器来达到容错和高效能?
所有这些问题都可以用一个简单的等式来表述:
Runtime= Overhead / (1 - {Time to process one hour of data})
运行时间=开销/(1-{一小时处理数据所需时间})
我们可以推导出这个公式。首先,通过“一个基于hadoop的系统”来简单描述下。一个hadoop的用例,处理连续的输入数据流。这个数据流使用"while(true)"实现,数据流每次迭代处理上一次累加好的数据。
下述分析的灵感来源可以以一个简单例子来说明。我们说,你有一个需要跑12个小时的工作流,并且他每次迭代处理12个小时的数据。现在我们说你通过一些额外分析来加速了工作流,你评估分析增加两个小时的运行时间给你的工作流。问题就在这里,你的工作流可能会增加不止两个小时的运行时间。他可能增加十个小时,100个小时,或者工作流可能会慢慢失去控制或者每次迭代增加无限定的时间。
为什么呢?
这个问题就是你把一个工作流从12个小时增加到了14个小时。这意味着下次这个工作流运行时,将会有14个小时的数据要处理。下次这个迭代需要更多的时间,他就会跑的时间更久。这意味着下次迭代就会有更多的数据,以此类推。
为了看看运行合适能够稳定,我们做一些简单数学运算。首先,咱们写一个单次迭代工作流的运行等式。
Runtime= Overhead + {Time to process one hour of data} * {Hours of data}
运行时间=开销+{处理一小时数据所用时间}*{总耗费小时时间}
开销指的是工作流内耗费的常数时间。例如,为了启动一些任务耗费的时间开销。使用分布式缓存分发文件所用的开销。任何独立于数据所耗费的时间都会归结到“开销”的门类下。
“处理一小时数据所用时间”指的是工作流内的动态时间。这是你花费处理实际数据所耗费的时间,忽略常数时间开销。如果单位小时增加了半个小时到你的运行时间内,这个值就是0.5.如果单位小时增加两个小时到你的运行时间内,这个值就是2.
T = O + P * H
为了决定工作流的稳定运行时间,我们需要找出工作流的那个时间点等于需要处理的固定时间数据。为了这样做,我们仅仅加入T=H来计算T:
T = O + P * T
T = O / (1 - P)
这个公式之前展示过。你可以看到,一个工作流的稳定运行时间线性等比于工作流的开销时间。所有如果你可以减少开销25%,你的工作流将会减少25%的运行时间。然而,工作流的稳定运行时间飞线性等比于动态处理效率“P”。一个含义就是效率提随着每个加入集群的机器而递减。
Withthis equation we can answer all the questions I posed at the beginning of thisarticle. Let's go through them one at a time:
通过这个公式我们可以解答这篇博客里的很多问题,现在开始过一遍:
为什么当我使用的处理能力加倍的时候我的工作流时间没有加倍?
机器数量加倍将会减少“一小时处理数据时间”(P)50%。这个作用于你的运行时间完全取决于你之前的值P。我们用数学公式展示一下。我们称为加倍集群数量之前的集群大小为“T1”,加倍后的集群数量为“T2”。这就给我们了两个数学公式。
T1 = O / (1 - P)
T2 = O / (1 - P/2)
加速通过T2/T1,比率新运行时间于之前运行时间,得到:
T2 / T1 = (1 - P) / (1- P/2)
T2 / T1 = 1 - P / (2 - P)
画出凸显,我们得到一下图线,x轴上的原点P和y轴的加速比:
这个图就说明了一切。如果你的P很高,例如54分钟动态时间花在每单位小时数据,这样增加集群数量一杯将会使得运行时间变为以前的18%,加速比82%。这是一个计数很直观的结果-我很推荐读者仔细思考一下这种机制的作用规律。
再次,如果你的P不是很高(例如,六分钟花在每单位小时数据上),加倍集群数量将会影响运行时间-仅仅有6%差不多,这意味着开销是由开销所决定的,这样动态时间将会对运行时间产生很大影响。
为什么10%的失败率会导致运行时间增加到300%?
这个问题强调了工作流稳定行。在一个大集群中,你总是会有各种各样的机器失败,所以激增的失败率不互惠影响到核心任务系统的效率。对于这个问题的分析相似与最后一个问题,除了我们让动态处理效率变得得下而不是提高他。一个10%的任务失败率意味着我们仅仅需要执行11%的更多任务来处理任务。既然任务独立于我们要处理的数据,这意味着我们“处理单位时间数据”(P)将会增加11%,在失败发生前的运行时间T1,T2位运行时间发生后:
T1 = O / (1 - P)
T2 = O / (1 - 1.11*P)
T2 / T1 = (1 - P) / (1- 1.11*P)
画出图线,我们得到了:
可以看出来,失败效果随着集群中“额外能力”运行时间激增。所以保持P处于很低的为止很重要。我们可以从这个曲线看到,你的P越高,随着失败率提升,你需要冒着越大的风险来进入一个“死亡循环”。
How does optimizing out30% of my workflow runtime cause the runtime to decrease by 80%?
为什么优化工作流时间30%导致运行时间降低了80%?
这个问题实际上让我去找出这个工作流运行时的原型。我有一个工作流的瓶颈,会有10个小时的开销,整个运行时间会有30个小时。在我优化了瓶颈之后(30%的运行时间),运行时间直降到6个小时(80%时间减少)。使用我们的模型,我们看看为什么会这么发生:
30 = O / (1 - P)
6 = (O - 10) / (1 - P)
O = 12.5, P = 0.58
所以这10个小时占据了工作流的80%的工作开销,这就解释了为什么增速明显了。
我的集群应该有多少机器来充分提高效能并容错?
在基于开销的分析中很重要的练习。我们看到增加集群的数量可以提高性能上的提升,一次P(“单位小时数据”)降低了30分钟)(0.5),性能会随着增加的机器数量线性提高。我们可以看到如何保持P处于低位,或者失败率增加或者其他任务的利用集群都会沿用影响你的任务运行。从这里可以看到,你最好针对应用来跑一些最有数量机器来提升性能。