以下是分布式系统中的八大误区:
- 网络是可靠的。
- 网络是无延迟的。
- 带宽是无限的。
- 网络是安全的。
- 网络的拓扑是不变的。
- 系统管理员只有一个。
- 传输数据的成本为零。
- 所有网络是同构的。
本文会解读上面的八个误区,并探寻它们与现代分布式系统之间的关联。
网络是可靠的
第一个误区是“网络可靠”。为什么这个是误区?你上一次碰到交换器宕掉是什么时候?毕竟,现在的交换机都有着5w个小时的MTBF (平均100台机器一年会有17台会出故障)。如果你的应用是那种要求全年无休运转的,那么你一定会遇上这种异常,同时墨菲定律会确保异常发生在最不合适的时机。但是,并不是所有应用都有那么严格的运行要求。所以,问题出在哪呢?
首先,在系统中存在大量的异常:电源问题,网卡中的缺陷,或者大量的客户端在一瞬间的并发访问(罗志祥),等等。如果硬件性能不足,软件同样会出现问题,并且这是确实出现过的。
而且,当你对接外部系统后,场景会变得更加复杂,比如一个电子商务系统对接了外部的一个信用卡服务。对方的系统并不在你的直接控制下,系统可能会遇到一些安全问题,如DDOS等等。
那么在你的设计中,这些又意味着什么呢?
从基础设施层面上看,你需要考虑硬件和软件的冗余,还要权衡系统异常和额外投入之间的平衡。
从软件上来看,在通过网络传输消息时,你需要无时无刻的考虑网络异常。一般来说,可以使用诸如 WebsphereMQ 或者 MSMQ 等提供可靠网络传输的平台。如无法使用,就需要考虑到重试,识别重复的消息(或者使用幂等),顺序性问题(或者让程序不依赖于消息的顺序),验证完整性,等等。
这里有一个关于 WS-ReliableMessaging 的说明:这个规范支持不同等级的消息保证--至多一次,至少一次,有序。你需要切记他只能在网络节点存活并正常运行时才能做到以上几点,他并不保证持久化,这就需要应用程序去做(或者换一个适合的解决方案)。
总结起来,网络是不可靠的。我们的架构和软件要去适应它。
网络是无延迟的
第二个对分布式系统的误区是假设网络是无延迟的。延迟是什么,延迟是将数据从一个地方运输到目的地所花的时间(带宽是同一时间内能传输数据的多少)。在局域网环境下,延迟会低一些,但是,一旦应用迁移到WAN环境,延迟就会变得很大。延迟往往比带宽更要麻烦。Ingo Rammer在博客《延迟VS带宽》中说的很好:
在过去的11年内,端到端的通讯,带宽增长了1468倍但是延迟(ping所用的时间)却只提升了一个数量级。如果前面的说法说服力还不够,那么换个角度。延迟是有“血统上限”的。在地球上任意两点信息传输的最小耗时取决于信息的最大传输速度-光速。约三十万公里每秒,所以从希腊发送一个ping请求到美国的服务器,最少也需要30 milliseconds,即使中间所有的路由器都能够实时处理。
你也许会这样想:如果我的应用只部署在局域网下,是不是就没有问题了呢?但是,即使你的应用使用千兆以太网通讯,网络间的延迟也要远高于本地IO。在零延迟的假设下,跨网络的通讯所耗费的时间等同于本地调用,在分布式系统之间的网络透明性会诱使你做大量的远程调用(但其实际成本相对而言远高于本地调用)。
将延迟计入考虑意味着你在编码时要更谨慎的使用远程调用,并且在带宽足够的情况下(后面会谈带宽的问题),你会尽可能多的在一次请求中传输尽可能全的数据。
AJAX 是一个应对延迟的典型例子。AJAX允许在用户无感知的情况下从服务器获取更多数据来渲染客户端。但是,你还是需要考虑延迟。假设你们的系统使用了AJAX来进行前后端交互。在测试环境,一切都很正常。在部署之前,所有的测试用例也都正常运行。应用仍然会在你未测试延迟场景时崩溃。从后台获取数据固然好,但如果延迟增大时,仍然会造成应用无响应。
可以(应该)使用工具如 Shunra Virtual Enterprise, OpenetModeler或者其他网络模拟然健去了解系统的行为去避免生产环境中的异常。
带宽是无限的
下一个误区就是“带宽是无限的”。这个观点在我看来,错的并没有其他几个那么离谱。因为带宽在网络的发展中,是会越来越好的。
但是,之所以说这个观点是错误的,原因有二。
一是随着带宽的增加,我们使用网络传输的数据也渐渐变大。VoIP,视频,IPTV等新应用会占据带宽。资源下载,越来越丰富的UI,使用了冗长格式(XML)的软件还在运行。特别是你使用T1或者更原始的线路时。但是,当你认为万兆网络已经远远够用时,你也许会遇到3T/天的新数据。
二是丢包问题。下面的引用会进行详细说明
“在本地网络或者大学校园里,影响到系统性能的瓶颈在于裸带宽,发包速度,服务器CPU等其他元素,而非rtt和丢包。在WAN环境下,rtt和丢包会变得突出,而且是你系统无法控制的。因此,对于广域网下的优化,只能寄希望于扩大包大小。”
举个例子:纽约到洛杉矶。rtt在40msec,假设丢包率为0.1%,MTU为1500字节,MSS 是 1460,TCP的吞吐量的上限在6.5Mbps左右。而且,在这个CASE下,瓶颈在于TCP拥塞检测。当我们把窗口大小调整到9000字节,TCP的吞吐量可以达到40Mbps。
我们来分析一下丢包率。在相同的网络环境下,假设我们想要达到500Mbps的吞吐量(半G)。在9000字节的窗口下,则需要将丢包率控制在10的-5次方。窗口大小在1500字节时,丢包率要控制在2.8*10的-7次方!相同吞吐量时,当窗口扩大6倍,可以容忍丢包率扩大了36倍。
认识到“带宽不是无限”这一点会让你更好的理解“零延迟”。that is, if acting on the realization the latency is not zero we modeled few large messages. Bandwidth limitations direct us to strive to limit the size of the information we send over the wire.
我们要明白生产环境的带宽问题是我们无法控制的,所以要找到环境数据传输的上限。
再上一节提到的建议:尽量模拟生产环境的网络。在这里也同样适用。
网络是安全的
Peter Deutsch 在1991 提出了“分布式计算系统中误区”。你也许会认为在那之后的15年后,“网络是安全的”不再是一个错误。
不幸的是,事实并非如此,因为现在的网络是安全的。没有人会这么天真的以为。Nevertheless, a few days ago I began writinga report about a middleware product some vendor tried to inflict on us that has no regard whatsoever to security! Well that is just anecdotal evidence, however.
Aladdin.com 给出的报告数据显示:
"For 52% of the networks the perimeter is the only defense.
According to Preventsys and Qualys, 52% of chief information security officers acknowledged having a "Moat & Castle" approach to their overall network security . They admitted that once the perimeter security is penetrated, their networks are at risk. Yet, 48% consider themselves to be "proactive" when it comes to network security and feel that they have a good grasp on their enterprise's security posture. 24% felt their security was akin to Fort Knox (it would take a small army to get through), while 10% compared their network security to Swiss cheese (security holes inside and out). The remaining 14% of respondents described their current network security as being locked down on the inside, but not yet completely secured to the outside. Preventsys and Qualys also found that 46% of security officers spend more than a third of their day, and in some cases as much as 7 hours, analyzing reports generated from their various security point solutions. "
为防止你来自一颗“网络不安全的星球”。下面有几组数据可以说明:
通过对财富1000强公司中一百家公司的7*24的监控,RipTech发现了几条信息安全相关的趋势。
- 网络攻击的次数以每年64%的速度增长
- 在过去半年里平均每家公司每周受到32次攻击
- 在过去半年,周末发生的网络攻击在持续增长
当我想找一些其他的数据时,我找到这些:
鉴于自动化网络攻击工具的广泛传播,针对接入网络系统的攻击变得越来越普遍。对于攻击事件数量的上报对分析网络攻击的范围和影响的用处越来越有限。因此,自2004年起,我们不在发布攻击次数的报告。我们开始与社区合作,来统计出更有意义的数据(2003年的网络攻击次数为137539次)。
根据Aladdin最新的报告,2004年度恶意软件(包括病毒,蠕虫,木马等)造成的经济损失在1690亿到2040亿之间。
网络安全造成的影响十分明显。你需要从一开始就要吧安全考虑进你的解决方案。在我之前的博文中有提到过,安全应当作为一个系统质量指标在架构之初就该纳入考虑。有非常多的安全相关的文献可供参考,限于篇幅,这里不再介绍。
首先你需要构建一个风险模型去评估安全风险。然后再去分析哪个风险应该被纳入考虑范围(需要权衡支出和风险发生的概率)。安全问题通常要从多个层面去考虑,包括网络,基础架构,应用层面。
作为一个架构师,你可能不是个安全专家,但是你仍然需要这方面的认识和它们可能造成的影响(比如,you might not be able to use multicast, user accounts with limited privileges might not be able to access some networked resource etc)。
网络的拓扑结构是不变的
第五个误区是“网络的拓扑是不变的”。这句话只有在实验室里的时候才是正确的。
当你将应用部署到生产环境时,网络的拓扑结构往往是你无法控制的。运营团队(IT)可能会不时地添加和删除服务器或对网络进行其他更改(“这是我们将为SSO使用的新Active Directory;我们正在用OSPF取代RIP,这个应用的服务器将被移入51区”,等等)。还有,服务器和网络错误也会导致路由的改变。
当讨论到客户端时,情况会边得更复杂。不断有笔记本接入网络,还有各类的移动设备。简单来说,网络拓扑也在不停的变化。
What does this mean for the applications we write? Simple. Try not to depend on specific endpoints or routes, if you can't be prepared to renegotiate endpoints. Another implication is that you would want to either provide location transparency (e.g. using an ESB, multicast) or provide discovery services (e.g. a Active Directory/JNDI/LDAP).
将网络结构抽象成物理模型同样也是个方法。最明显的例子就是使用DNS去代替IP地址。就在最近,我迁移了博客。迁移过程十分平滑,因为旧网站和新网站运行的都很稳定。然后当DNS刷新时(DNS花了几天时间才全部更新完),路由变化时,用户完全感知不到他们已经在访问新网站了。
还有一个有趣的例子是由WS-Routing迁移到WS-Addressing。在WS-Routing中,消息中包含了路由的路径,这表示你可以提前得到消息的传输路径。路由是不变的(这可能会造成安全漏洞,不过这是后话了)更新的WS-Addressing依靠下一跳路由(就行TCP/IP那样工作)更为可靠。
另外一个例子是SQLServer中Broker的路由。唯一麻烦的点在于需要将路由设置在broker服务中。而IT需要在路由变化时去更新路由表。不过,为了缓解这个问题,路由依赖于下一跳语义,它允许通过DNS名称指定地址。
系统管理员只有一个
第六个误区是“系统管理员只有一个”。当应用运行在一个小规模的,独立的LAN环境下,这个观点便是成立的。但是,对于大多企业级应用,情况更加复杂。
IT部门通常有着多个系统管理员,根据不同的智能去划分- 数据库,Web服务,网络,Linux,Windows,主框架等等。This is the easy situation。当企业开始接入外部系统时(如对接合作伙伴),如果您的应用程序部署为Internet使用,并由某些托管服务托管,而且应用程序还使用了些外部服务。在这些场景下,有些管理员是不受你控制的而且他们还有自己的工作方法。
除此之外,很多管理员可能不是项目组的管理成员之一,我们还需要提供工具去诊断和寻找问题。当多个公司一起协同工作时,这一点显得尤为重要(这个问题是他们的还是我们的?)。监视正在运行的程序同样也是一个积极的应对方法,这样让管理员在问题扩散为系统异常之前之前进行解决。
Another reason to think about multiple administrators is upgrades. 我们该如何处理?我们改如何确保系统的各个模块保持同步并且能够协作。比如,当前的数据库模型是否符合当前的O/R映射?问题在第三方参与时会变得更加突出。比如,当我们修改了一个SOA接口时,是否会影响到外部接入的用户,所以我们在设计对外接口时需要考虑向前兼容。
总之,当系统存在多个管理员时,他们会限制我们的操作余地,并且我们需要帮助他们去管理我们的应用。
传输成本为零
关于这一点,你可以从多个角度去理解它,不过他们全都是错误的。
其中有个错误观点是:数据从应用层到传输层的花费为零。原因在于序列化(将信息序列化为字节)是其中必不可少的步骤,不仅占用系统资源而且还会造成延迟。这一点同时也能证明“延迟不为零”,因为无论如何都存在额外开销(无论从时间还是资源角度)。
第二个错误观点是:使用网络去传输数据是免费的。这是非常荒谬的。这过程中存在很多开销(路由器,网络安全,租赁带宽,网络运行和维护的成本)。总有某个地方的某个人要为这些费用买单。
假设你已经成功搭建了 Dilbert's Google-killer search engine (应用前景及其广泛)。但是如果你忽略服务器运行维护的成本(E3,数据中心,SAN等),你仍然可能会失败。当你认为你已经通过现有的解决方案解决了其他的问题(看,我们使用了Cisco's HSRP 协议解决了网络可靠性问题),这时,费用问题可能会消无声息的靠上来,你就需要一个更省钱的方案。
网络是同构的
第八个,也是最后一个误区就是网络是同构的。
当Perter Deutsch一开始提出前面七大误区时,我找到了James Gosling在六年后提出的第八个误区。
今天的大多数架构师还没有天真到接受这种谬论。任何网络,即使它再小,也可能是异构的。甚至,就在我家,我家有一台基于Linux的HTPC,几台Windows,一个小型的NAS,一个2005的WindowMobile设备,它们通过无线网络可以互联。家庭网络都是如此,更何况在企业里。我相信,如今很少有同构的网络。即使你维护着一个同构的网络环境,在对接到外部服务时,也会出现问题。
假设这一谬误不会在较低层的网络造成太多麻烦,因为IP几乎无处不在(例如,即使是Infiniband这样的专用总线也有IP- over - ib实现,尽管它可能导致对非本机IP资源的次优使用)。
具有“网络是异构的”这个意识是非常具有价值的。带着这个前提,设计出的应用会更具扩展性。
不要依赖任何小众的协议(会给迁移带来大量困难)。尽量使用那些被广泛采用的,标准的技术。值得一提的是,XML和Web Services的流行在很大程度上可以归因于这两种技术都有助于缓解企业环境异构性的影响。
综上所述,当今大多数架构师都意识到这个错误,这就是可交互技术流行的原因。 但是在您必须使用专有协议或传输的情况下,仍然需要牢记这一点。