云计算的技术路线探讨

jopen 11年前

    引言

        当前的“云计算”一词已经被神话,似乎快成了放之四海皆准的时髦真理,就好比当初言必称“希腊”一般,表面光芒四射,但实际上却无比教条、且越来越令人生厌。

        作为“云计算”的一个普通开发者和推广者,很有必要通过亲身实践,以正视听,希望能让后来者(云计算系统的开发者)少走弯路——有所为、有所不为。 

        前言

        我们所要谈论的不是商业领袖们所热衷的云计算概念、云计算市场,而是讨论技术人员眼中云计算具体形态和切实的实现办法。

        我们将从需求分析入手、进而讨论设计理念、再具体化到子系统设计和实现中存在的难点问题、最后谈谈云计算对外服务的技术选择。其中有些观点属于业界共识,也不少属于个人看法——难免有所偏颇——真诚欢迎从事云计算开发的朋友积极讨论和批评。

        本文试图回答这么几么几问题:

        1. 技术人员理想的云计算是什么?

        2. 理想和现实的鸿沟是什么?

        3. 云计算到底需要什么样的基础架构?

        4. 云计算基础架构可能的组成部分。

        5. 虚拟机和App Engine等云计算的关系。

        强调一下——本文仅以开发人员视角出发!以大中型互联网公司、海量数据、多业务线运维为背景,围绕后台基础架构进行分析讨论。

        另外,借此机会王婆卖瓜式的推荐一下我个人发起的开源云计算相关的小项目:http://code.google.com/p/cloudxy/

        我们到底要什么云

        现在的麻烦

        谈理想之前先回顾当前现实中RD(开发人员)和OP(运维人员)的工作场景。作为一个”过来人”,分析一下RD和OP在开发、测试、部署一个新应用时不得不做的那些麻烦事吧。

        开发阶段面对的麻烦:

        Ø 可用性问题——互联网应用作为在线服务都希望能永远在线;而从成本考虑,规模使用廉价PC SERVER、廉价硬盘、廉价路由器等必然就会出现相对较高的故障率,甚至可以说故障是常态,因此从应用设计上必须考虑故障切换,而且最好是自动透明的故障切换。

        Ø 负载均衡问题——无论存储集群或者是应用服务集群等都可能出现负载不均匀情况。同一集群中因种种原因总是会有热点(因为访问压力大而造成的或磁盘空间不 够、或内存不足、或CPU负载太高、或网络带宽不足)出现,当热点出现时,就需要将热点的访问流量分流到比较冷的服务器上去。总之希望集群中的服务器冷热 均匀,服务才能稳定、高效。

        Ø 扩容缩容——当你的应用用户越来越多时,就要有扩容要求(集群中补充新机器),扩容时最好能不停或者少停服务。

        上面这些问题,其实是分布系统的普遍共性问题,解决办法无非是采用supervisor、主从热备、smartclient、状态报告、一致性哈希、数据分区等等技术,兵来降挡,水来土掩的case by case的解决。

        作为一个在线应用RD(开发人员),很可能在处理上述问题花的功夫,比自己应用逻辑本身的还要多不少,这显然是一个不小的负担。

        测试阶段面临的麻烦

        测试首先在于搭建环境和系统部署。这点说起来简单,其实现实操作中可够你折腾一阵了。因为你不得不做:

        Ø 抢到足够多的机器——你很可能要排队、要求人、总之要费点点功夫。

        Ø 搭建存储服务——应用开发人员对存储系统各种配置参数和部署方式的理解和摸索过程,绝对是一个常犯错误的窝工活。

        这个过程对很多RD和测试人员来说,绝对比写代码要费时费力。沟通成本(公司大了,很多沟通都是跨部门的)不容小视呀。

        部署的麻烦

        Ø 容量规划——一个应用上线前肯定需要根据经验(或者拍脑袋)估算出未来一段时间内系统面临的负载。估算少了,肯定要面临扩容的风险,这无疑是自搬起石头砸自己脚。再加上一些好大喜功的人类天性,应用负责人肯定会满打满算的推算出最大可能的机器规模。

        Ø 申请机器,搭建集群——申请机器意味着报计划、等审批、等机器、走麻烦的流程(这很多都是经理的事啦)。搭建集群则是RD和OP一起携手完成(RD出上线 步骤等,OP 实施),这个过程要小心谨慎,需要不止一个人反复检查(差劲点的应用会是实例配置不统一,每个实例的配置都有所区别),还常常需要RD陪同实施,总之绝对 是个体力活。

        Ø 备机准备——很多应用为了防止意外机器硬件故障(硬盘、主板、网卡、电源等坏了)下,能快速进行故障恢复,还会搞一些备机,以防万一。这些机器纯粹是养兵千日用兵一时。

        任何一个自认为重要的应用都希望自己单独占领一个集群,如果和别人混合部署,害怕资源征用,自己被拖累。鉴于此原因一个应用往往就意味者需要搭 建1个以上集群(很可能存储、或者其他服务都要单独搭建一个集群为其使用)。应用RD人员还好说,为自己应用搭建一次就OK了、存储等基础服务RD就要多 搭建几次,受点累了;而OP就更辛苦了,要不断重复这些体力劳动。

        容量规划和备机准备多多少少会带来物理资源的闲置,容量规划意味着预先准备未来一定时期内都足以应付请求压力的足够机器,那也就是说初期用户规模还没上来前,压力还不大时,集群中多余的机器或者每个机器上的多数资源都会被闲置。

        上线后的麻烦

        故障恢复——一旦出现物理故障,或者系统自动FAILOVER做的不好情况下。但凡有机器异常,就有可能需要手动或自动(一般是手自一体的)进行故障恢复了。这个时候如果是常见故障,OP则需要按照事先准备的运维预案进行故障恢复。

        OP最怕线上服务出现问题,影响用户访问。这种事故一旦碰到,就必须立刻响应,不容有误。如果不幸的OP碰到那些未能自动透明的进行故障恢复而仓促上线的服务,那绝对够喝一壶了。

        一言以概之,困扰我们是:

  • 系统分布化带来的麻烦
  • 反复沟通带来的麻烦
  • 搭建环境带来的麻烦
  • 资源浪费(这点一般是大老板们关心的问题)

        我们憧憬的云计算

        RD们真的希望能有一台“超级计算机”,它大的有用不完的内存和磁盘、有强大无比的计算能力、更有无限带宽、而且还是永不宕机!!!

        如果真有这么一台超级计算机,那么我们开发程序就不用再去考虑什么分布化、什么机器故障、负载均衡等事啦;也不用费神去申请机器,搭建集群(因 为资源无限吗);甚至上线动作都可省去,不再需要麻烦OP同学如履薄冰的部署程序,RD自己就能如同部署本机程序一样简单的部署线上服务。

        如果那样就太酷毙了,应用RD从此可以心无旁逸的投入到自己业务逻辑的开发中去,彻底释放自己的想象力了。

        完美理想的破灭

        OK ! 我们想要的已经清楚了,那么当今什么是否能有这样的超级计算机呢?或者说是否使用集群技术实现这种理想的超级计算机呢?答案是否定的!我们无法使用集群技术实现这样的超级计算机。

        否定的原因在于:1. 我们没法将集群机器中的CPU计算代数相加,变成超级CPU(能做的只能是把任务分解,让多个CPU并行计算罢了);2. 我们没法将集群机器的内存代数相加,变成超大内存。千万别想着用我们普通以太网做共享内存尝试,要知道内存带宽(GB量级)可要比网络带宽(MB量级)高 出好多个量级;

        次完美理想的再破灭

        我们向现实第一次妥协,我们不求像写单机程序那样写应用了,我们将应用请求分区处理,即将应用请求按照给定规则划分成多个处理单元,每个处理单元都下发到集群中的某台机器上执行——我们从理想的统一集中处理,变为“化整为零分区并行处理”。

        我们无法拥有资源无限的超级计算机来肆意开发程序,而是要遵循限制:

  • 必须在单机资源容量(尤其内存)的顾虑下来开发服务程序——以求在集群中被并行处理。
  • 还必须给出分区规则——以求能化整为零,分区执行。

        然而我们仍然奢望我们可以不用考虑如何进行分区、也不用考虑如何调度各子任务在集群中调度,不用考虑如何进行故障迁移、不用考虑如何负载均衡、 不用考虑扩容缩容等分布式系统的共性问题;同时我们也奢望的程序上线自动化(无需人工干预),即应用可自动在云环境中部署和自动运行的。至于如何分区、如 何调度、何时扩容等都交给“云”老大了。举个例子,如果我们开发了一个key value系统,只要告诉“云老大”我们需要的分区规则(或者哈希打散、或者字典序分区)则万事大吉了。

        那么当今是否能有这样智能的云呢?答案还是否定的!我们还是无法真正实现这样智能的云。为什么呢?

        首先我们思索一下这种智能云如果存在,会隐含有那些具体要求:

        Ø 规模足够大——足够的规模的集群才配称为云,才能提供认任我们为所欲为,不用考虑无法获取资源的情况(当然不意味你可无限使用,可是要算钱的)。

        Ø 支持共享—— 云可不是为了某一个应用专门搭建的,它必然要支持各种千差万别的应用服务同时运行其中。

        Ø 支持自动分区、任务派发、启动——只要告诉分区规则,就能根据集群中资源情况,自动对应用服务进行分区,并派发服务程序到合适节点机器上、然后自动运行服 务。我们不需要具体指定该分多少区、该部署到那个机器上,也不用自己拷贝执行程序和配置到目标机器、也不用手动去启动服务。

        Ø 支持自动故障切换—— 云应该具备高可用性,任何在其中运行的程序都应该有可用性保证。所以云中任何“节点故障”的处理应该能自动实施故障切换;而且云中任何“应用服务故障”也都应该能获得自动故障切换的保障。应用开发人员从此可高枕无忧了。

        Ø 支持自动扩容——应用服务当压力负载加大时,需要能不影响服务的前提下,自动试试扩容(获得更多资源,运行更多实例)。

        Ø 支持负载均衡,智能调度——避免应用所在实例中出现冷热不均的情况。当发生热点时,可进行分区再分区方式,变一个服务实例为多个服务实例,并将分出来的实例迁移到多个机器上运行,从而消除热点。

        接下来的问题应该是:这些技术要求,从技术实现角度而言到底意味什么?实现难度到底在那里?

        在我刚从事云基础架构设计开发时,对上述要求真可谓是信心百倍。甚至我们会有意炫耀式的挂在嘴边,无数次向别人吹嘘。但事实教育了我,仰望星空,仍然要脚踏实地。我们展开来分析这些貌似理所当然的一些技术点,在云计算实践中会有那些困难制约我们。

        应用共享云资源之制约

        不同用户、不同特征的应用在一起混合部署、同时运行时候,相互之间需要保证“资源隔离”,这种隔离意味着避免相互资源争用,否则同一机器上的不 同程序服务必然相互影响,对资源的你争我夺的情况下,服务性能必然发生抖动,从而破坏我们许诺的SLA(服务质量保证)—— 这也是为什么很多项目经理,都怕和别人的应用公用一个服务集群或存储集群的原因。

        资源隔离这个问题,我们要深刻认识,这点是实现大规模云计算面临的一个普遍问题(谁也躲不开)。对于资源隔离这个共性问题,自然前人研究过无数 种解法: 内存的预分区使用(如机器虚拟机XEN为domu预分配内存)、CPU的分核(利用CPU Affinity性)和配额限制下的分时复用、磁盘的分盘器使用、网络QOS等等。

        但是很不幸的是——相对富足的资源(如CPU在当前服务器中多数情况下大多属于营养过剩,供大于求)和可以分区使用资源(如MEM、磁盘容量都 可按配额预先划分给应用)可以理想的做到资源隔离(或者说应用之间影响有限);可对于机器中紧缺资源,说白了就是“IO资源”(磁盘I/O和网络I/O) 隔离效果就很不理想了。我们实验结果表明网卡QOS将损失近近一半带宽,而磁盘QOS几乎不能有效防止I/O争用(两个I/O密集型应用在一起争夺I/O 依旧那么不可控制)。

        因此当前的技术条件下,你可借助内核工具Cgroup(Google放出来的一个内核资源受控功能),或用户信号 suspend\resume、自维护内存池等等技术做到给应用服务固定的CPU和内存配额限制,但没有太好方法多I/O进行配额限制(至少没有很理想的 办法)。所以我个人认为要想解决I/O争用问题,要么借助于新硬件的升级——万兆网络代替千兆网络、SSD代替IDE硬盘等——使得I/O资源变的相当富 足;要么就避免I/O密集性程序混合部署,也避免离线任务(多是I/O密集性任务)和在线任务(尤其是有数据查询的在线任务,key value 存储服务)混合部署,以防止I/O争用给在线服务造成响应延迟。

        智能调度之制约

        我们理想的调度意味着应用服务程序可以在集群中任意资源够用的机器上启动运行,甚至更理想的是能不停服务的情况下,将应用程序进行机器间动态迁移。

        很显然如若让应用程序可在任意机器上执行,就要求应用服务的“上下文状态”不能持久化在本地磁盘,也不能从本地反持久化(总之不能依赖本地存 储)—— 这就是常说的无状态。只有这样才有可能实现程序的运行和位置无关(即,和运行其的宿主机无关),从而才能有智能调度的基础。

        “上下文”不持久化于本地,就要求云环境能提供存储服务,以便各应用的上下文能存储分布式的、安全、高效的存储在云中,但至于具体在那里,应用不必也不想关心。

        “上下文” 的定义是宽泛的,包括各种格式的存储容器。比如Hbase应用中,可以将是Range Server看作应用服务,而数据就是它的上下文——被分布式的存放于HDFS之中,也正是因为这种上下文位置无关的设计,使得Range Server可以被智能调度。 同样HBase又被作为一个上下文存储服务,供其他更多应用服务使用,那么这些应用服务也就和位置无关了。

        作为一个云服务,应该提供有:基于offset的类文件存储系统;key value存储系统;类似数据库(SQL)存储系统;类似BigTable这种(No Sql)列存储系统;甚至可能的图存储等等。

        不过这种上下文远程存储实现在实践中所面临的最大挑战是网络带宽不够,一旦数据持久化的真实位置与提交、查询的位置不在一个机器内的情况发生,必然带来响应时间恶化,带宽被大大占用。

        仍以HBase为例,Range  Server 接受客户端提交的数据,然后当数据在内存中积攒到一定量后,再写入到HDFS中,因为HDFS的写入优先选择最近的Chunk Server,而Chunk Server和Range Server是混合部署的,所以必然初期负责某个分区的Range Server与该分区落地的数据实际上是存储都在同一个机器上(这就是HBase所谓的location相关性指标此刻为100%)。但当Range Server负责的分区数据过多,已至超过单机存储量时;或者Range Server发生了故障切换后被重新调度,则Range Server和对应数据可能就不再在一个物理机器上时,显然读写都必须多了一次跨机器交互——这种多余交互在千兆以太网环境下很可能要花去几毫秒,对于强 调响应时间的在线应用很可能是不可接受的。

        跨机器带来额外的带宽占用毋庸置疑,更需要考虑的还有,因为性能原因Range Server不可能每一条数据都写透到HDFS中,而必须聚合起来到达一大批时才一次推到HDFS中(目的无非是减少网络交互的消耗)。但是如果还没有被 推入HDFS之前,Range Server所在机器宕机则肯定要丢失数据了。所以为了防止丢失,Range Server需要在成批写入HDFS之前,将提交请求先记录下来(所谓editlog),为安全和调度时效性原因(Range Server故障后,需要立刻进行故障切换),也不能存储于本地,而是要存储在远程(实际上是以append模式写到HDFS中)。我们知道为了避免数据 丢失,HDFS存储采用了多副本技术(一般3份)。因此一份数据从客户端提交开始有可能需要在网络中传播7次(从客户端到Range Server一份,Range Server写editlog三份,Range Server聚合后到HDFS三份)。对于网络的压力可想而知,所以没有一个超级强大的网络基础架构休想这样理想的实现所有上下文数据远程化。

        很多公司都设想数据远程化,但这之前请先设计一个强大的网络环境。谷歌网络环境许诺“任何机器”之间都能达到500大B的传送速度;而我们国内又有几家能保证这么快呢,可能500小b都不敢拍胸脯保证。

        故障切换之制约

        故障切换除了要求和智能调度一样的"上下文数据远程化"以外,还有一个很重要的要求——速度快,要做到对客户端透明。

        客户端透明的一般要借助于Smart Client和服务逻辑寻址技术。Smart Client是指服务端尽量无状态(或者状态在启动后可以重建),而把智能放在客户端实现。其中一个重要智能就是故障探测和故障切换;服务逻辑寻址是说寻 址过程不再直接使用具体IP寻址,而是使用一个逻辑名称表示某个服务实例(逻辑名称对应实际的IP属于系统全局信息)。Client根据逻辑地址查询系统 全局信息,获得具体IP地址,从而进行访问。当服务发生故障,进行故障切换后,系统刷新该全局信息。而Client发现原IP地址访问失效后,则从系统全 局信息处重新获取给定逻辑地址对应的Ip地址,重新进行连接并访问——透明的完成故障切换。

        全局信息维护并非难事,主要是考虑高可用性。不过这方面已经有很多成功办法了。如Erlang有Globe模块提供全局注册名、ZooKeeper等服务也可作为配置中心存放这种全局信息。

        回头来说切换速度的问题。切换速度取决于:{故障发现 + 应用服务重启后构建上下文}

        故障发现看似简单,其实是个错误多发区,而且也没太好解决办法。分布系统故障有机器故障、服务故障、网络故障(还有包括该死的网络分区故障)。 故障发现一般依靠外部watch dog监控、心跳、或者外部抢锁等机制。但不管如何判断都要是要一定时间的,因为需要为了防止假死情况——一旦发生服务假死,而发生故障切换,就会出现双 主并存而引发数据错乱等等麻烦——所以往往需要一个确认时间(或者租约到期,或者是提升版本确认新旧)。另外,上下文重建也需要时间,比如key value服务或Range Server等服务可能需要加载一些索引进内存,才能开始提供服务,那么这个加载动作根据数量级不同而不同,数据多时,甚至需要数分钟才能完成。

        我们要心知肚明——这些故障切换耗时并非所有应用都能接受,有些应用可能根本无法容忍分钟级别的切换时间(记得亚马逊的传奇论文dynamo就 是一个要求always writeable的产品)。这种应用实际上并不合适采用上述的准实时故障切换策略,而是需要采用热备、热切、多提交点等架构才能得意满足。

        调度以及负载均衡的制约

        master-slave模式的分布系统应用中,master的职能一般包含元数据管理、接受用户命令并下发给slave、还有就是负载均衡、故障切换等等。总之,全局性动作一般都需要由master参与处理。

        智能云老大要想使用统一的方式接管各种应用的“负载均衡”和“故障切换”,也就是说实现一个大Master负责所有应用的负载均衡和故障切换。想法很好,但难免有写天真。原因有二。

        第一,应用的负载均衡和故障切换未必能简单粗暴的使用一种模式完成。也就是说不一定仅仅选一个资源(CPU、内存、I/O)够的机器就能可以迁 移应用,或者进行恢复。很多应用具有自己特殊的调度要求,比如有些应用要求所有实例都处于一个路由器之下(如VM在线迁移)、或者要求必须不能处于同一机 架(如DFS等)。

        这种约束往往是case by case的,并不容易统一抽象出来。所以大Master方法对于各种约束是否能从容面对,是其一个很大挑战!

        第二,实时负载均衡就必须随时掌握应用实例的负载情况,也就是要不断采集(很多信息是靠心跳消息报带给master )应用实例的各种负载指标。采集越勤,调度越实时。但是高频度采集状态是有代价的,它必然会给大Master带来不小负载(网络带宽负载、处理请求计算负 载等)。所以全局性的状态监控是系统扩展性的一大障碍,经验数据是大Master大约监视6000-10000个应用实例的负载就是处理上限了,再大就很 难调度管理了。

        分区的制约

        我们虽然很想把如何分区工作交给云来做,我们只用给出规则。可实现这个理想还是有些障碍的。

        1. 这个规则描述上就有一定的难度。因为每个分布应用往往都有自己的分区方式(其实就是我们所谓的7层负载均衡),如HBase使用字典序分区(因为要实现按 序检索);Memcache则实现一致性哈希分区(随机查询);还有些应用使用步长式分区;而更多应用则有自己特殊的规则进行分区,比如有些应用按地域分 区(美国的请求一个区、日本的请求一个区等)、有的按用户年龄、甚至还有的按照动态负载进行分区等等。

        2. 除了规则难以统一外,更棘手的是:实例的资源分配量,云很难确定。如果错误的资源配置很可能应用实例无法使用——有些应用会要求实例的最小资源配额(如有 些服务要加载巨大的字典表,就必须要有足够的内存才能完成);而有些应用实例更会因为分区大小的不同对资源的要求也不同(分区越大资源要求越大,但比例关 系并非线性,所以不好确定)。

        3. 剩下的麻烦就是扩容时如何将分区再劈开呢? 字典序列、一致性哈希等还算好劈开,按地点则难度就麻烦些了,要是分区规则更复杂,则劈分区也绝对是个有难度的事情了。

        综上所属,就分区一事与调度、负载均衡一样是个性化的东西,可谓各应用蛇有蛇道,鼠有鼠道。真的很难做到一刀切的统一实现。

        现实可能的云计算

        上述分析后(我也实际实践过),我们知道了现实环境的种种制约。我们不得不尊重现实,因此我们要重新定义我们智能云的职责功能了,重点是明确云的职能范围(有所为,而有所不为!)。

        强化资源管理职能

        资源管理智能需要从下面几个方面考虑:

        Ø 沙箱容器

        要想混合部署各种服务实例,我们自然希望有类似沙箱的容器,能把运行实例“封”在其中,所谓封意思限制其资源使用。既包含有资源配额管理,也包 含隔离意思。最彻底、但也是最重(为什么重,我们后面分析)的容器自然是机器虚拟机(machine virtual machine)、其次是系统虚拟机(system virtual machine);另外java 、perl、erlang等语言虚拟机也可算是不太合格的容器(封的不够)。

        但不要迷信虚拟机做容器,道理上讲凡是能提供受限环境都属于容器。容器实现并未有确切套路。比如一个C开发的基于事件(网络IO、信号、超时、 甚至磁盘IO)驱动的服务程序便是一个很好的容器,它接管了所有事件处理,提供了一些标准的资源访问接口。任何应用逻辑都将被实现为一个动态库,按需加载 到该服务程序中,从而能通过自身实现的消息回调函数执行具体的业务逻辑;同时对内存、磁盘当访问也都使用容器提供的特定接口完成,不再直接调用标准库。如 此资源使用、对外通讯都被容器所监控——Google的App Engine就是类似这种实现的,不过不是借用了一些语言虚拟机的能力罢了。

        如果应用不情愿使用容器提供的资源接口,而是按传统方式申请资源。那么从外部使用cgroup等手段也可达到资源配额管理的目的。

        Ø 接管IO

        只从容器限制应用服务的资源还不够,因为容器只能控制自己本身的资源使用。但是对是整个机器的资源却缺乏“全局控制”。若要从机器角度控制资源,不能仅靠容器,而应该借助于独立的驻机监控程序完成。

        Cgroup实际上就是一个这样的监控程序(虽然实现于内核),它可以控制机器上所有程序的资源(CPU/Mem)配额。

        IO配额管理也同样道理,需要接管服务程序接管机器上所有程序的IO使用——即,代理所有IO请求。机器上所有其它服务程序都不能再擅自直接使 用IO,而是将请求交给代理服务进行;机器之间也不会存在服务socket直连,只可能是各自的代理服务socket连接(其实这也可减少socket连 接资源占用)。

        这样做的好处是:代理服务能控制所有应用服务的IO配额,从而避免资源争用——坏处不用说:IO流程被加长,效率低了点。

        注意,我们这里所说的IO包括网络IO,也包括磁盘IO。网络IO代理可以做的类似于消息中间件,甚至可以实现点播、组播、广播、故障切换等功能。磁盘IO代理则还要考虑管理多个磁盘的IO排队,优先级问题等。

        分区、调度策略、故障恢复等智能下放给应用

        上一个章节我们分析了应用之间的差别性使得很难存在一个超级Master一刀切的处理各种应用的分区、调度、故障恢复等“智能”的行为。尤其要 认识到越是基础性的服务——尤其在线核心服务,其“智能”越强,因为其可用性等要求越严格、设计也更具复杂性、也越难进行统一方式管理。

        比如,对于可用性要求比较宽松的应用服务而言:Master探测到slave发生故障后,再重新在另外机器上启动一个新实例(可能还要重构上下文),然后再对外提供服务。这个时间很可能需要数分钟之久(探测故障需要花时间、重启实例需要时间、重构上下文需要时间)。

        再高要求一些的应用,备用实例可能预先启动好,所以切换时只需要重启上下文(如Hbase就是将故障分区交给其他在分区管理)。

        如果要求继续加快故障切换时间,那么就需要使用热备热切方式了(所谓热备份是指实时同步主备之间数据同步,保持同构上下文)。

        如果这还不够,那么就采用对等网结构,也就是无主结构(保证系统无单点)。客户端可多点提交,各点之间的一致性通过集中决策等技术保证(如dynamo系统)

        说了这么多,无非是告诉大家,不要指望有一个超级智能的大Master能搞定应用程序的各种智能,尤其是越重要的应用越难接管。所谓人贵在有自 知之明,当我们熟悉互联网应用的复杂性后,就别再强求做大一统的Master了。不如退而求其次,放手将智能性的动作下发给各个应用服务本身把,因为只有 他们自己更了解自己的需求。

        下放智能意味着各应用可以有自己的Master来处理个性化的、“智能”高的需求,而智能低的需求当然可以交出去统一完成了。

        注:master传统意义上负责那些职责(笼统概念,实际并非绝对如此,往往都是具备下述部分功能罢了):

  • 负责存储原数据——slave节点位置信息、各服务实例运行配置。总之是应用之间的数据中心。
  • 负责管理命令——由于安全、以及元数据集中管理的原因,管理类命令一般只发给master,然后如果需要master再发向slave。
  • 负责数据分区和调度实例——化整为零的工作由master做。
  • 负责故障监控——探测slave故障(如通过心跳)、并可做出故障切换。
  • 负责负载均衡——采样负载信息(常通过心跳报实例负载)。

        放弃统一的负载监控、动态调度

        很多时候我们宣称能削峰填谷式的使用集群中所有资源,可以根据集群中机器资源使用情况,动态调度应用实例。这样不但可消除热点,也能节约资源, 因为应用实例可按需使用资源,不用的可以将资源还给大资源池。这种分时复用资源的方式无疑是很符合大老板的审美观——似乎资源能被最有效的利用了。

        但如果你多实施几个大应用,就会发现这么做不大现实。因为你会碰到如下几个切实的障碍。

        1. 监控实例运行态负载带来的压力

        监控实例运行状态不是无代价的。监控意味着需要频繁对实例采样和上报超级Master,上报必然要占用宝贵的网络带宽,尤其是要占用超级 Master所在机器的带宽(有时会利用前置卫星机分担Master压力);而且超级Master还必须不断记录和随时计算这些上报的负载信息。如果想尽 可能及时发现负载变化,那么就要求尽可能频繁负载采样,从而给Master带来更大传输和计算压力。随着越来越多的实例,Master将承担越来越重的压 力,直到无法承受。

        通常网络环境(千兆以太网)和机器情况(numa体系的8核路服务器)情况下,大概到6000-10000个实例(一个机器可运行数个实例)就 是监控上限了,因此可见大Master方案本身对扩展性就有制约。所以还是那句话,放弃大Master调度,各应用的Master负责监控自己应用实例。

        2. 调度代价太大

        理想中当发生热点时,必须将肇事实例或相关实例迁移走。但迁移服务是有巨大代价的:

        Ø 迁移很可能需要影响可用性

        Ø 迁移很可能给网络带来压力(重构上下文需要网络流量)

        不过这些都不是最纠结的事,最纠结的是调度是否真的合理未尝可知。因为我们调度无非是依靠曾经的负载情况推断未来的负载情况——当发现眼前某个 实例运行资源不足时,需要找一个眼前和这一段时间负载都不重的机器,将实例迁移过去。但是眼前资源不足也许只是一个突发事件,而眼前和近一段时间负载轻的 机器也许很快也将迎来自己的压力高峰。如果调度碰到这种情况,就需要再重新调度,当然还有可能又出现类似情况——这就是抖动。如果这样,那反而不如不作为 的好。

        就一个公司而言,应用数量有限,而且因为地域性或者应用特性很有规律可循,那么负载规律也是有据可循的。有据可循自然容易合理调度(甚至可以制 定完美的调度计划——消峰填谷式的资源消耗不同类型应用混合部署,也可差开时间段运行不同类型应用等)。但是当你需要提供公共云服务时,天南地北、鱼龙混 杂的各种应用就难说负载有据可循了,发生调度抖动的潜在危险也将大大增加。因此与其去动态调度,不如大方一点(不大方也不行呀),给每个实例一个资源配置 上限,即便运行时资源利用不到上限,也不会让别人占用——简而言之,实例资源不复用,让实例霸占吧!!!。

        现实中云计算大约的架构

        下来简要总结一下当前业界所能接受和未来可能接受的云计算架构。

        数据总线(Data Bus)

        我们试图接管集群中所有的网络IO请求,实现下述功能。

  • 面向应用的配额控制
  • 优先级控制
  • 流控(滑动窗口)
  • 通讯故障处理
  • 异步或同步消息

        甚至可以将很多通用消息功能做到数据总线上:

  • 点播、组播、广播
  • 负载均衡

        消息总线实现和部署特点是:

        1. 数据总线是驻机后台程序,每个机器理论上只部署一个。

        2. 数据总线服务程序两两之间只借助一个sock完成通讯,已节约连接资源。

        分布式块存储

        我们试图将集群中机器所有磁盘都能通过网络方式连为一体,形成存储资源池。其目的在于:

        1. 资源池化可防止局部存储资源不足(单机存储不够),使得资源利用最大化。

        2. 存储资源(磁盘存储)和计算资源和内存资源剥离,从而解放任任务调度。

        3. 接管所有的磁盘请求,原则不允许应用直接访问本地磁盘。

        4. 存储高可用性,不比再担心磁盘故障(多副本等冗余技术保证)

        运行容器

        容器完全是个逻辑概念,虚拟机是容器(机器虚拟机,系统虚拟机,语言虚拟机),进程也是容器。容器不在乎实现,而是在于是能做到应用资源受限使用(重在内容,不再形式)。

        驻机精灵

        说白了就是一个系统默认服务(系统安装好就在其中,系统启动后就自动运行)。这个驻留精灵应该具备一下功能:

        1. 按要求下载指定应用的应用程序发布包

        2. 对应用程序运行期管理——启动、关闭、暂停、恢复。注意当发现应用crash后,精灵往往要负责重启,以提高系统可用性——这点可参看erlang的supervisor,都是类似的东西。

        3. 对应用程序资源配额限制——比如采用cgroup规定资源配额;或者监控proc性能指标而调整nice 、或通过suspend/resume信号控制程序运行(好比轻点刹车一样)。总之方法很多。

        4. 汇报系统状态——状态包括有:静态状态(系统版本、机器资源等);应用状态(runing,crash等);机器和应用负载(上文分析了负载可能会带来性能问题)。

        资源分配中心

        资源分配其实映射为程序运行容器(可需可实)的分配。资源分配中心要有集群中所有机器的资源信息和位置信息。当有应用需要运行一个应用实例时, 就向该中心发出请求。中心从资源池中找一个能满足需要的物理机,然后告知该机器上的驻机精灵去获取该应用的发布包,并按要求启动应用实例。

        上述是一个概要描述,具体实现可能要做如下几个考虑:

        1. 应用和资源中心可协商资源(讨价还价)—— 比如应用的master向中心要100个20G内存的运行容器,而中心发现资源池不足这么多可用容器,那么告诉只能给90个15G内存的容器,你要不要? Master则根据具体情况,看是接受还是拒绝(如果可以将就着接受,那么master继续启动;如果不能接受,则拒绝退出,不继续不启动)

        2. 容器的资源请求可能受网络环境、机架位置等约束。因为除了内存等资源要求外,有些应用有机架感知要求(如HDFS)、或者有网络布局要求(如要求在一个路由器下等——虚拟机动态迁移往往需要统一路由器下,fake arp才能走通)。

        3. 有时也能接管一些力所能及的负载均衡或故障切换等功能(注意,复杂的智能逻辑可做不来,应该交给应用自己的master处理)。当然这要在应用允许情况下(如发现机器故障——精灵可报告,中心负责重新选择一个新机器,再启动一个新容器,并重新运行该实例)。

        资源分配中心的存在为应用部署、管理提供了很大方便。Google内部使用的borg就是这种系统的代表(对应的驻机精灵叫borglet —— borg是德语城堡的意思,感觉不打贴切,不如我们曾经开发的matrix系统,对应的祝机精灵叫smithJ)。

        另外值得注意的是应用资源描述问题!最高境界是开发一个描述性语言,做得简陋点就用XML、json等搞个配置文件,应用资源被描述其中。资源描述应该覆盖如下方面:

  • 角色(如master, slave)—— 一个应用可能会包含多个角色(这点和erlang中一个relase有多个application类似吧)
  • 角色实例的资源要求 —— 内存量、IO吞吐、CPU能力等等
  • 角色实例故障后是否重新启动 ——    如erlang中superivsor选择重启的几个方式
  • 角色的全局地址—— 类似于erlang的全局注册名等,供别人访问
  • 还有很多七七八八的限制等,如依赖服务、日志级别、性能计数等等,不再唠叨了。

        全局命名中心

        为了对各应用通讯寻址实现解耦目的,我们要避免应用实例之间直接写定对方IP和端口地址(如写在配置文件中)来实现通讯。因为直接给定IP意味着各程序的运行宿主机固定不变,也就意味着我们失去了服务迁移、故障切换等自由——意味着资源被绑定。

        若要解开资源绑定,我们需要使用逻辑地址代替物理IP+端口方式寻址,而逻辑地址具体绑定那个物理地址则是可变的。比如应用的逻辑地址(类似于 一个URI)是http://myexample.master,其开始运行在192.168.0.1机器上,这时逻辑地址http: //myexample.master实际指向192.168.0.1(端口2000);但当应用被迁移到192.168.0.2机器上,这时同样的逻辑 地址http://myexample.master则又指向192.168.0.2(端口2000)了。

        显然上述的逻辑地址到实际物理地址的映射关系需要存储在某个地方,这便是我们所谓的全局命名中心。实例之间只知道对方的逻辑地址,相互连接前都 要询问该中心获得真实的IP地址,然后才能进行连接通讯。当通讯失败(很可能是被连接实例切换机器了)后,需要再重新去命名中心询问该逻辑名对应的新物理 地址,再重新连接——这种更新逻辑地址映射关系和实际连接则往往是客户端负责的事情了。

        Erlang 中的global模块提供的进程全局注册服务,完成的就是类似功能,只不过erlang的global服务没集中存储这个命名关系,而是分布存储在集群中了。

        配置管理中心

        配置中心为各应用实例提供了一个配置信息的集中存储地。所有应用都可以将自己的配置信息,尤其一些动态变化的配置信息(静态一般就由配置文件管理)存储在该配置中心中,从而能在需要时(如重启后)从配置中心获取对应配置。

        比如HBase中的range分区信息和Range Server的位置信息都属于动态变化信息,这些信息传统上是交给Master维护。但更合理的做法是将这些原信息存储在统一的配置中心,如此以来即便 Master倒掉,也可借助查询配置中心获得上述信息了——简单讲,Master把原数据存储功能交出来了,自己不再负责,因为元数据存储智能要求不高, 完全可以由一个通用服务——配置管理中心——负责。 

        分布式锁

        分布应用中难免有需要串行化完成的动作——任务需要有序执行;或者有需要保护的临界资源——一个时刻只能一个实例访问。

        上述的锁要求和线程锁的需求很类似,不同无非是放大了执行单位——从线程粒度变为实例粒度。使用上遵循非强制锁(协同锁)的使用方式,即锁被作 为一个外部服务,只提供加减锁以及检测是否加锁的操作,但是不提供锁的控制与协调工作。依赖于各应用自觉的去检测是否加锁,然后通过内部协议来约束各实例 的行为。比如bigtable使用分布锁chubby完成表格防并发访问,就是各实例自己负责访问前加锁,访问后解锁。

        故障监控服务

        我们上面提到过Master的各种任务,其中有一点是负责监控slave各节点是否正常。如果发生异常则要进行故障切换等动作。而具体状态监控则往往通过心跳等方式——当发现slave出现连续几个未报心跳时,则认为slave发生故障。

        显然监控状态这点事,也属于通用型功能,完全可以提出来由一个公共服务来完成。也就是实例的心跳都报向该心跳监控服务,将故障探测这个脏活交给从我们特有的应用中剥离出来。

        除了简单监控各实例死活外,可能还要将其死讯通知其伙伴才算有始有终——因此告知给定的”联系人”也应该是该服务所接管。

        在分布系统中碰到故障时的主备切换(这里主从是active – non active关系,别和master/slave模式搞混淆),完全可以交给上述监控服务完成——当发现主点倒闭后,则通知备机点变为主,完成故障切换。

        另外,为了避免系统双主出现(因为往往主点要求必须是逻辑单点,才能确保操作的串行化次序,所以如果系统出现双主,那怕暂时,也则会造成的数据 错乱)。因此各实例常常需要和监控服务定一个租约协议:当租约超期时,监控服务负责通知备机(重新选主);租约到期的实例则自杀来防止系统双主出现。

        注意:

        全局命名中心、配置管理中心、分布锁服务等几个服务作为全局服务都有一个毋庸置疑的要求——高可用性;另外一个共性则是还一定的存储能力——存储配置、命名等记录信息、锁记录;最后一个共性是服务必须逻辑上单点(即便内部用小集群实现),才能原子和串行处理请求事务。

        我们必须感谢开源项目zookeeper(打心底敬佩yahoo公司,虽然它业务上最近不大景气,但从其推出的zookeeper、S4等重量级的开源系统来看,无疑国内公司还未有能达到其高度的,至少开源胸怀上还不能相比),因为它一气呵成的提供了上述三个服务。

        Ø 它采用Paoxs类协议实现了高可用性(容错率达到2F+1),以小集群形式实现了逻辑单点;

        Ø 它采用树形结构存储描述实现了配置存储管理和分布锁;

        Ø 它采用租约协议实现了故障监控(不需要我们自己实现心跳探测)。

        从而用一种架构同时提供了上述几种全局服务,逐步成为分布系统服务基石之一,越来越被业界所认可——不少自视甚高的公司最终都选择zookeeper,放弃了自己独自开发类似项目的想法和实践。

        不过要知道zookeeeper强于高可用性,而非存储能力,虽然它确实可用来存储一些配置类信息。但因为任何Paoxs协议需要在小集群中一 致性协商,所以性能必然随集群规模而下降,尤其是写性能。所以不要把zookeeper当作key value服务那样,进行频繁IO请求。如果你只是想找一个可靠的地方存储你那些不大变化的元数据,那么选择zookeeper无疑是明智之举。比如很多 时候我们将分布系统的第一层(最上层)原信息存放在zookeeper上,比如你可以将向将hdfs的namenode分布化——将第一层分布分区和位置 信息存放在zookeeper之上。

        各种结构或半结构化数据存储

        数十年来使用的关系型数据库在当今互联网应用场景下已经显得有点力不从心、或者说不合时宜了。究其原因大约如下:

        1. 扩展性(scalability)不够好。关系型数据库实现上那些范式规则强调数据关系约束性,但在大规模分布系统上实现这些约束,显然则不是很高效——性能不会很高。

        2. 可用性不够好。传统上数据库实现多采用专用机器或者说将异常情况交给硬件处理,本身软件层面错误处理做的比较少(也就是主从备份等吧)。而互联网世界中更 多采用大量廉价存储机器搭建起来,因此错误更常态化,所以软件要做更多的容错工作——多副本、故障切换等考虑要更多。

        3. 数据组织方式不合时宜。关系型数据库更合适处理离线的数据仓库这种复杂关系模型的统计、分析任务。而互联网上面数据组织和查询有所区别,具体来讲:

        Ø 可能需要历史版本。

        Ø 可能关系性要求弱,而强调访问速度,因此可能需要进行——空间换时间、反范式化、利用过滤代替jion、非精确查询(允许少量错误)等折中手段达到性能要求。

        Ø 可能数据更稀疏,列访问特征突出。

        Ø 可能需要图元遍历,比如广度和深度遍历好友等。 

        总而言之互联网世界受欢迎的存储系统(不敢称数据库系统)会有:

  • Key Value 存储 —— 代表作有dynoma (对等网实现) 、MemcacheDB、Tokyo Tyrant等
  • NoSql 存储 —— 代表作有Bigtable 、HBase 等

        他们最大的共同特点是扩展性很强、总体性能几乎可以线性扩展!弱点是和关系数据库相比,关系特性要简单的多,key value不用说,就是bigtable、Hbase等NoSql存储也只是支持简单的select查询,复杂join、事务操作、存储过程等强关系操作 都能不支持。

        更重要的妥协还在于放弃了传统数据库的ACID(Atomicity-原子性、Consistency-一致性、Isolation-隔离性、 Durability-持久性)精髓;而去拥抱BASE(Basically Availble-基本可用、Soft-state、EventualConsistency-最终一致性) 和 CAP(Consistenc-一致性、Availability-可用性、Tolerance of network Partition-分区容忍性——可理解为部分节点故障或节点之间连接故障下系统仍可正常工作)。

        这种弱一致性妥协极大松绑了分布式存储设计,虽然和完美主义要求有不小差距,但对互联网世界来说,够了!!!

        存储的分层实现策略

        如果能忍受性能上的一定损耗,我很赞同数据存储的分层实现——即最下层是抽象类的块存储层,其上是分布(式)类文件系统层,建立在其上的是结构 化和半结构化数据存储层——即hadoop中的ssFile,hdfs层和其上的hbase的关系(google 也是分层设计的拥戴者)。

        所谓类文件系统层就是在用户态实现的分布式存储系统,又为了方便管理实现了一些类文件操作的语意,如open/close/write /read/opendir等等。结构化和半结构化存储层则是建立在类文件系统层之上,自己按需组织数据——数据又已文件形式存储在类文件系统之上。

        类文件系统这层负责所有集群磁盘资源管理:负责处理数据冗余存储(多副本)、负责机器容错(故障切换)、负责负载均衡等等任务。而上层结构化数 据存储层则不再关心这些特性,只需要处理具体的数据组织。这种分层实现避免了各种结构数据存储系统重复开发分布系统的通用特性,也很有利于运维简单化。

        另外值得一提的是我个人很赞同类文件系统层采用——只允许追加方式修改的设计,不允许随机修改。因为这样做带来了好处很明显:

  • 写操作只会顺序向前进行,对于IDE硬盘而言,能提供更大的写吞吐和写响应速度(对于SSD而言虽然没有磁头机械臂的移动,但其实顺序写也会带来巨大收益)
  • 不允许随机修改,对于系统多副本一致性和故障后的反熵(同步各副本差异)操作带来了很大遍历,简化了很多。

        当然,如果下层的类文件系统只能追加写,那么上层的结构化存储必然需要以log structure方式实现。比如其上实现leveldb那样实现key value结构存储;或者hbase那样实现nosql结构都是如此。Log structure存储系统实践证明,性能没问题,而且很容易实现历史版本查询,还可实现快照等我们梦寐的高级功能;其代价则是需要更多的磁盘空间(还 好,当前认为最廉价的就是磁盘了),还有经常的垃圾回收(别怕,总有闲的时候让你回收)。

        再次做一下广告,我们cloudxy中子项目hlfs就是在hdfs之上实现的log structure 磁盘镜像存储系统,请见http://code.google.com/p/cloudxy/。欢迎喜欢云计算和开源的朋友加入。

        重要思想重申

        上面分析了似乎不少,其实各个部对于做分布式系统的朋友来说都应该都不陌生。只不过大家可能过去更多关心具体的分布应用、或者分布存储、或者调度等专用系统的设计开发,而不大会上升到全公司甚至更大范畴的基础架构体系角度去考虑——如何消除重复劳动、提高资源利用率。

        所以思路的转变是做云计算的首要前提——要从宏观上考虑云计算实现,而不是一城一池的得失;其次从云计算技术上讲其实并无太大跃变,其仍可看做是分布存储、并行计算等普遍技术的再升华——主要体现更强调大规模、强调普通硬件、强调低成本等。

     明白上述两点,就能除去云计算的神秘。这里我们回过头来再重申几个云计算架构设计中的核心思想,我们把握这下面几个主要原则,有所为有所不为。

        Ø 分层划分和实现功能

        尽可能将系统分层设计(虽然会损失一定性能,但你得到的更多),这样每层能各司其职,非常有利于功能收敛、系统稳定;减少重复劳动;便于调试; 便于优化;解耦等。只有在一个好的层次结构下,系统才能有序演化。所以很建议将资源分配、块存储、类分布文件系统、结构数据存储等功能分层实现。

        Ø 接管资源分配

        尽可能接管一切资源分配工作,原因很简单——我们希望做类似超级计算机,那么就需要像单机操作系统那样,在集群中接管资源分配:包括内存、 IO、存储等。莫要让用户程序自己直接调用本地操作系统接口使用资源,以防止从全局角度失控。比如不要让用户自己直接写本地磁盘,而是使用存储服务操作; 也不要让不通机器程序自己直连,而是要委托消息中间件进行连接。

        Ø 应用服务上下文分布存储

        为了达到准实时的failover,以及按需调度服务等弹性,就必须保证服务的上下文数据不能本地持久化,而要分布式持久化到远程,从而应用运 行和位置无关。不怎么变的小数据可放在zookeeper中,大数据可借助于key value、hdfs、hbase等存储。

        Ø 化整为零管理

        不要指望我们的云无所不能,无所不知;不要让其做智能太高的事情,与其让云告诉我们该做什么,不如我们告诉它该如何做。所以对于故障迁移、任务调度等差异性大,应用耦合性高的逻辑还是下放给应用自己去管理吧。

        对外服务该如何做呢

        当你真有了这么一套分布式体系架构后(即便没有也可以对外服务,只不过运维成本很高罢了),对内服务搞定后(即便没搞定也没关系,对外也可以服务J——往往内部阻力更大),那么到底如何对外出卖服务呢?

        在谈服务方式之前,首先我们要清楚云计算服务的对象是谁?服务包含那些内容?

        广义上讲任何互联网服务都能纳入云计算(至少他们这么宣传),为了不陷入茫茫云海,我们收敛一下,只谈一下侠义的云计算——出卖计算能力、存储能力;那么显然我们的服务对象就是第三方互联网公司或者个人应用。

        对外服务方式业界已经有两个案例供我们借鉴。一个代表是亚马逊的EC2 (服务stack中还有simpledb,s3,消息中间件等等);一个是google为代表的app engine(服务stack中有HRD等)。前者是基于虚拟机容器为外界提供计算、存储服务;后者则是通过语言虚拟机+受限进程容器对外提供计算和存储 服务。

        到底孰优?孰劣?

        APP ENGINE和虚拟机比较

        APP ENGINE和虚拟机(我们这里专指机器虚拟机如xen/kvm)概念上应该属于一个范畴:资源沙盒;但实现差别很大。所谓尺有所长,寸有所短。它们也一样,各自有自己的优势,也有自己的不足。具体如何选择,我们分析看看。 

        Ø 谁更轻,谁更重。

        我们所谓轻是说系统资源使用更少,更有利于资源复用。搞操作系统的人应该都知道APP ENGINE相比虚拟机更轻,原因很简单:

        1. APP ENGINE不需要模拟硬件平台,它作为宿主操作系统内的进程运行;而XEN需要模拟硬件平台,需要截获敏感性硬件指令转换处理,也需要运行级上下文切换。

        2. APP ENGINE更有利于资源复用,因为其不需要预先霸占资源(主要是内存资源),而是按需使用(你甚至可以突发性使用整个机器的内存);而XEN等虚拟机则 需要预先霸占资源(虽然QOD等模式也开始学习按需使用内存,但超限使用内存还是很难——除非你愿意费劲去采用热插拔技术;另外值得赞赏的是TMEM技术 似乎可以避免预先霸占,但不幸的是它需要修改DOMU的内核中的内存分配例程)。

        轻重就这些区别吗? 其实不然,我个人认为系统虚拟机最重的是对网络资源(mac地址ip地址)的使用!系统虚拟机每个都会霸占一个mac和ip地址,别把村长不当干部,以为 虚拟的网络地址不是真实地址。对于路由器、交换机等网络设备而言,它们仍然会占用地址映射表等。一般路由器ip-mac表也就3000多项,用一个少一 个,所以大规模系统使用虚拟机势必要定制更多表项的路由器;另外,如果是大二层网中运行众多虚拟机,则广播风暴也是一个不得不考虑的麻烦。所以虚拟机对网 络设备来讲更尤为“重。

        Ø 谁更友好,谁更约束。

        使用APP ENGINE的最大不便在于,你必须接受它的约束——资源访问需要按照其规定的接口进行;不能自己启进程等。这种不便使得APP ENGINE多是被个人票友所热衷,而公司用户没有几个。公司若要使用APP Engine则必须要修改自己已有程序、修改自己已有运维方式、更糟糕的是开发人员培训或者招聘成本都要高很多(市场上找一个会Linux开发的人,要比 找一个会app engine开发的人要容易的多)——当然这些不利因素对于公司内部使用倒不存在,所以google自己内部使用app engine到是可行(但我也听说gmail也不再使用app engine了,难道内部都推不开吗?)

        机器虚拟机则对用户很是友好,所有程序都可以不加修改的运行在机器虚拟机当中,如果实现二层虚拟子网,那么已有的管理软件都可原封不动迁移过来 ——再次做一下广告,我们cloudxy项目目标之一就是实现二层子网虚拟化。所以对于用户而言,他们显然更喜欢机器虚拟化方式的云计算服务。亚马逊在美 国的成功也证明了这点——注意一下,在美国成功不代表在中国也能成功,毕竟互联网在中国还是暴利,所以没有多少像样的企业为了节约目的而使用你虚拟机租赁 服务,另外在当今国内环境中,也没有几个企业敢于把自己核心数据托管到别人提供的虚拟机之上。   

        注:

        除了xen/kvm机器虚拟机外,还有zone,vps等系统虚拟机,以及jvm、python等语言虚拟机、进程虚拟机qeum,甚至普通进程也可看虚拟机。从轻重角度将,机器虚拟机最重其次是系统虚拟机。

        云计算生态圈

        下来说的纯粹是题外话了,都是个人观点,不知所云:)

        云计算如果仅仅是提供计算资源和存储资源服务(如亚马逊那样),我个人认为只是一个初级形态,而且在中国可能没多大前途。

        个人认为真正理想的云计算应该是一个“围绕数据服务的生态圈”,在数据周围应聚集大量的第三方应用——他们使用数据同时又产生数据,从而数据越来越多、越来越有序;应用也越来越丰富、越来越专业——这就犹如滚雪球,良性循环,价值逐步放大。

        伟大的企业一定是积累了足够有价值的数据(网页内容、买卖记录、用户关系等都属于数据)。不管怎样,要明白第三方企业入驻入你的云计算服务,首 要是希望获得你的数据或者流量(我认为前者更重要),而不是看重什么计算和存储服务(互联网暴利时代,机器成本目前还不是企业最紧迫的问题)。但如果在你 的云环境中更有利于他们获得数据和流量,那他们自然而然会接受将服务hosting到你的云中。

        以ebay为例来说,长期积累的交易记录就是其最有价值的数据,这些数据准确、有序、结构化强,非常有利于检索、分析;假若再结合交易者信息, 个性化服务则是举手之劳(如果不涉及隐私的话);另外它还有很强的入口作用。这些无疑都是吸引第三方应用的重要因素,如果他们开放数据,又提供托管环境 ——托管环境中能更快访问其数据,甚至还能提供统一的支付、用户认证等服务,那么无疑第三方是愿意租用其计算和存储服务的。而第三方应用,尤其那些数据分 析应用所产生数据又可被其它应用所使用,则就进入了上面谈到的滚雪球模式了:)

        国内的百度、腾讯、阿里、新浪微博等几个大佬们都有自己的数据和入口地位。百度搜索入口能力强,结构化数据弱一些,比较适合于咨询类应用;腾讯 游戏/sns类入口能力强,用户关系数据强,适合游戏类应用;阿里电子商务内入口能力强,结构化商业数据丰富,适合于商务服务类应用;新浪微博用户极度活 跃、消息产生和传播优势明显,也很适合做咨询和游戏类应用。所以这几家做云计算成功可能性最大,希望他们能抓住机会,取得成功。 

        不成熟的几个断言

        Ø 专用系统必然比通用系统性能更高

        Ø 网络带宽是当前云计算中的最短板

        Ø 没有能统一天下的云计算环境

        Ø 云计算绝不等于虚拟机,虚拟机只不过是沙箱实现的一种。

        Ø 绝对的实时调度难以在实际中做到,自动化管理可以期待。

        Ø 万兆网和SSD等新硬件的到来将带来云计算架构的变革。

来自:http://blog.csdn.net/kanghua/article/details/7232191