进行大规模计算是很困难的,要处理大规模数据需要将数据分布到多台机器上并行处理,第当多台机器之间需要协作时,失败的几率就很升高。
在单台机器环境中,失败并不是设计者经常关心的问题,因为机器崩溃了,反正是无法将程序恢复的。
但在分布式环境中,局部失败是经常会发生的,比如网络会因为交换机和路由器崩溃局部失败或全部失败;数据有可能因为意外的网络阻塞没有按时到达特定结点;运算结点可能因为过热导致磁盘崩溃或用完了内存或磁盘空间;数据可能出错,也可能传输时发生错误;不同实现或不同版本软件在使用协议时有细微的差别;时钟可能变的不同步;锁文件可能没释放;可能在分布式不可打断的传输时受到干扰,导致网络连接中途断开,等等。
在上述每一种情况下,分布式系统的正常工作部分应该可以从失败中恢复,或使用户不需要关心这些错误,也可以继续正常工作。显然,提供这种弹性是软件工程的巨大挑战。
不同的分布式系统会着重处理不同的几种失败,而不太关注另外的失败类型。
Hadoop没有提供安全模型,也没有防止恶意插入数据的安全机制,比如它无法控制一个在结点间的攻击,然而,它在硬件失败和数据阻塞方面的设计非常健壮,其它的分布式系统数据它们所要处理的问题(比如,高安全性)需求做出了不同的权衡。
在考虑上述的bugs和挑战之外,我们还需要意识到,计算硬件都只有有限的资源,主要的资源包括:
- 处理器时间
- 内存
- 磁盘空间
- 网络带宽
单台计算机通常只有几G内存,如果输入数据是TB级的,那就需要上千台计算机才能将这些数据放入内存,即便如此,但是单台计算机仍无法处理和寻址这些数据。
磁盘的空间要多的多,单台机器的磁盘空间现在有几TB左右,但在大规模计算中,计算机产生的中间数据通常是输入数据的几倍,这也就将占有输入数据的几倍磁盘空间。在处理过程中,一些结点磁盘满了,分布式系统也许需要把这些数据传输到其它可以保存这些溢出数据的结点上去。
最后,即使在内网名,带宽也仍是稀缺资源。
假设一组结点用千兆以太网连接,也许它们之间的有很高的传输速度,但如果所有的结点同时传输几G的数据集合,这样很容易使交换机带宽饱和。
另外,如果机器都分在多个主机架中,那么可用以数据传输的带宽就会更少,更严重的是,用这个信道的RPC请求或其它数据传输请求会延时或被丢弃。
故一个成功的分布式系统必须能高效地使用上述资源,更重要的是,它在分配这些资源时,应将系统视为一个整体,将尽可能多的时间用于核心计算。
多台机器之间的同步仍是分布式系统设计的最大挑战,如果结点在分布式系统中可以直接交互,那么设计者必须认识到交互模式所带来的危险,它很容易产生超出系统所能承受的RPC调用!进行多方数据交换也会引起死锁和竞争。
最后,在面临部分结点失败时,保持继续计算的能力是一个更大的挑战,比如,一个系统中有100个结点,其中一个崩溃了,但其它99个结点仍能继续计算,理想情况下,系统只是损失了1%的计算能力,更进一步,如果在分布架构上采用了复杂的交互网络,那么决定如何重新计算失败结点的任务是最好,和通知网络拓扑的改变信息,也许是实现的重要部分。