当虚拟机遇见Hadoop -- 基于hadoop的开源EBS实现思索 (康华)

      谈起云计算,一些人会滔滔不绝的谈论虚拟机,而另一些人则口若悬河的宣讲hadoop。相互之间嗤之以鼻,都自认为是正宗,谈到对方,颇有"道不同,不相为谋"的味道。—— 有点象数学史上搞几何的和搞代数的相互不服那个时代!:)

      当然相互不服自然有各自的大道理。虚拟机的拥戴者说我们虚拟机可“化整为零”的使用物理机,将物理机分身多个虚拟机,随时按需分配给用户使用,且有亚马逊的EC2的弹性云为证;而hadoop的吹鼓手则绝对相信“化零为整”的使用物理机,将集群机器的能力化身为一个超级计算机才是云的王道,尤其是现在依托于hadoop大数据分析似乎才是云计算的真谛!

       一个是"化整为零",一个是"化零为整,似乎一个去分散资源,一个去聚合资源",好像是完全背向相持两个概念!

       难道虚拟机和hadoop真的是水火不容吗?其实他们也是有那么点共同点的!那就是:资源的动态分配(无非是资源的聚散离合罢了—— 虚拟机是资源的分化,而hadoop是资源的池化),所以它们都可叫云吧(资源无处不,却居无定所,随叫随到就像云)!

       从咬文嚼字的概念上统一他们意义不大(对立统一本来就是世界的普遍规律吗),我们追求的是实践中统一-----  要知道代数、几何后来也是相互融合,最终衍生出了代数几何学。

       那么如何从实践中统一这两种技术呢? 最朴素的想法往往就是最可行的办法——将虚拟机弹性云加载hadoop集群之上! !!

       为此首先也是最重要的是让虚拟机用到的存储,即虚拟磁盘(包括镜像盘和数据盘)采用网络磁盘方式由Hadoop中的hdfs支撑----这也就符合了虚拟存储向网络存储发展的最新趋势。

       但显然直接放到hdfs上是不不行的,因为虚拟存储首先要是块设备存储,而hdfs是面向文件的;另外一个重要限制是,hdfs设计上是不可修改的(只能append,没法pwrite),而虚拟机使用的块设备则要求必须能随机读写。

       鉴于上述两点,我们需要开发一个中间层——变文件存储为块存存储(虚拟磁盘),且在hdfs的追加存储上实现随机读写功能! 如果能做到这两点,无疑hadoop 的hdfs将是一个很理想的选择(后面会分析为什么非常理想的原因)  

       对应第一点,实现虚拟块设备,解决方法不缺——我们大可以用nbd/iscsi/qemu等模式实现;头疼的是第二点在hdfs基础上实现随即读写特性。                  如何办呢? 别放弃!如果研究过文件系统的朋友,一定听说过log structure filesystem吧——这是一个颇有历史,构思大胆的文件系统设计。虽然尚未被广泛使用,但在linux本地系统中其实早有一个叫nilfs2的 log structure filesystem存在 —— log structure filesystem最大设计特点就是仅以追加写方式实现随即读写文件特性,设计初衷带来的主要好处是:追加写有利于磁头的顺序调度,从而保证了高效的写入速度;另外一个好处则是追加写方式天然支持连续快照(continue snapshot)。

       拜提出log structure filesstem 技术的先知们所赐!我们按图索骥,借log structure的思想在hdfs之上实现随即读写块设备--没错是块设备,不是文件系统。相比文件系统块设备访问要求简洁很多(支持给定偏移的读写即可),大可不必

