星期六, 06月 21st, 2008
人们往往会问:如果当时做出了其他的决定或者选择了另外的道路,历史会怎样?我们可以设想,假如当年IBM没有在它所发明的PC中使用专利芯片,而是采用了非专利元件的话,那么今天的计算机行业会有怎样的不同。至少,PC机的克隆市场就不可能出现,而领导计算机革命的就将是IBM而不是微软。 还可以设想,假如Steve Jobs根本没去过施乐PARC观光,根本没见过施乐PARC开发的图形界面的话,那么他能否研制出Macintosh?还会不会有今天的Windows? 这里所呈现的就是塑造了今天的IT业的9个重大转折点,其中有些事件仍将继续影响着IT业的未来。
苹果收购NeXT
上世纪90年代末,苹果公司陷入绝境,企业形象暗淡无光,市场份额极度萎缩,而Windows NT和Windows 95在功能和技术上都已超过了“老迈”的Mac OS。
而苹果当时绝密的新操作系统,即代码为Copland的操作系统如果能够交付的话,则有可能一举恢复苹果公司的技术领先优势。然而,在历经十年的研发之后,自命不凡的Copland已经成了眼高手低的无效劳动。
1996年,在Copland的发布仍然遥遥无期之际,当时的苹果CEO Gil Amelio无奈地做出了苹果历史上最困难的抉择——放弃Copland这座所谓的“金矿”,转而收购了新兴企业NeXT。后者不仅拥有自主版权的基于Unix的操作系统可在Mac机上运行,更重要的是,它的CEO就是苹果的共同创始人Steve Jobs。
两家公司合并后,Jobs开始致力于重塑苹果。他不但让Mac OS焕然一新(Mac OS X),而且推出了包括iMac、iPod以及一系列的服务器、工作站和便携设备。Amelio的抉择虽然导致了他自己的离去,但是他收购NeXT的举措却让苹果公司起死回生了。
施乐与自由软件的曙光
1980年,在麻省理工学院的人工智能实验室,很多程序员一边咒骂着新安装的施乐激光打印机,一边奔跑到楼上去看自己的打印任务是否完成了。
而在以前,情况不是这样的。那时,麻省理工学院有一位“黑客”简单地修改了施乐打印机的软件,每当用户的打印任务完成后打印机都会自动地给用户发送一封e-mail。但是最新的施乐打印机有些不同,因为牵涉到版权和商业机密,施乐不再提供打印机驱动的源码了。
这位黑客名叫Richard Stallman,他对施乐的做法深恶痛绝。Stallman很快就成了传奇人物,他声称要向专利软件宣战,创建了GNU项目和自由软件基金会。
Handspring创造智能手机时代
上世纪90年代末,创造出PDA市场的Palm正在拼死抵抗包括微软在内的众多竞争者的蚕食。结果是Palm的一群高管离开公司自创了Handspring公司。
Handspring的PDA可以容纳很多附加的硬件模块,可以与其合作伙伴共同测试各种功能,比如说,你的PDA不只能存储电话号码,而且还能通话,那会怎么样?
结果就是被称为VisorPhone的计划出笼。很快,结合了手机与PDA功能的紧凑设备面世了。
2001年,当Handspring发布Treo时,Palm终于觉醒。2003年,Palm收购了Handspring,单一功能的PDA走到了头,取而代之的就是更加实用的智能手机。
上世纪70年代的垃圾邮件
现代互联网的前身是由美国防部研制的ARPANet,可允许计算机专家、厂商和其他的政府合同商相互之间用e-mail进行长距离通信。
1978年的某一天,DEC的营销人员Gary Thuerk利用这种新的通信方式想出了一招推销“妙招”。他在想,为何只给ARPANet上的一两个人发信,而不一下子发给所有人呢?这不正是一个能让所有人在短时期内便得知DEC新推出的主机产品的最佳办法吗?
他所群发的邮件就成了全球第一封垃圾邮件,这让ARPANet的管理者们很不高兴。“这是对ARPANet只作为美国官方政府网络原则的公然违背,”Raymond Czahor少校写道。“必须采取适当行动以避免此类事件再次发生。”
但是,Raymond少校,你是否知道“此类事件”已经愈演愈烈了呢?
微软Office逐渐形成垄断
假如你在1986年购买PC的话,你可以用WordPerfect或者Lotus 1-2-3来写文章或者填写表格。这些DOS程序功能完备、速度又快,很少有谁会想到它们居然会被微软的平淡无奇的产品所取代。
遗憾的是,无论Lotus还是WordPerfect都未曾预料到Windos的成功。它们以为用户会根据应用去选择相应的操作系统,而不会倒过来。但是当用户们争相使用基于图形界面的软件时,微软便迅速地利用Word和Excel填补了这一空白。
1990年,微软在推出这两款应用之时,还引进了新的PowerPoint,捆绑在一起便成为“Office套件”。和Lotus及WordPerfect这样功能单一、只适用于DOS系统的软件相比,微软的Windows显然更有优势。最终,先前的市场领导者们虽然也增加了更多的功能,但是它们拒绝支持Windows的决定却让它们付出了高昂的代价。
Web放弃同步通信方式
在Web上看e-mail是很耗费资源的,因为Web是基于页面的。每个HTTP请求都意味着从客户端到服务器的一次往返,需要刷新整个页面,这对于像e-mail客户端这样高度活跃的应用来说并不是好事。所以,为了让Outlook Web Access 2000更好用,微软就开发了一种让浏览器和Web服务器通信的新方法,就是异步下载一部分内容给客户端。
没成想,这种做法相当有效。尽管IE的缺陷不断,但是Mozilla还是给2002年的Mozilla 1.0配备了相似的功能,称之为XMLHttpRequest。从此,闸门大开,一种Web编码的新方法由此诞生。
我们很难相信,Facebook、GMail、Google Maps和其他无数基于Ajax的网站的生存都得归功于微软的这一技术。只不过这些网站做得更好罢了。
Linux击垮SCO
2003年,一朵乌云压向了开源阵营。由新上任的CEO Darl McBride带领的SCO声称自己拥有Linux内核一些关键部分的所有权。它警告Linux用户,要他们向SCO支付许可证费用,否则就有可能吃侵权官司。
然而,SCO显然低估了Linux对于企业,尤其是对于IBM的重要性。谁都不禁要问:SCO凭什么认为自己能够胜过蓝色巨人呢?结果呢?IBM的律师们一条一条地驳斥了SCO的指控,确立了Linux的合法地位。
随着官司的缓慢进展,McBride和SCO受到了业界的嘲笑,最终破产。与此同时,Linux业务却在迅猛增长。由于像CA、IBM、Novell和Red Hat等巨头的支持,Linux如今已站稳了脚跟。原本想置Linux于死地的这场官司到头来反而成就了Linux的黄金时代,这的确颇具讽刺意味。
英特尔突破MHz局限
在PC处理器制造的初期阶段,速度就是一切。厂商需要做的就是如何加快时钟周期,然后就能看到对处理器性能饥渴的用户蜂拥而至。然而当新的世纪开始的时候,时钟速度已达到GHz,旧的芯片设计已无法跟进。芯片会很快过热,消耗大量的电能。此时,在以色列海法的英特尔实验室,由Mooly Eden领导的一个团队开发了一种创新的芯片,即Pentium M。
虽然Pentium M只是用于笔记本电脑的,但是因为它比同时代的各种CPU的能耗更低、指令集也更高效,所以它很快就给英特尔带来了技术上的突破。
如今,英特尔于2006年推出的芯片内核技术都是源自Pentium M的。从那时以来,处理器芯片不仅赢得了速度上的赛跑,而且变得更加智能。
外包全球化
当2000年来临时,美国的企业都把Y2K(千年虫)危机视为严重的威胁。它们无法预测这一危机到底会对企业产生何种程度的影响。
由于解决Y2K危机的人手奇缺,企业的IT部门便开始向外界寻求帮助。于是它们在无意中挖掘除了一座金矿。互联网的普及再加上社会和经济的变革,在发展中国家培育出了一支数量庞大的高技术人才大军。
印度的一批企业,如Infosys和Wipro,是首先开始离岸外包业务的,随后便有俄罗斯、东欧、中国和世界其他国家的企业也开始进入外包服务市场。与此同时,1990年的《移民改革与控制法案》创建了H-1B美国移民签证程序,使得美国公司引入外籍员工变得更为容易。
今天,Y2K问题早已无人问津,但是外包的趋势却丝毫未见减弱。越来越多的国家卷入了互联网经济,IT工人如今必须在一个日益扁平的世界中进行职业竞争了。
Posted in 首页 | 1 Comment »
星期五, 06月 13th, 2008
在eBay,可伸缩性是我们每天奋力抵抗的一大架构压力。我们所做的每一项架构及设计决策,身前身后都能看到它的踪影。当我们面对的是全世界数以亿计的用户,每天的页面浏览量超过10亿,系统中的数据量要用皮字节(1015或250)来计算——可伸缩性是生死交关的问题。
在一个可伸缩的架构中,资源的消耗应该随负载线性(或更佳)上升,负载可由用户流量、数据量等测量。如果说性能衡量的是每一工作单元所需的资源消 耗,可伸缩性则是衡量当工作单元的数量或尺寸增加时,资源消耗的变化情况。换句话说,可伸缩性是整个价格-性能曲线的形状,而不是曲线上某一点的取值。
可伸缩性有很多侧面——事务的方面、运营的方面、还有开发的方面。我们在改善一个Web系统的事务吞吐量的过程中学到了很多经验,本文总结了其中若 干关键的最佳实践。可能很多最佳实践你会觉得似曾相识,也可能有素未谋面的。这些都是开发和运营eBay网站的众人的集体经验结晶。
最佳实践 #1:按功能分割
相关的功能部分应该合在一起,不相关的功能部分应该分割开来——不管你把它叫做SOA、功能分解还是工程秘诀。而且,不相关的功能之间耦合程度越松散,就越能灵活地独立伸缩其中的一部分。
在编码层次,我们无时不刻都在运用这条原则。JAR文件、包、Bundle等等,都是用来隔离和抽象功能的机制。
在应用层次,eBay将不同的功能划分成几个应用程序池。销售功能由一组应用服务器运行,投标功能由另一组负责,搜索又是另外一组服务器。我们把总 共约16,000台应用服务器分成220个池。这样就可以根据某项功能的资源消耗,单独地伸缩其中一个池。我们也因此得以进一步隔离及合理化资源依赖关系 ——比如销售池只需要访问后台资源的一个相对较小的子集。
在数据库层次,我们也采取同样的做法。eBay没有无所不包的单一数据库,相反我们有一组数据库主机存放用户数据、一组存放商品数据、一组存放购买数据……总共1000个逻辑数据库分布在400台物理主机上。同样,这种做法让我们得以单独为某一类数据伸缩其数据库设施。
最佳实践 #2:水平切分
按功能分割对我们的帮助很大,但单凭它还不足以得到完全可伸缩的架构。即使将功能一一解耦,单项功能的资源需求随着时间增长,仍然有可能超出单一系 统的能力。我们常常提醒自己,“没有分割就没有伸缩”。在单项功能内部,我们需要能把工作负载分解成许多我们有能力驾驭的小单元,让每个单元都能维持良好 的性能价格比。这就是水平分割出场的时候了。
在应用层次,由于eBay将各种交互都设计成无状态的,所以水平分割是轻而易举之事。用标准的负载均衡服务器来路由进入的流量。所有应用服务器都是 均等的,而且任何服务器都不会维持事务性的状态,因此负载均衡可以任意选择应用服务器。如果需要更多处理能力,只需要简单地增加新的应用服务器。
数据库层次的问题比较有挑战性,原因是数据天生就是有状态的。我们会按照主要的访问路径对数据作水平分割(或称为“sharding”)。例如用户 数据目前被分割到20台主机上,每台主机存放1/20的用户。随着用户数量的增长,以及每个用户的数据量增长,我们会增加更多的主机,将用户分散到更多的 机器上去。商品数据、购买数据、帐户数据等等也都用同样的方式处理。用例不同,我们分割数据的方案也不同:有些是对主键简单取模(ID尾数为1的放到第一 台主机,尾数为二的放到下一台,以此类推),有些是按照ID的区间分割(1-1M、1-2M等等),有些用一个查找表,还有些是综合以上的策略。不过具体 的分割方案如何,总的思想是支持数据分割及重分割的基础设施在可伸缩性上远比不支持的优越。
最佳实践 #3:避免分布式事务
看到这里,你可能在疑惑按功能划分数据和水平划分数据的实践如何满足事务要求。毕竟,几乎任何有意义的操作都要更新一个以上的实体——立即就可以举 出用户和商品的例子。正统的广为人知的答案是:建立跨资源的分布式事务,用两段式提交来保证要么所有资源全都更新,要么全都不更新。很不幸,这种悲观方案 的成本很可观。伸缩、性能和响应延迟都受到协调成本的反面影响,随着依赖的资源数量和客户数量的上升,这些指标都会以几何级数恶化。可用性亦受到限制,因 为所有依赖的资源都必须就位。实用主义的答案是,对于不相关的系统,放宽对它们的跨系统事务的保证。
左右逢源是办不到的。保证跨多个系统或分区之间的即时的一致性,通常既无必要,也不现实。Inktomi的Eric Brewer十年前提出的CAP公理是这样说的:分布式系统的三项重要指标——一致性(Consistency)、可用性(Availability)和 分区耐受性(Partition-tolerance)——在任意时刻,只有两项能同时成立。对于高流量的网站来说,我们必须选择分区耐受性,因为它是实 现可伸缩的根本。对于24×7运行的网站,选择可用性也是理所当然的。于是只好放弃即时一致性(immediate consistency)。
在eBay,我们绝对不允许任何形式的客户端或者分布式事务——因此绝不需要两段式提交。在某些经过仔细定义的情形下,我们会将作用于同一个数据库 的若干语句捆绑成单个事务性的操作。而对于绝大部分操作,单条语句是自动提交的。虽然我们故意放宽正统的ACID属性,以致不能在所有地方保证即时一致 性,但现实的结果是大部分系统在绝大部分时间都是可用的。当然我们也采用了一些技术来帮助系统达到最终的一致性(eventual consistency):周密调整数据库操作的次序、异步恢复事件,以及数据核对(reconciliation)或者集中决算(settlement batches)。具体选择哪种技术要根据特定用例对一致性的需求来决定。
对于架构师和系统的设计者来说,关键是要明白一致性并非“有”和“没有”的单选题。现实中大多数的用例都不要求即时一致性。正如我们经常根据成本和其他压力因素来权衡可用性的高低,一致性也同样可以量体裁衣,根据特定操作的需要而保证适当程度的一致性。
最佳实践 #4:用异步策略解耦程序
提高可伸缩性的另一项关键措施是积极地采取异步策略。如果组件A同步调用组件B,那么A和B就是紧密耦合的,而紧耦合的系统其可伸缩性特征是各部分 必须共同进退——要伸缩A必须同时伸缩B。同步调用的组件在可用性方面也面临着同样的问题。我们回到最基本的逻辑:如果A推出B,那么非B推出非A。也就 是说,若B不可用,则A也不可用。如果反过来A和B的联系是异步的,不管是通过队列、多播消息、批处理还是什么其他手段,它们就可以分别地伸缩。而且,此 时A和B的可用性特征是相互独立的——即使B受困或者死掉,A仍然能够继续前进。
整个基础设施从上到下都应该贯彻这项原则。即使在单个组件内部也可通过SEDA(分阶段的事件驱动架构,Staged Event-Driven Architecture)等技术实现异步性,同时保持一个易于理解的编程模型。组件之间也遵守同样的原则——尽可能避免同步带来的耦合。在多数情况下, 两个组件在任何事件中都不会有直接的业务联系。在所有的层次,把过程分解为阶段(stages or phases),然后将它们异步地连接起来,这是伸缩的关键。
最佳实践 #5:将过程转变为异步的流
用异步的原则解耦程序,尽可能将过程变为异步的。对于要求快速响应的系统,这样做可以从根本上减少请求者所经历的响应延迟。对于网站或者交易系统, 牺牲数据或执行的延迟时间(完成全部工作的实践)来换取用户的延迟时间(用户得到响应的时间)是值得的。活动跟踪、单据开付、决算和报表等处理过程显然都 应该属于后台活动。主要用例过程中常常有很多步骤可以进一部分解成异步运行。任何可以晚点再做的事情都应该晚点再做。
还有一个同等重要的方面认识到的人不多:异步性可以从根本上降低基础设施的成本。同步地执行操作迫使你必须按照负载的峰值来配备基础设施——即使在 任务最重的那一天里任务最重的那一秒,设施也必须有能力立即完成处理。而将昂贵的处理过程转变为异步的流,基础设施就不需要按照峰值来配备,只需要满足平 均负载。而且也不需要立即处理所有的请求,异步队列可以将处理任务分摊到较长的时间里,因而起到削峰的作用。系统的负载变化越大,曲线越多尖峰,就越能从 异步处理中得益。
最佳实践 #6:虚拟化所有层次
虚拟化和抽象化无所不在,计算机科学里有一句老话:所有问题都可以通过增加一个间接层次来解决。操作系统是对硬件的抽象,而许多现代语言所用的虚拟 机又是对操作系统的抽象。对象-关系映射层抽象了数据库。负载均衡器和虚拟IP抽象了网络终端。当我们通过分割数据和程序来提高基础设施的可伸缩性,为各 种分割增加额外的虚拟层次就成为重中之重。
在eBay,我们虚拟化了数据库。应用与逻辑数据库交互,逻辑数据库再按照配置映射到某个特定的物理机器和数据库实例。应用也抽象于执行数据分割的 路由逻辑,路由逻辑会把特定的记录(如用户XYZ)分配到指定的分区。这两类抽象都是在我们自己开发的O/R层上实现的。这样虚拟化之后,我们的运营团队 可以按需要在物理主机群上重新分配逻辑主机——分离、合并、移动——而完全不需要接触应用程序代码。
搜索引擎同样是虚拟化的。为了得到搜索结果,一个聚合器组件会在多个分区上执行并行的查询,但这个高度分割的搜索网格在客户看来只是单一的逻辑索引。
以上种种措施并不只是为了程序员的方便,运营上的灵活性也是一大动机。硬件和软件系统都会故障,请求需要重新路由。组件、机器、分区都会不时增减、 移动。明智地运用虚拟化,可使高层的设施对以上变化难得糊涂,你也就有了腾挪的余地。虚拟化使基础设施的伸缩成为可能,因为它使伸缩变成可管理的。
最佳实践 #7:适当地使用缓存
最后要适当地使用缓存。这里给出的建议不一定普遍适用,因为缓存是否高效极大地依赖于用例的细节。说到底,要在存储约束、对可用性的需求、对陈旧数 据的容忍程度等条件下最大化缓存的命中率,这才是一个高效的缓存系统的最终目标。经验证明,要平衡众多因素是极其困难的,即使暂时达到目标,情况也极可能 随着时间而改变。
最适合缓存的是很少改变、以读为主的数据——比如元数据、配置信息和静态数据。在eBay,我们积极地缓存这种类型的数据,并且结合使用“推”和“ 拉”两种方法保持系统在一定程度上的更新同步。减少对相同数据的重复请求能达到非常显著的效果。频繁变更、读写兼有的数据很难有效地缓存。在eBay,我 们大多有意识地回避这样的难题。我们一直不对请求间短暂存在的会话数据作任何缓存。也不在应用层缓存共享的业务对象,比如商品和用户数据。我们有意地牺牲 缓存这些数据的潜在利益,换取可用性和正确性。在此必须指出,其他网站采取了不同的途径,作了不同的取舍,也同样取得了成功。
好东西也会过犹不及。为缓存分配的内存越多,能用来服务单个请求的内存就越少。应用层常常有内存不足的压力,因此这是非常现实的权衡。更重要的一 点,当你开始依赖于缓存,那么主要系统就只需要满足缓存未命中时的处理要求,自然而然你就会想到可以削减主要系统。但当你这样做之后,系统就完全离不开缓 存了。现在主要系统没办法直接应付全部流量,也就是说网站的可用性取决于缓存能否100%正常运行——潜在的危局。哪怕是例行的操作,比如重新配置缓存资 源、把缓存移动到别的机器、冷启动缓存服务器,都有可能引发严重的问题。
做得好,缓存系统能让可伸缩性的曲线向下弯曲,也就是比线性增长还要好——后续请求从缓存中取数据比从主存储取数据成本低廉。反过来,缓存做得不好 会引入相当多额外的经常耗费,也会妨碍到可用性。我还没见过哪个系统没机会让缓存大展拳脚的,关键是要根据具体情况找到适当缓存策略。
总结
可伸缩性有时候被叫做“非功能性需求”,言下之意是它与功能无关,也就比较不重要。这么说简直错到了极点。我的观点是,可伸缩性是功能的先决条件——优先级为0的需求,比一切需求的优先级都高。
希望以上最佳实践能对你有用,希望能帮助你从新的角度审视你的系统,无论其规模如何。
Posted in 首页 | No Comments »
星期二, 06月 10th, 2008
项目管理意识
项目经理兼顾项目管理和分析、设计、编码、测试等具体的技术实施工作;兼顾具体技术工作和各种项目管理任务(如:项目分析/评估、项目计划的制定/检查/调整、上下左右的沟通、专业资源调配、项目组织调整、项目财务控制、风险分析/对策等)。
项目成本基础
项目管理的精髓是必须在规格(Specification)、成本(Cost、Resource)和进度(Schedule)之间取得平衡。
项目管理制度
规范化而且切实可行的项目管理制度,必须因企业、因项目而异。一般而言,应是项目管理原理、企业/行业特点和项目规模/性质、企业开发文化/素质等各种因素综合的产物。产生的过程应是,由具一定的理论素养、丰富的规范化项目实施经验和总结能力的资深项目管理专家,结合企业的具体情况,有针对性地制定,并经培训、试行、调整予以落实贯彻。
专业服务组织
国际上的企业级应用软件的开发组织,基本上分为产品研发和专业服务两类。国内由于市场成熟度低等原因,多以直接面向客户需求的项目型开发为主,应属专业服务型的技术组织结构。
项目计划
项目计划是项目经理实施项目管理控制的基础。项目计划的Breakdown或曰“粒度”,是一个需要小心把握平衡的问题。越细则控制力度越大,但项目管理的成本越高;反之亦然。
项目风险意识
项目风险意识就是失败意识。每当我们启动一个项目的时候,我们往往憧憬项目投产之日的成功,但是否想过精疲力竭后失败的沮丧?做项目不比卖产品,产品卖出就是成功,项目投产才算成功;产品是静态的,项目是动态的;产品质量有问题可以包换、保修,项目一旦失败,时间不能倒流,客户损失的可能就是市场竞争优势和机遇。风险意识,就是对这种结局的可能性的警惕。如此,我们就会小心谨慎地处理许多项目业务需求、技术方案和组织管理的问题。
业务参与意识
客户购买IT系统的目的是为了更好地发展自己的业务。应用软件将通用计算机变成了专用的业务系统,因此应用软件中渗透着业务制度、策略,成为应用软件甚至是IT系统的灵魂。因此,国际上成功的案例是业务部门贯穿始终地参与,作为确保项目成功的底线(Bottom Line)之一。
Posted in 首页 | No Comments »