我有分寸

改变互联网的IaaS服务

gnawux IaaS《程序员》云硬盘云计算cloud
原文发于5月号《程序员》

改变互联网的 IaaS服务

4月10 日早上,我和老婆提起,“今天早上的大新闻是 Instagram被Facebook 收购了, 10亿美金,iOS 平台上最受欢迎的拍照分享服务”,我故意顿了一下,说“这家公司现在只有 13个人。”老婆立刻惊问,“他们怎么做到的?”确实难以置信,在去年年底冯大辉先生在DBANotes的《Instagram 架构笔记》(http://www.dbanotes.net/arch/instagram.html)里提到,“只有三名工程师,所以自己部署机器到 IDC是不靠谱的事情。幸好有亚马逊。” 是的,是亚马逊的IaaS服务—— AWS改变了游戏规则。

本文希望从技术角度,介绍IaaS服务商借助哪些核心技术提供了这样的能力,而创业者如果希望将来能和Instagram一样,服务上千万的用户、存储上亿张照片的话,应该如何更合理地使用IaaS云服务。

互联网创业的后AWS时代

实际上,互联网的从业者都知道,在AWS上的成功案例远不止这一家,去年QCon杭州的云计算主题的引言里,笔者就提到了Dropbox的案例,Zynga的成长也是AWS的受益者,同样的受益者还包括Foursquare, Quora… 正是AWS,或者说靠谱的IaaS服务的存在,才为这些创业公司的成长铺就了道路,以至于业界有了“后AWS时代”的提法。具体地说,后AWS时代都包含了那些特征呢:

随时可用的资源池——服务上线之前,创业者不需要租用IDC的机架位,也不需要购买服务器,更不需要去机房插网线,当服务需要上线的时候,在资源池里租用刚好够用的服务即可,没有固定资产投入,运维投入也是从服务上线部署才开始的。根据Zynga的案例(Zynga在没用AWS时,用户增加,运维加班严重,运维老大怀孕的老婆都来机房帮忙插网线,后来用了AWS,就再也无此窘境了 https://blog.khsing.net/2011/10/%E6%94%BEamazon%E7%9A%84%E6%88%90%E6%9C%AC.html),网友曾经杜撰过一条广告词——“AWS,让你的老婆在家安心待产”。

快速弹性——如果仅仅是方便的主机资源,那么也就不需要所谓“云计算”了,VPS们已经做得很好了。但是,Draw Something只用了几周就有每日1500万活跃用户和每秒3000张图片,Animoto 需要在3天之内将主机从5台增长到5000台(http://www.weibo.com/1642316384/yaS0on3xm),这样的规模和扩展速度,不仅依赖于网站的良好架构,也依赖于基础设施服务的高弹性。换一个角度考虑,如果你期望自己的服务也可以以这样梦幻速度增长,却不希望一下就准备这么多资源的话,具有快速弹性的IaaS服务无疑是你的首选。

用量计费——有了上面两项特性,相应地,成本也需要细粒度地按照用量来计算才划算,对于主机,只需要为运行的时间付费(随时可以新申请或释放掉主机资源),对于存储,只为使用的空间和流量付费,对于网络,只需要关心实际使用了多少流量。这样更能为小型的刚刚起步的服务节约成本。

按需自服务——所有上面的特征都依赖于便捷的使用,IaaS服务不仅可以通过页面点击完成资源的申请和释放,而且可以通过API,直接编程进行资源操作,配合自助的监控服务,IaaS的用户可以根据服务的负载情况,自动的增加或删除使用的资源,既保证终端用户的体验,又无需无谓付出成本。

新的互联网创业模式正式建立在这些特征之上的,他们可以更专注于应用的开发、低成本地提供服务。下面我们就来看具体提供这些特征的核心技术,以及如何使用这些技术和服务,确实获得这些期望的特征。

弹性的基础设施

IaaS的基础设施提供了从计算到存储一整套和传统计算机平台完全一致的环境,从而最大程度地方便了既有应用向云平台的迁移,但是云平台也不是“银弹”,并不是一切传统应用迁移到云上就可以无限扩展了。要想引爆云平台带来的弹性,还需要可扩展的网站架构以及合理利用云基础设施的各项实用功能。

面向扩展的服务架构

成为“合格”的云应用,服务架构自身的体质是最重要的。可扩展性,或者说弹性、可伸缩性,追求的是,当服务的节点规模增加时,服务能力也可以线性或近似线性的提升。这就需要服务请求可以被良好地、互不干扰地分配到多个节点上执行。

简单地,我们可以把一般的网站架构分成“服务”和“数据”两个大的层次,前者接纳用户的访问请求,执行各种计算任务,从数据层获取状态信息,并将可能存在的处理结果持久化到数据层;而数据层则要保证数据的正确性、一致性和可用性。

为了线性扩展,服务层就必须做到无状态,这样,任何新上线的节点都可以分担同样的负载请求。同时,要对数据和对数据的访问进行均匀的分片(sharding),在著名的eBay的分布式实践(http://www.infoq.com/cn/articles/ebay-scalability-best-practices)中,强调任何数据都要被分片,并避免分布式事务,这样,当面临海量请求的时候,才可以分而治之,而不是互相影响导致崩溃,重蹈火车订票系统的覆辙。尽管“分治”的思路很简单,但要做到均匀且可动态扩展却并不容易,一方面需要合理选择划分依据,另一方面需要数据存储层面的一些配合,后面的内容还会继续介绍多种云中的和分布式的存储技术。

虚拟化技术:弹性的基础

笔者个人并不赞同过度夸大虚拟化对云计算中的意义,显然虚拟服务器上的服务不能被称为“云服务”,但也无法否认,正是日益成熟的虚拟化技术,才让云计算的IaaS服务真正可以成功地大规模投入商业运营。

David Wheeler的有一句名言:“计算机科学中的一切问题,都可以通过再增加一个中间层来解决”(Diomidis Spinellis. Another level of indirection. In Andy Oram and Greg Wilson, editors, Beautiful Code: Leading Programmers Explain How They Think, chapter 17, pages 279–291. O'Reilly and Associates, Sebastopol, CA, 2007.),虚拟化计算技术就是这个在多任务操作系统出现之后,又在操作系统和硬件之间插入的中间层,它解决的问题包括:

  • 一台计算机的处理能力已经足够满足多个用户的需求了,但在分给多个租户的时候,他们需要的操作系统环境不尽相同,也需要彼此安全地隔离;
  • 动态的调整一台计算机(或者说操作系统)的物理资源不够容易,至少不容易自动化;
  • 安装或迁移一台服务器需要大量的时间,而且不灵活。

虚拟化技术主要是一种隔离与监视技术,让不同的虚拟机分享同一套物理机(主要指CPU/内存子系统)而彼此隔离、互不干扰,同时,为虚拟机代理访问网络、磁盘IO等共享的外部资源。由于虚拟化技术对CPU/内存子系统工作的干扰很少,因此,计算能力方面很少有开销,相比之下,IO的性能受到的影响会略大一些,但也是可以接受的。

目前的IaaS服务中,主要的虚拟化技术包括开源的Xen、KVM,以及VMWare的ESX和微软的Hyper-V。它们的工作原理都比较接近,以Xen为例,它通过一个hypervisor来监控管理多个不同的虚拟机(称为Domain),并将IO等访问特权资源的操作在专门的特权域(Dom0)中执行,其他的运行客户操作系统的虚拟机称为用户域(DomU)。某些DomU操作系统是被修改过的操作系统,它们知道自己运行在虚拟化环境中,并不直接和硬件打交道,于是,它可以将IO请求通过“XenBus”直接发送到Dom0,由Dom0代理完成,这种方法效率很高,称为半虚拟化(PV, ParaVirtualization)。对于不支持以PV方式运行的虚拟机,我们需要首先实现一个虚拟的设备(在Linux下,Xen和KVM的虚拟设备都是基于Qemu的),提供给虚拟机,它再将这些IO请求代理发出,这种方式的IO相比之下更加繁琐,效率更低,称为完全虚拟化(FV, Full Virtualization),优点是可以兼容任何操作系统,无需修改。

实际上,在VPS主机服务和各种内部的虚拟化服务方案中,还使用另一种虚拟化技术,包括Linux的OpenVZ、vServer以及Sun的Zone等技术,这些技术利用操作系统内核本身的特性,在操作系统中划分出多个强隔离分区,从而解决资源共享的问题。但是,这种方案下,多个虚拟机是共用同一个内核的,隔离性不高,也不可能支持不同虚拟机使用不同类型的操作系统,因此,IaaS服务普遍不会使用这项技术。

实现快速扩展的公有云运维技术

即使虚拟机可以快速分配、部署了,用户的服务程序的部署也不见得是一个简单的过程,尤其要在服务提供的过程,自动化地扩充服务器,更需要费一番力气。实际上,除了使用配置服务等“传统手段”之外,IaaS服务商们还提供自己的一些运维用工具,帮助用户更好地实现弹性服务。

这些技术之一就是快照/镜像服务,很多云服务商都已经提供了这项功能,它可以帮助用户保存虚拟机的一个快照性质的副本,一旦用户的虚拟机发生故障,可以用于恢复虚拟机;同时,因为用户的应用服务器一般是无状态的,这样,通过定制镜像可以直接快速复制出大量的包含用户应用的,相同配置的虚拟机。而且,对于实现良好的IaaS服务,镜像服务系统可以加速热点镜像的传播,进一步加速了用户服务的扩展。

通过API实现自动扩展

IaaS的目标之一就是帮助用户尽可能的降低运维的复杂度,即使用户需要随着服务规模的增长迅速扩展服务能力,仍然能够举重若轻。这里,不可忽视的一个方面就是云服务的API,对于一个“可编程”的IaaS服务,用户可以在业务需要时,通过RESTful API请求来直接创建新的虚拟机,而无需登陆管理页面。

更进一步,与监控程序配合,用户的扩展脚本可以根据性能监控的数据,用户可以实现在业务流量在一定范围内发生变化时,无人值守地扩展或缩小服务规模,既不浪费资源,又不影响服务质量。通过云监控、API和扩展脚本,以及上面提到的镜像服务的配合,用户可以实现高效可靠的自动化扩展能力。

善用存储服务

前面提到数据层对于网站可扩展性的重要性,这里就要展开介绍云中的各种存储服务。存储本身说来简单,但实际需求却很多样,有提供客户端访问的,也有服务自己的元数据;有需要持久化的,也有用于加速的缓存;有要求严格一致的交易数据,也有不太重要的状态更新;有结构化的,也有非结构化的。而不同的存储系统、存储服务也是为不同的用途所准备的,要真的做到高效、低成本、可扩展,就需要为服务选择合理的存储服务。

对象存储服务

对象存储服务是指可以通过HTTP RESTful接口的API,以键值访问的数据对象,典型的对象存储服务是亚马逊的S3服务以及国内相应的云服务商的云存储服务。通常对象就是一个文件,如图片或文档、音乐、压缩包等,而用于标识对象的键值可以看作是文件名。对象被组织在称为桶(bucket)的容器中,每个桶可以指定特定的访问权限等属性。与网盘或分布式文件系统不同,对象存储服务不提供全局的命名空间和复杂的目录树,只有桶-对象二级结构,这简化了系统的实现、也提高了访问效率,当然,要把直接使用既有服务迁移到对象存储服务上来,需要进行一定的调整:

对象存储服务的访问URL一般是类似下面的形式:

http://s3.amazonaws.com/ppt-download/cloud-bupt-phpapp01.pdf?...

URL的路径部分就是对象的逻辑结构,而“?”之后的参数部分会包含请求的Token和其他相关参数。在页面中,将附件、图片等托管到对象存储中实际并不需要太多的调整。

对于使用IaaS云搭建的云服务,推荐使用云存储服务存放需要浏览器或是客户端直接下载的静态内容,因为这样一方面可以直接使用云服务带来的高可靠、高可用性,利用云服务商提供的网络加速功能,同时,相对于虚拟机存储空间的局限性和其他存储服务的成本来说更低廉,也不会占用虚拟机服务的带宽,是一种性价比更高的存储服务。

在网页的图片和附件之外,对象存储还胜任很多其他场合,如网盘和计算机间的数据同步,著名的同步服务Dropbox就构建在亚马逊的S3上,而苹果的iCloud也被认为可能构建在亚马逊的云上。时至今日,亚马逊的S3已经是最受欢迎的云基础设施服务了,截止到2012年1月,亚马逊S3中已经存储了7620亿个对象了(http://www.36kr.com/p/79515.html)。在国内,IaaS服务商们也提供了类似的服务,但国内的用户市场还在培育之中。

云硬盘服务

云硬盘服务或弹性快存储服务(EBS, Elastic Block Store)并不是网盘,而是一种提供给弹性计算中的虚拟机使用的,具有独立于虚拟机的永久存储能力和高可用性的存储服务。对于虚拟机来说,云硬盘使用起来就是一块硬盘。用户可以申请一块任意大小(一般是1-1000GB之间的整数GB)的云硬盘,将它挂载到自己的任意虚拟机上使用,也可以将它同一台虚拟机上卸载,并挂载到另一台虚拟机上,甚至于可以删除所有虚拟机,只保留云硬盘。

相对于虚拟机自己的存储空间,云硬盘的大小更灵活、可以由用户指定;云硬盘具有更高的可靠性,即使虚拟机发生故障,云硬盘由于有后台的类似RAID的多副本保障,仍然可以保障数据的可靠;云硬盘的生命周期与虚拟机彼此独立,弹性计算服务鼓励用户在不使用时,释放虚拟机,让出资源,同时也节约自己的开销,这样的情况下,云硬盘可以承担数据持久化的功能,不必因为释放虚拟机就丢弃数据。

尽管作为一块硬盘,云硬盘显然可以存放图片、附件等内容,但并不意味着云硬盘是比对象存储更好的存储系统。两者是面向不同用途的,如上所说,使用对象存储意味着更低的成本和往往更好的客户端访问性能,可以利用服务商的网络加速能力,并且不占用虚拟机的网络流量;作为对比,云硬盘可以从虚拟机更快的访问(读取操作平均响应时间一般是小于10毫秒的),各种程序可以像访问本地磁盘一样使用云硬盘中的数据,当然,云硬盘会比云存储贵一些,因此,相对于面向客户端请求的对象存储服务,云硬盘更倾向于存放数据库等供虚拟机直接使用的持久化数据。

云中的关系型与非关系型数据库

毫无疑问,Web 2.0时代的基石之一是一种开源的关系型数据库——MySQL,但随着移动互联网和社交网络的发展导致的数据爆炸性增长,关系型数据库的范式模型和事务性限制了它们在保持原有功能性的情况下,水平扩展到更多节点上。于是,在“大数据(BigData)”时代,很多非关系型数据库(NoSQL)开始受到越来越多的推崇。

根据Brewer的CAP原理,对于一个分布式系统,一致性(Consistency)、可用性(Availability)和分区耐受性(Partition Tolerance)三个特性,只能强化其中两个。作为面向大数据的分布式存储系统,分区耐受性是必须的选择,因此,就不得不在一致性和可用性之间抉择,选择一致性的系统不得不在有些情况下无法提供服务,而那些强化可用性的服务则允许系统在某些时刻不完全一致,也就是所谓的“最终一致性”。用户在选择一个存储系统时需要选择,自己的数据模型怎样、是否需要强一致性。当然,NoSQL和MySQL之间并非取代关系,两者各有优势,并且,笔者负责任的说,大部分的应用还没到MySQL无法承受的数据规模,只是有的需要更良好的架构设计而已。

而对于NoSQL,也有很多可以选择的,比较流行的包括面向JSON文档的、灵活的MongoDB,主要用于内存缓存的、高性能的、通过键值方式访问的Redis,基于Hadoop、提供列族模型的HBase,以及同样提供列族模型的、写入性能很高的、无中心的Cassandra等。

很多IaaS云服务商也提供了SQL与NoSQL的增值服务,用户可以选择安装、调优好的虚拟机,作为云数据库服务。

CDN服务

CDN(内容推送网)服务很难确切定位为存储还是网络服务,它是用于加速用户的网络访问的,其加速手段是通过部署在接近终端用户位置的缓存服务器,向他们提供高速内容服务的。

传统的CDN服务一般是面向访问量很大的客户的加速服务,不仅贵,而且购买、调整不方便。而IaaS云服务商面向他们的客户,提供了自助化的CDN加速服务,使得中小网站也可以享受到同样的加速服务。

 展望:从IaaS到PaaS

虽然相对于IaaS,PaaS还没有大量的改变我们生活,但并不妨碍很多业内人士将其视为公有云的未来 。与IaaS的简单直接不同,PaaS服务并不直接提供资源,而是提供运行环境和功能组件(库)以及附加的服务,如数据库、队列及其他特殊功能,更方便开发者的开发、部署,而将伸缩、扩展等复杂性进一步屏蔽。

在PaaS服务逐渐成熟的同时,一些开构建在的IaaS层之上的PaaS服务也开始出现,成为IaaS的增值服务,使得两者的界限逐步开始模糊。此外,一些可以构建在多种IaaS服务上的“开放PaaS”平台的出现,更进一步方便了IaaS服务商提供附加的PaaS服务,给用户更多的选择。这一演进将进一步降低运维开销,让创业者把精力更多专注于创新和提高用户体验上,彼此共赢。

gnawux
me!#$!@#$@#$wangxu!@#$%^&*()_me