云计算概念发端于Google和Amazon等超大规模的互联网公司,随着这些公司业务的成功,作为其支撑技术的云计算也得到了业界的高度认可和广泛传播。时至今日,云计算已被普遍认为是IT产业发展的新阶段,从而被赋予了很多产业和产品层面的意义。由于意义多重,各种概念纷繁复杂,众多公司和从业人员的眼中都有自己的一朵云,正如徐志摩在《偶然》一诗中所说:“我是天空里的一片云,偶尔投影在你的波心”。传统的系统设计考虑的主要是单机环境,而云计算主要考虑的环境却是数据中心。从单机到数据中心,很多设计原则发生了根本变化,极端点甚至可以说PC时代30年来一以贯之的系统设计原则到今天已完全不适用。考虑到云计算的诸多内涵,从技术角度讲,数据中心计算(DatacenterComputing)可能是更合适的表述。本文对数据中心计算的技术领域和设计原则的变化进行了粗浅的探讨。一家之见,仅供参考。云计算简介从20世纪80年代个人电脑的发展开始,PC的计算能力不断增强,用一台PC就可以存放个人需要的所有数据并完成处理工作,比如编写文档、处理邮件等。但在互联网时代,一家互联网公司提供服务时需要用到远超过个人规模的数据,这些数据的存储和处理需要成千上万台机器的协同工作才能完成。这种服务器规模不是个人能够提供的,只有大型公司或机构才能拥有,这好像又回到了更早以前的Mainframe时代。从Mainframe到PC再到云,这正是计算机技术螺旋上升的发展过程。简单来说,云计算就是利用系统架构技术把成千上万台服务器整合起来,为用户提供灵活的资源分配和任务调度能力。这里有几个关键字:一是超大规模,包括机器的数量、用户的数量和并发任务的数量;二是资源整合,成千上万台的服务器资源能集合起来做一件事情,比如存储大量数据,或者处理一个大型任务;三是灵活与快速交付,大规模的服务器资源能进行灵活的调配,按应用需求分解成若干个虚拟的资源池,快速地支持大量的并发请求或作业。云计算技术的出现,使整理和加工数据的能力变得空前强大,这种能力可以帮我们找出很多看似无关的事件背后的规律,并用其来预测未来发展。结合移动和物联网等技术,还可以更好地服务于社会和人们的日常生活,如灾难预警、智慧城市和智能交通等。这种数据处理能力是在海量数据之上发展起来的,与作为基础支撑的系统架构技术同步发展并逐渐融合,共同组成了现在大家所看到的云计算技术。综合系统架构和数据处理技术两方面,云计算技术自下而上可分为硬件基础架构、软件基础架构和数据智能三个层面,如图1所示。图1云计算技术可分为三个层面硬件基础架构包括服务器、网络和数据中心的设计与实施等技术领域,软件基础架构聚焦于存储、计算与大规模分布式系统等技术领域,数据智能则关注数据仓库(DataWarehouse)、机器学习(MachineLearning)及数据分析与可视化(DataAnalysis&Visualization)等技术领域。值得一提的是,这三个层次的划分主要以技术领域为出发点,而通常提到的云计算三个层次SaaS/PaaS/IaaS则更多地是从资源的提供形态和接口为考虑进行划分的,二者并非同一维度。时下流行的大数据(BigData)概念可以看成从海量数据的角度看数据分析技术和软件架构支撑,包括软件基础架构与数据智能相关技术。二者都与数据有关,但其区别在于:软件基础架构关心的主要是数据的格式、容量以及访问模式等,而数据智能更在意数据的语义。而数据中心计算则是从体系结构的角度看待软硬件系统设计。下文将就相关的技术领域和设计原则进行讨论。数据中心计算技术领域与挑战如图2所示,数据中心计算包含存储、计算、实时存储与计算、超大规模系统、体系结构以及数据中心等技术领域。存储系统的需求来自两个维度。首先,大量的无结构数据需要表(Table)、对象(Object)与文件(File)等多种存储结构进行支持;其次,访问模式的不同(如只读不写、只写少读、读写均匀等)将很大程度上影响对存储系统设计和优化的考虑。图2数据中心所包含的技术领域计算系统的需求和技术特点与计算任务的类型有很大关系。数据密集型的代表是MapReduce,它对CPU和I/O的需求比较均衡。计算密集型任务与通信密集型任务都是CPU密集计算,但二者访问数据的规模不同。如果只需要少量数据则是计算密集型。而如果需要访问大量数据,比如大矩阵迭代,内存限制这些数据必须存放在多台机器上,那么往往此时系统瓶颈将转移到通信的延迟上,这类似于传统的高性能计算。通常的存储系统和计算系统只能支持到一定级别的延迟和并发度,对于更高的要求则需要基于内存构造实时的存储与计算系统。考虑到内存的特点,在存储上更适合提供具有丰富语义的数据结构。在分布式数据结构的基础上,加入流式数据处理和触发式事件处理的模型,则可以更好地支持实时检索、OLAP、PubSub等应用。超大规模系统主要通过分布式相关技术保证系统的可用性(availability)和可管理性(manageability),包括系统建模、设计、开发以及运维等多方面。体系结构包括虚拟机、服务器设计等。数据中心包括机柜设计、网络规划与设计、数据中心设计与建设等,主要关注于能效比(PUE)。系统设计原则传统的软硬件系统主要面向单机和个人,在桌面环境中使用,我们也可以称其为桌面计算(DesktopComputing)。从桌面到数据中心,应用特点和负载模型发生了巨大变化。在单机上,主要面向一个用户,他可能运行多项任务,任务可以分为前台任务和后台任务两种。用户对系统的响应性(promptness或responsiveness)十分敏感,所以前台任务通常优先于后台任务,而后台任务则希望被公平调度。这也是抢占式调度(PreemptiveScheduling)策略最终胜过协作式调度(CooperativeScheduling)的原因。在数据中心里,同样也有在线和离线两种应用类型,在线系统直接面向用户,而离线系统多用于数据处理。在线系统通常是一个大型应用服务于海量用户,用户对系统响应性仍然十分敏感。但由于用户规模巨大以及互联网服务通常免费,成本压力十分严峻,所以系统需要充分挖掘用户对响应性的容忍度。通常情况下,人对事件响应的感知能力在500ms左右,利用这一特点可以优化系统调度并节省资源。而在极限压力情况下,没有足够的资源满足所有请求,很多系统开始延长响应时间,然后在持续压力下失去响应直至崩溃。此时,为可服务范围内的请求提供正常服务,并为超过范围的请求提供快速的拒绝响应,将会给用户带来更好的体验,也能提升系统的可用性。到最后,我们会发现在线服务系统应以稳定的极限吞吐(SustainedThroughput)作为首要设计目标。当然,要在一定延迟阈值的前提保证下。离线系统主要服务于数据处理类作业,这些作业涉及海量数据,使用者的预期并不会特别高,此时的处理效率更为重要。通常,这些作业将会以批处理的方式合并执行,提升系统的总吞吐率,即资源利用率成为首要调度目标。在系统设计时,有一些永恒的矛盾需要做出折中考虑,例如延迟与吞吐、公平与效率。在桌面环境中,我们选择了低延迟和公平,而在数据中心环境中,我们选择了高吞吐(或稳定的极限吞吐)和高效率。在具体实现方案上,也带来了不同的选择,比如同步与异步模型、线程与事件驱动、线程池与队列等。从桌面到数据中心,同样发生变化的还有开发模式。PC是一个开放系统,无论软件还是硬件,每个厂商都只负责系统中的一部分,都需要考虑和不同的组件一起工作。由于用户众多,需求各不相同,只能采取按层次组织的系统架构(layeredarchitecture)以及约定俗成的标准化规范。这虽然保证了系统的通用性,以及不同来源的各种组件的有效分工和协同工作,但也带来了一些问题,例如一个功能需要穿透多层才能完成,而每层互不信任,需要执行严格的参数检查等。更严重的是,在系统的每一层中,都可能存在一些重复的功能。以存储为例,一次写入需要经历从libc的文件流(FILEstream),到文件系统的缓冲区,再到驱动器中的缓冲区,最后到磁盘上的缓存这样的长调用流程才能完成持久化(persistency)。这个流程从其中的每一层单独来看都是合理的,但从整个系统的角度看来,存在着性能浪费。另外,由于分层带来的透明性使得数据持久化不得不通过额外的fsync操作才得以保证,从而使系统的可靠性保证机制变得更复杂。此外,在架构设计时,我们也经常在谈机制(mechanism)与策略(policy)的分离。固定、明确的功能称为机制,通过灵活的可变的策略进行配置,从而使系统具有良好的可扩展性。但实际上,每层独立且透明,且通常也都沿用相同的设计理念,这其实并不能保证机制策略的有效分离,最后的系统往往很难取得可扩展性和性能的良好平衡。我们可以发现分层导致了每层都倾向于变得聪明、变得复杂,但综合效果却不如人意。而在今天的数据中心环境中,如前面所说,很多时候我们其实是在做一个超大型应用,应用的特点需要被充分考虑。另外这个系统通常只有一个生产商,可以进行垂直化的设计或整合。此时,由应用层或平台的上层提供策略,而下层只需要考虑机制,这将使系统变得更加简单,从而取得更好的性能,而扩展性也可以得到很好的保证。以SSD为例,现在的SSD在设计时通常假设由文件系统来使用。由于闪存的擦除特性,需要考虑写缓冲区,而由于缓冲区需要有预留空间也需要有复杂的置换算法和回收机制,这对性能和成本(也包括开发成本)都有很大影响。但在数据中心环境里,我们通常有完整设计的存储系统,数据组织方式和读写流程也被充分优化,对存储设备的需求就是最基本的定长块。这种情况下,SSD的逻辑其实可以做得非常简单,直接对上层暴露内部的状态(如通路、物理块),从而提高性能、降低成本。更重要的是,这将有效提高交付速度——这对于缓解服务器、网络、IDC等硬件系统的长实施周期和业务快速增长的规模需求之间的矛盾至关重要。上层对下层的要求是逻辑简单、功能单一,而下层对上层则暴露更多细节,最复杂的逻辑判断由最上层的应用来完成,这是另一种方式的层次化。而且,层次之间也不需要维持一个物理边界(如现在应用和内核之间),可以通过函数调用的方式实现柔性的层次划分。有兴趣的读者可以参考libOS【注:Exokernel】或者in-kernelwebserver【注:khttpd】的一些设计思路。从桌面到数据中心的第三个变化是评价体系。一个中等规模的数据中心通常包含数万服务器,在这样的规模下,硬件故障成为家常便饭。一般,我们通过冗余复制或者重复处理来解决硬件故障问题。在习惯了硬件故障之后,我们对软件Bug的态度也会发生变化。软件Bug中有一种偶发性Bug【注:也被称为heisenbug,意指海森堡测不准原理】最难发现也最难调试,消除这些Bug需要付出巨大的代价。但考虑到这种Bug的出现概率堪比硬件故障,我们其实可以采用同样的方式来对待。规模增长的同时,系统的复杂度也变得越来越高,以至于很多时候已经超过一个人的直接掌控能力。要去理解系统的运行状态以保障其正常运行,在这种情况下变得十分困难。此时,我们可以利用系统冗余的特点,对一些组件进行定期重启(reboot),通过重置状态降低Bug被触发的概率【注:“RecoveryOrientedComputing”】。而对于性能上的问题则更是如此,有时还需要采用数据挖掘的方法来进行优化或系统调试【注:M.K.Aguilera,J.C.Mogul,J.L.Wiener,etc.,“Performancedebuggingfordistributedsystemsofblackboxes”,inSOSP’03】。海量数据以及数据处理应用也带来了很大的影响。由于数据的规模以及处理算法的特点,很多时候系统只需要提供概率意义上正确的结果,不需要保证数据的绝对可靠,也不需要严格保证运行结果的可重复性。总而言之,互联网服务规模巨大,对成本很敏感,而且业务需求的变化也异常频繁,这和PC应用的特点截然不同。现在的系统设计原则是在桌面环境中历时30余年发展起来的,但到了今天已经完全不适应数据中