我有分寸

云计算中的持久化与安全性

gnawux AWSEBS云硬盘云计算副本存储数据安全时延cloud

前几天,亚马逊的云服务(AWS)连续发生大规模服务中断,使得默默无闻的EBS(弹性块存储)服务再次被推上风口浪尖。实际上,过去一两年间,差不多所有AWS服务大规模中断,都可以听到EBS的叹息,难怪新浪的程辉兄说:“EBS仍然是公有云最大的难点和故障点”。

作为国内为数不多的,也大概是最早提供商用EBS服务的团队成员,我当即跳出来为EBS说了几句“公道话”,之后的图灵生日会上,和刘江老师聊天的过程中,他建议我把这些想法写出来,也让用户和相关产业了解,一个EBS服务的设计者是怎么看待自己这个“故障点”的。

首先说说我的总体观点,EBS是最后一道防线,所以重大故障才往往在EBS身上体现出来。只要存储不出问题,再大的问题也不容易造成长时间、大范围的停机,不论是网络还是计算,都是无状态的,有电、有链路就可以工作,而这些也是最容易通过冗余来保障可用性的;但存储则不同,对存储来说,数据正确是我们第一要保障的,如果真发生严重故障,我们不可以为用户迫切要求的可用性而冒险牺牲正确性。

系统设计的哲学:熔断器与冗余

没有系统能避免异常情况的出现,大系统的设计中,最复杂、最难处理的地方往往是不常遇到的意外(超负荷)情况,在这里经常用到的两种策略是熔断器和冗余——

  • 系统常常设计为可以承担远高于其标称值的负荷,从而在出现异常的情况下,也能持续工作,这是所谓服务能力的冗余
  • 对于另外一些情况,我们会采取一种看起来和服务可用性背道而驰的策略——停止服务,以避免更严重的损失,这个就类似于电子设备中的熔断器,或者叫保险丝。

这两种策略几乎总是同时用到的——对普通的困难,我们争取用设计上的冗余来克服,让它对用户透明。但是,当系统无法承受的时候,就需要果断地中断服务。什么情况下中断服务,总是设计者最为头痛的地方,他们不愿意向用户暴露自己脆弱的一面,但也不能背弃对用户的承诺——如果你无法保证数据的持久写入,就不能欺骗用户说数据你已经存储好了。

而没有程序是没有Bug的,这些最极端的情况,往往是设计实现者自己也最难以枚举的,他们的测试很难涵盖到类似的情况,于是,对于包容性比较好的存储系统设计,在这样的困境下,尽力保持现场地退出服务,让独立的运维程序,甚至是人工来介入,恢复服务状态是一种负责任的态度。对于亚马逊的EBS故障情况,我个人基本是这么理解的。

那么好了,我想,一定有人要问一个问题,既然EBS可能会造成这样的窘境,为什么一定需要这么一个服务呢。

让人又爱又恨的EBS服务

如果你想成为最好的云服务商,请做EBS服务,这是杀手服务;如果你想成为被人唾骂的云服务商,请做EBS服务,这是你的最大故障点。(改自《北京人在纽约》的经典台词)

亚马逊大多数的AMI(操作系统镜像)都放在EBS上,亚马逊很多虚拟机都用到了EBS服务,很多数据库都放在EBS磁盘上……亚马逊的EBS需要额外付费,亚马逊的EBS的性能并不稳定,甚至可以说亚马逊的EBS性能公认的不好……这一系列的事实同样是这么矛盾,一遍又一遍地问:为什么人们要用EBS服务呢?

  • EBS服务是便宜的——是的,单独额外付费的EBS反而可能是更便宜的,使用EBS作为操作系统镜像,这会让虚拟机在不需要工作的时候,可以处于stop状态,这个状态是不计费的;而且,使用EBS作为数据盘,可以在不需要计算的时候,销毁虚拟机实例,而在需要时在申请新的虚拟机,直接使用已有EBS上的数据。(后者盛大云已经提供,前者即将提供)
  • EBS服务是可靠的——即使虚拟机发生故障,服务器的硬盘发生故障或其他问题,EBS作为一种可靠的持久化存储服务,仍然可以保证数据的可靠性。
  • 在上面两个优异特性的基础上,更让人兴奋的是,EBS服务居然真是能用的,而且,你的程序可以直接像用本地磁盘一样用EBS,这简直是上天赐予我们的礼物。
  • 此外,EBS服务有更多的玩法——可以使用RAID,组合多块EBS盘,在一定程度上提高EBS的性能;可以创建快照,可以用快照来恢复成多块EBS盘。(盛大云硬盘的快照功能即将提供)

概括地说,EBS提供了持久化的、具有独立于主机的生命周期的、高可用的块存储设备,在这一设备上可以创建支持POSIX语义的本地文件系统(或是Windows本地文件系统)。这些独一无二的特征,让用户们在口诛笔伐这个服务的同时,也离不开这个服务。

云中的存储服务的差异

实际上,云服务里的存储服务并不少,有对象存储服务(亚马逊的S3和盛大的云存储服务皆在此列),也有块存储服务(亚马逊的EBS和盛大的云硬盘),当然,还有各种关系型、非关系型的云数据库…… 但是,为什么只有EBS服务受到这么大的争议呢。我们知道,数据存储服务可以分为结构化和非结构化,或分为块、对象、文件……但是,抛开数据的形式,不同的存储系统仍然有一类决定性的参数——时延。