去实现目录结构,和诸多纷繁的文件接口,所以实现块设备要简洁不少,同时也高效的多。具体实现设计和代码请见我们开发的hlfs 系统(http://code.google.com/p/cloudxy/)。

      那么hlfs和hdfs嫁接的网络块设备特性效果到底如何?与业界当下同领域的sheepdog、ceph提供的分布式快设备相比长处和不足有那些呢?

      我们绝非为了融合云计算概念而融合(谁都知道强扭的瓜不甜)。虚拟机在hadoop集群之上运行(hlfs相当粘合剂,使得虚拟磁盘寄宿于hdfs之上)可谓天作之合!下面我们详细分析他们的结合会给虚拟机使用带来那些有点:


可能的优势

计算存储一体化——集群机器的计算资源被用于运新虚拟机,存储资源被用于做虚拟磁盘。这无疑是大势所趋,毋庸多言。

虚拟磁盘存储容量不再受限—— 集群存储被池化,不再受限单机容量,不会再有各机器存储负载不均等问题;要是池不够用了,还能在线扩容、当然也能缩容;另外池化的好处还方便了精简配置(thin provisioning)等要求。

虚拟机自由调度 —— 正是由于前两点,虚拟机一旦摆脱了本地存储限制,那么就可以被自由调度了——那里有计算资源(cpu和内存),那里就可运行vm——无论创建虚拟机、启动虚拟机、还是在线迁移都能自由进行了(传说中的虚拟机动态负载均衡也可再此基础上实现啦)。

高可用性和数据安全—— hdfs多副本冗余容错、机架感知能力都是出了名的好,即便过去被诟病的namenode单点设计,现在也有了很棒的HA方案。

负载均衡 —— hdfs分块打散策略和触发式增量分块搬迁策略,非常适合大集群业务系统。

压缩率 ——   hdfs 支持文件压缩,也支持对偏冷数据ErasureCode等方式的raid。这些技术都极大的提高了数据存储效率。不过我们hlfs本身也实现了基于lzo的块压缩,所以压缩不是问题。

高吞吐 ——  hdfs 有三个重要特性保证了其吞吐高于其他网络存储(尤其是基于DHT技术的存储系统)。第一个特性是就优先写本地一个副本,第二个特性是优先读最近副本。这两个特性相辅相成,使得hdfs在卓尔不群。优先写本地一个副本,会使网络传输流量减少了一份,所以对于集群来说省了1/3网络带宽,而且也使得读时能直接读本地副本,彻底避免了网络带宽。(DHT等存储网则很难做到优先本地的读写,所以网络带宽占用更高,读时也需要夸网络传输数据);第三个特性是pipeline式写入(并非就是串行,连续块传输也是流水线式),pipeline相比很多虚拟同步方式进行的多份副本并发广播写而言要更优,因为其占用出口带宽更少,网卡出口带宽不会成为瓶颈。比如三副本情况下写文件,pipeline方式速度可到100Mb/s(千兆网),而虚拟同步方式只能到33Mb/s,因为三个副本需要三个流需同写出,所以出口带宽成为瓶颈。

实现规模化CLONE功能 —— clone功能最适合用在大规模部署虚拟机场景下:一个母盘clone出数个增量盘,供给不同用户使用。母盘保留只读的共享数据(如操作系统原始安装后的镜像),增量盘给各用户写入自己私有数据。这样以来即便1000个用户虚拟机也能瞬间以增量盘方式被clone生成,既创建速度块,而且也节省存储空间(母盘数据被共享)。但再其他网络磁盘系统上实际运行一下(其实没几个网络存储系统能支持clone),就会发现1000各虚拟机怎么启动这么慢! 原因是母盘要承担1000各虚拟机的数据读访问,必然成为瓶颈。如何解决了? 给更多母盘,每个母盘只服务10个增量盘吗? 其实大可不必大费周折,hdfs 支持以文件粒度的副本设置和动态调整功能对CLONE而言真是久旱逢甘露,他乡遇知己呀! 我们要做的就是根据需要的增量盘数量的不同,动态调整母盘的副本数,从而获得读负载均衡。如果有1000个增量盘,那我建议你母盘副本设置10啦(如果压力还太大,那么再动态增加10个,够了吧,如果还不够继续啦,完全可以按需动态调整。设想一下极限情况吧——假如每个机器都有一个母盘副本,那么就意味只有增量盘的读写请求会经过网络,那将极大减少网络访问,提高虚拟机磁盘IO。其实对于相对固定,且为数不多的系统镜像,如centos,ubuntu,winxp等常用镜像,我们完全可以将母盘寄宿于每个机器之上,以求空间换性能——存储最便宜,性能最重要

不间断的快照(continuously snapshot)-- 不间断快照是的 用户能够方便地恢复被误删除的文件,或者将被误修改的文件恢复到修改之前的内容。这个特性对于虚拟机服务(hosting服务)和系统管理员而言,简直是太舒服了。因为你再不怕网站受攻击,数据被污染;也不怕因为自己误操作而删除数据;而且每日备份的工作也大可不必了。

高效恢复速度 —— 系统崩溃后文件系统的检查和恢复时间往往很长(fsck),从而有了 journaling file system系统来缓解该问题。不过相比log structure系统而言(Journal 文件系统保存在日志中的只有 metadata,而 Log-structure 文件系统则采用日志记录一切改动,包括 metadata 和数据),是小巫见大巫啦。log structure结构的存储系统数据恢复时间可谓瞬间完成,无需等待。

随机写速度占优——log structure 设计保证了随机写被转化为顺序写,从而提升了写性能(无论是sata盘或者是SSD—ssd更突出)。另外关于写入速度要说明一个重要事实。hlfs 建在hdfs之上,为了保证数据安全,我们写操作后调用hflush刷新数据(hdfs的hflush实现也很高效,它甚至没有惊扰namenode),但为了效率考虑,应减少刷新频率,所以我们也设计了回写cache,以求延迟聚合写入(可以想象,  如果cache大小到hdfs块大小,则写入速度就是hdfs的写入速度)。具体使用是可根据数据安全需要设定回写cache(大小和写入周期两个纬度)参数,以求在速度和数据安全中取得平衡。

可支持权限等访问控制:继承于hdfs的权限管理。

易于划分存储池:在hlfs设计考虑的使用场景中hdfs集群并未被独占,我们只需要从中开辟出来部分空间给虚拟磁盘使用即可。在实现中其实就是占用了hdfs中给定目录作为逻辑上的资源池。

并行segment usage 计算 - log structure 结构逃不了旧数数据回收(术语叫做段回收),回收中最重的一步是段使用统计。而hadoop的map reduce正好能并行方式计算段使用率,提升了回收速度。

推广成本低 :hadoop 作为云计算的基石已无可置疑,使用很普遍。无论是资料或是技术人员都相当丰富,所以吗,各方面成本都要低很多。

跨平台:hadoop java 实现所以天生跨平台,而我们hlfs 基于glib跨平台库实现,所以也可跨平台。(但目前代码中还有一点非移植接口,后续逐步替换为可移植接口)


可能的缺点

读响应时间慢?:log strcture 结构 会造成数据分片,在个别场景下读取会被拖慢(数据分片会造成多次磁头跳跃,而且有可能跨机器——未来的SSD设备和万兆网环境该问题将消亡);另外由于存储的分层结构(hlfs 通过hdfs层完成数据读写,而非直接访问磁盘)的原因,数据流转变长,因此理论上读取速度多少会受影响。不过在实际使用场景中问题不大,因为其上的文件系统多有cache 和预读(这两点是读优化的核心,好在我们做了一点工作,但更多的工作交给了其上的文件系统啦),很大程度解决了读速问题。

占用更多存储空间:log structrue 结构相比modify in place 站用更多存储空间。不过今天看来存储价格持续走低,更重要的是集群中存储资源实际使用中往往闲置较多。所以不用白不用,与其闲置不如充分利用已获取性能和其他特性(存储紧张时加速回收就是了)。


HLFS 当前开发状态 (http://code.google.com/p/cloudxy/)

已支持 NBD,ISCSI等块设备

已支持 Xen、Qemu(KVM)

已支持 Libvirt

已和Openstack进行实验性集成(http://code.google.com/p/cloudxy ... HLFS_INTO_OPENSTACK


     留个悬念话题,现在虚拟机和hadoop存储层面统一了,那么计算层面怎么统一呢?

     其实hadoop 2.0 已经贴近通用资源调度器模型了——按照任务需求选择资源宿主去运行,任务以进程方式使用资源(目前的资源主要面向的是内存资源,cpu资源)。

     虚拟机可以和任务进程类比。进程其实和虚拟机一样都属于运行容器(容器就是个资源宿主),只不过虚拟机(无论机器虚拟机xen/kvm/qemu,或者系统虚拟机lxc)相对进程容器更重,隔离性也更强。

      所以当虚拟机存储寄宿于hdfs之后,将虚拟机在hadoop2.0中调度管理也就变的完全可行了。至于具体实现,留给有识之士吧!

      很希望社区或从事虚拟化研发的企业一同探讨有关虚拟机存储相关问题(理不辩不明,灯不拨不亮,欢迎争论)。也可以共同开发感兴趣的产品或特性。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