存储 频道

中国移动通信:何种网络存储适合弹性云

  【IT168 方案】本文首先就 ”弹性云” 的存储需求进行分析,尝试的归纳出弹性云应用环境对存储的普遍需求;接下来针对这些具体需求,一一检验了当前林林总总、颇为流行的典型网络存储系统(如dynamo,GFS,Hadoop Fs等)的功能特性,分析其得失;再最后抛砖引玉——提出一种自认为比较理想的网络存储架构。

  为了避免空洞的说理。在本文后期,我“试想”在基于XEN虚拟机的弹性云环境中到底如何实施这一理想化的存储系统。

  概念问题(如hosting,弹性云等),不再啰嗦。我们直接切入正题!

  一.用于HOSTING目的的弹性云需要什么样的存储系统呢?

  弹性云环境所托管的虚拟机基本需求大致如下:

  Ø 虚拟机系统故障停机时间尽可能短(甚至号称永不停机!不过一般一年内因不可抗拒的因素,停止10分钟还是能被大度的客户接受的)

  这首先要求虚拟机的运行数据(包括操作系统和用户数据)非本地存储,而是需要存储于后端的可靠的存储系统中。因为虚拟机的宿主机发生故障(比如断电或者硬件永久故障)在所难免,如果故障时虚拟机的磁盘数据本地存储,长时间的故障停机时间就将不可避免的 —— 甚至人品不好时,碰到本地硬盘物理损坏,则要造成虚拟机系统永久不可恢复。

  鉴于上述原因,hosting环境的存储需要放在远端的可靠存储系统,且应该写透到远端存储(切记!不要使用本地cache等,否则故障时要丢失数据的!),这样只要后端存储系统正常则虚拟机便可旋即进行”failover”——再其它可用宿主机上重新启动. 这样一来停机时间可降低到1分钟内。

  Ø 虚拟机系统高用性

  高可用意味着——Hosting的虚拟机需要 ”always online”,那么显而易见对后台存储也应是always online吧!

  对于这点我个人认为倒不尽然!远端存储的可用性可略低于虚拟机的可用性。为什么这么说呢?因为虚拟机的I/O请求其实可可以短暂挂起的 —— I/O挂起时计算型任务还是可以正常运行的,而I/O相关的任务可以临时处于"D"状态 ,默默地等待I/O请求应完成。当后台存储系统恢复后,则可继续正常工作。这种容错性给了后端存储系统设计留下了不少余地。存储系统可以在扩容、failover 、snapshot等非常时期,短暂的停止或者降低服务能力。

  但是毋庸置疑的是 —— 虚拟机的高可用性必然要求一个高可用的后台存储。如果后台存储不稳定、效率低下、故障频繁则必然破坏到虚拟机的正常运行。

  Ø 弹性云资源利用最大化

  1. 资源利用最大化的第一要求是智能调度。为了能将所有宿主机的资源整合成一个资源池,供虚拟机最大限度使用。弹性云系统需要根据虚拟机的资源使用情况,在各个宿主机之间调度虚拟机——这就是传说中的热迁移(live migration)。热迁移实现最重要的就是数据远程存储,同时要保证迁移时虚拟机的所有on disk数据都被刷新到了远端存储中,也就是要求 ”写透”——至少在迁移时刻。

  2. 资源利用最大化的第二要求就是存储高性能(高吞吐,低响应)。因为每个宿主机将启动多个虚拟机,每个虚拟机的一般而言需要保证2-4BM/s的I/O带宽(对多数用户足够啦)。如果后台的存储性能跟不上,则必然成为虚拟机运行数量的瓶颈。

  3. 资源利用最大化的第三要求是存储系统支持足够大的规模,且能自动扩容/缩容——规模足够大才可消峰填谷式的资源调度——这点几乎适用于所有的云集群系统;扩容和缩容是指可按需向集群补充机器,空闲时抽出空余机器。为了保证虚拟机的高可用性,存储系统的扩容和缩绒都必须是在线、不中断服务的情况下完成的。而且进行时尽可能不引起性能访问性能下降。也要能保证数据和并发压力平衡,不引起明显抖动。

  Ø 数据需要保证一致性。

  VM镜像存储的数据一致性行低于并行文件系统(如REDHAT 的 Global File System),但高于最终一致性系统(如AMAZON 的Dynamo KV)的数据一致性要求。它要求的是client - oriented consistent ,既面向VM自己看到的数据“实时”一致(read fellow write, write fellow write 等), 而并行文件系统则要求多个客户端看到一致的数据;最终一致性系统则不能保证时刻满足read fellow write等要求。

  Ø 廉价、低成本

  低成本对于后台存储系统而言,具体要求可体现在两个方面。1 是硬件价格低廉;2是最好资源能复用。

  所谓价格低廉不用说就是和传统存储SAN/NAS等相比要更便宜(SAN这东西我确实不熟悉,但听说那是相当的贵呀!);所谓资源能复用最好的理解是这些硬件除了给虚拟机做后台存储,最好还能在适当的时候用于别用。综合上述两个要求,目前比较流行的存储方案是采用”云存储”思路:使用PC 服务器搭建集群存储系统。这样不但便宜,而且其计算资源等也被复用。总之都用通用机器、sata硬盘、普通网卡搭建廉价的存储系统是最低成本的。当然代价就是需要严密设计的软件系统来保证系统的健壮性—— 数据怕丢,就需要采用多副本冗余存储;机器怕坏,就需要能自动、快速failover . 总之你需要一套坚强的存储软件系统做支持。

  Ø 高速的中小I/O请求处理

  Hosting目的的虚拟机的I/O请求有自己的特点。应用统计出的规律大约是: 1读操作多余写操作(相差往往10倍);2 请求以小块数据为主(多数在50-100个扇区左右)。因此后台存储系统最好能是“读优先”,且对“小块数据优先”。

  读优先问题不谈了(好的定位索引、大的cache 和多副本均衡读等通用技术就差不多了),就说小数据访问性能问题,就够让很多存储系统头疼的。尤其是对于廉价PC服务器组成的存储网,其使用普通千兆网卡——网络包的相应速度可不敢和光纤相比呀。这时小包传送来回的网络延迟时间可不容忽视。因此最好存储系统能提供“异步请求接口”。以便客户端能非堵塞的异步发送请求,这样才不至于让VM的I/O堵塞,响应速度更高;并且如果结合广播方式异步传输请求,则理论传输速度可线性scale到很大(想想P2P软件)。

  当然除了上述要求外,差点忘了基本要求是能随机修改——准确说是以扇区大小为单位变长的随机读写。

  注:1 这里的一般hosting应用,不包括那些爬虫、日志分析等”惹事生非”的肇事者,这些应用应该规劝其使用hadoop等类似的分布文件系统。2 读写比例和I/O请求大小可观察cat /sys/block//stat看到,—— 我说的比例数据来自观察我自己使用机器,你看到的肯定有所差别。

  分析了这么一通,可以概括一下弹性云中Hosting服务需要的后台存储特点了:

  n 后台非本地的网络存储系统

  n 高可用性,几乎always online !

  n 支持足够大的规模,且能在线扩容,负载均衡。

  n 面向client的实时数据一致性

  n 客户端不能缓存数据

  n 廉价,最好使用通用pc服务器(当然对于EMC、华为、IBM本身就做存储、做网络的企业;或者电信、银行这种有钱的主,当然采用可专用存储设备啦!)

  n 高吞吐、低响应。

  n 读优先,支持异步访问,支持以扇区大小为单位变长的随机读写。

  二.检阅当前流行的网络存储系统

  Hadoop DFS

  Hadoop 的集群文件系统HDFS,当初是为了满足爬虫应用而设计的廉价存储集群。主要特点是:可支持廉价的异构机器搭建集群;面向大数据块;只能append修改——对于顺序写入提供高吞吐的性能、有很好的数据安全性性和可用性——数据存多份,且能对客户透明的进行failover(稍有遗憾的是,其master好像是个单点)。而且可支持在线扩容,负载均衡。

  但遗憾的是显然它不能满足“支持异步访问,支持以扇区大小为单位变长的随机读写”,“客户端不能缓存数据”等要求。

  Gblobe file system

  Redhat 的Gfs是一个标准的并行文件系统。它支持本地文件一般的随机读写(按照offset)。且具备不错的性能。

  但它的设计初衷是建立在规模有限的可靠集群上的,也就是说几百台机器的集群,且机器的存储安全是依靠raid等硬件技术保证。因此我们不能说其是个廉价的系统。再就是并行文件系统需要用锁来保证各个客户端所见数据的一致性,而对hosting的一致性来说——只需要保证给定客户端所见数据一致就好——有些杀鸡用了宰牛刀啦,带来了不必要的overload。

  Dynamo

  亚马逊的这个系统我着实喜欢(曾经自己和朋友剽窃其思想开发过那么一个)。它几乎能满足上述所有要求。

  但是只是数据一致性问题上差了那么一点点 —— 它走的是最终一致性路线。当然改造改造,也凑活能用。比如用时间戳进行读时的集中决策,选择最后时间戳的为准。但这个时间戳需要由客户端打上(如果服务器断打的话,则需要集群内部时间同步,这太累啦!),因为我们是面向客户端的一致性就可以啦。不过再VM迁移时,你可要注意,别目标机器时间慢于原机器的时间太大,那样就不成啦(如果是秒级别的,迁移时有意阻塞一下I/O到是可以避免错误)。但总的说来,dynamo的一致性保证用在Hosting 环境下玄了点。

  Memcachedb 也是key value存储系统,但它好像没有做数据多副本冗余要和failover切换。那机器坏了怎么办呀(没用过,只是看了看文档)。

  还有很多存储系统,如Redis,Cassandra,pnfs等,都可在上面几个典型的系统中找到其共性,这里不多说了。 就我个人来看,目前这些开源系统还没有那个完全理想,不过也都有很多不错的特性,理清需求后取博众家之长必能整出来一个理想的hosting存储系统。需求说清楚了,设计其实不是大难事啦(不是说现在是技术过剩的时代吗!哈哈)。

  分析到这里就差不多了,我们就权当现在有这么一种理想的存储系统,那么我们有如何接入到虚拟化环境中啦。下面就讲讲这个。

  三.在XEN环境中如何实施网络存储

  熟悉XEN当前架构的朋友一定知道VM的I/O请求是通过device model (qemu)或者前后端虚拟设备转到domain0处理的。Dom0的处理方式要么将I/O请求存在于本地的镜像文件中(如raw格式、qcow格式、vhd格式镜像)、块设备中(如physical磁盘)、要么存再于远程网络存储中(如nbd、nfs、iscsi等)。

  我们推敲一下,看如何将我们理想的网络存储集成进来呢。

  假设我们使用前后端方式,且采用目前流行的blktap2用户态后端驱动 —— qemu方式也大同小异,这里不在赘述。

  方式 1 —— blktap + tapdisk + 虚拟块设备(DOM0中) + 用户态 I/O请求转发精灵(DOM0中) + 远程存储系统。

  显然这里使用的是”physical 设备”方式挂载了VM磁盘镜像,因此“dom0加载虚拟块 设备”目的是模拟一个假的”physical设备”, 这个虚拟块设备作用仅仅是将写入的I/O请求,截获下来,然后转发(把数据从内核倒腾到用户空间)到dom0上本地运行的“I/O请求转发精灵”,最后再由转发精灵真正实现写到远程存储系统 —— 之所以在用户态使用转发精灵写远程系统是因为还是在用户态开发调试来的方便,况且多数远程系统也只提供用户空间的访问API。

  方式 2 —— blktap + tapdisk (block-device api) + 远程存储系统。

  显然方式1如果不经过内核态这层(这层实在是多余的)转发数据,而是经tapdisk直接将数据从用户空间发送到远程存储系统岂不妙斋。有兴趣的话试验一下qemu-nbd,借鉴其思路在tapdisk里实现一个tapdisk-nbd就成啦。

  无论方式1还是方式2都只能使采用挂在“physical 设备”的方式,如果要使用目前颇为流向的镜像文件——如vhd格式的磁盘镜像—— 方式又该如何做呢? 挂载镜像文件和挂载设备最大不同在于:镜像文件属于文件范畴,因此需要存在于文件系统之上。那么好吧,我们想法子在整个文件系统放上去!

  方式 3 blktap + tapdisk + 虚拟块设备(DOM0中) + filesystem (虚拟块设备中) + disk image + I/O请求转发精灵(DOM0中) + 远程存储系统

  好长呀!但说白了就是在方式1基础上——虚拟块设备上在去创建一个文件系统(ext2呀3呀,随你啦,只要支持dio就可——VHD为了安全使用DIO方式操作文件),然后在其上在创建景象image文件即可。

  方式 4 blktap + tapdisk (posix-like api / libaio-like api ) + 远程存储系统

  不用说拉,方式4就是去掉数据和内核层的通讯,和方式2一样直接从tapdisk用户态直接将请求发送到远程存储系统。不过因为tapdisk操作vhd是调用posix文件系统的访问接口(如open文件,write文件),或者是调用libaio的异步请求(如sumbmit_io等),因此远程存储系统就需要提供posix-like api 或者是libaio-like api。如果一切具备,那么我个人认为这便是最理想的集成方式。(如图中红线所示)

  总结 :

  这次先唠叨这么多把,存储的基本需求算是梳理了一便。其他高级需求,比如存储上的基于内容的去重功能;文件的内拷贝功能(拷贝过程数据不再经过VM客户端,直接走内部存储节点直接的链路)等我现在也还没想清楚怎么搞,等我想清楚了再和大家分享吧。

0
相关文章