Google的Jeff Dean在一次演讲中,引用了这样一组时延数字(节选, 引用链接: https://gist.github.com/2841832):

  • Main memory reference 100 ns
  • Round trip within same datacenter 0.5 ms
  • Disk seek 10 ms
  • Send packet CA->Netherlands->CA 150 ms

这也就是说,使用硬盘的本地程序,期待的是毫秒级的时延,而对于 Web 应用来说,上百毫秒的时延仍然是可以忍受的。

这也就决定了按照毫秒级时延设计的EBS系统的服务对象是运行在虚拟机上的本地应用,其最主要用法就是包括Ext2/¾, XFS, NTFS在内的各种本地文件系统,这些文件系统将数据和元数据存放在存储设备上,并认为存储是不常出错误的,相信存储设备一定会在可以盼望的时间里返回,而不需要考虑设备突然消失之类的事情。

与此相反,设计为面向Web应用的对象存储服务的客户应用,包括浏览器中的静态或动态网页、各种客户端的API请求。所有这些访问都通过HTTP API来执行,调用者期待这些服务在上百毫秒,甚至几秒钟内返回,甚至暂时的无法获取也不会对应用有太大的影响。

既然EBS需要满足毫秒级的时延需求,它的访问方式就必然是在一个数据中心内部的,而且,为保证数据可靠的多副本也必须在一个数据中心内部,否则,数据副本复制的时延和副本故障的切换将很难满足需求。当然,这不是说不可以进行跨数据中心的备份,只是,不可能实现跨数据中心的强一致性副本。

这样,我们可以发现两点:

  • 虚拟机中运行的应用强烈依赖EBS存储自身的可靠性,没有考虑,也很难特别考虑EBS的特殊性;
  • 如果一个数据中心出现大规模断电,比如这次亚马逊的事故,任何EBS服务都是不能保证0服务中断的,因为完美恢复只能依赖这个数据中心中的数据,而存储这些数据的服务器集体断电,需要时间来确保这些数据的正确性。

EBS做了什么

尽管我们知道EBS的脆弱性了,但是,我们得说,这种整个数据中心多路断电,同时切换到油机供电也发生故障的情况是极为罕见的,面对这样或更严重的(比如911)的事故,任何机构的民用级别的数据中心中的计算机也很难幸免,这样的故障可能暴露了亚马逊的某个Bug,但并不是说云服务商就比“前云时代”的主机托管安全性差了。

相反,具备了EBS服务的亚马逊AWS或盛大云服务会给用户更多安全保障,这些保障包括:

  • 不依赖于虚拟化服务器的本地硬盘。硬盘是PC服务器故障的重灾区,而且不论是服务器的电路故障还是硬盘物理故障,都会导致依赖于本地硬盘的服务无法继续;
  • 可以透明处理单机/单块硬盘的故障,在系统内任何一台服务器出现故障时,都不会影响存储服务的正常工作;
  • 良好设计的EBS系统,在更严酷的故障面前,可以进行较好的自我保护,在服务被迫中断时,也尽量避免数据不一致等问题出现;
  • 相对于SAN设备,成本低廉,对于用户来说,成本同样也更低。

基于这些考虑,我为EBS追加的辩护词里写到:虽然在极端故障下,EBS可能成为命门,但在更多情况下,EBS为云服务提供了更好的保障。持久存储仍然是故障面前你最可以依赖的。

如何使用EBS

对于EBS的使用,实际上和本地硬盘区别不大,可以直接使用,甚至做RAID,利用条带化来提高一定的性能。所有这些都非常简单易用。但是,EBS毕竟和本地磁盘还是有一定差异的,尽管应用无法感知,但用户还是需要在使用时有所注意。

首先,EBS的时延略高于本地磁盘。由于加入了网络传输过程,EBS的时延会比本地磁盘访问略高一点,这样,单线程、串行小请求的qps一定会受到比较大的影响,无法充分利用EBS的带宽。因此,在应用选择与架构设置时,如果可以更多地并发进行IO访问,会在IO性能方面有不错的收益。在Windows上观测,用FastCopy复制数据就会比Windows自带的复制程序快,用IOMeter加高outstanding IO值,就会获得很好的性能数据。特别地,对于Linux,利用预读设置

/sbin/blockdev --setra 1024 /dev/xvdb
<span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;">来增大块设备预读大小,可以明显地提升顺序读的性能,对于其他读写操作没有影响。我们也已经对盛大云计算的EBS缺省加入了这个设置参数。</span>

其次,EBS是共享存储带宽的服务,因为在很多应用中,存储本身不像CPU那样,是持续访问的,而是簇发方式地读写,为充分利用带宽,也为了让有需要的主机得到更好的性能,在其他卷不工作时,是允许某些卷占据超出平均值的存储带宽的。这样,在不同的时间,不同虚拟机得到的IO带宽是会有比较大的波动的。用户无法应该期待所有IO访问性能都是一致的。用户需要合理地利用系统缓存或缓存服务,并在必要时对数据进行分区,从而满足应用的需求。

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