作为云计算的核心服务之一,存储服务是每个用户都会用到的。不过当前的现状是:大部分客户除了虚拟机的数据盘(持久盘)之外,并没有充分的利用存储服务。我们来看一个典型的应用场景:例如某Web应用系统需要用户上传发票扫描件(图像文件)。在代码实现层面,通常会将用户上传的图像文件直接保存到磁盘文件系统里面。在传统的物理服务器部署环境中,这是具备最高性价比的实现方式,而且也不妨碍实现高可用——多个物理服务器可以共享一个存储设备(SAN/NAS)。但是在公有云环境中,这种设计却不再适用,因为公有云通常没有供类似SAN/NAS的共享存储设备。当然Azure和AWS分别发布了File Service和EFS服务,但是:
- Azure的File Service是基于SMB 3.0协议的,而且并未实现协议中所有的功能。同时,在Linux环境中,对SMB协议的支持并不完善;
- AWS的EFS是基于NFS v4协议的,无论是Windows环境还是Linux环境都可以支持的很好,可惜的是,EFS目前依然是AWS国际版的一个处于Preview阶段的服务,AWS中国版自然也没有EFS可以用。
为了在不修改代码的情况下实现所谓的“平滑迁移”,因此出现了一个非常不靠谱的“腻子”方案:开一个虚拟机运行NFS服务为其他实例(虚拟机)提供共享存储服务。很明显,这个运行NFS服务的虚拟机是个单点——如果这个虚拟机挂了,其他依赖共享存储的实例和应用也全部完蛋!既然这样,那我们就给运行NFS的虚拟机也做个高可用吧,这样不就高枕无忧了嘛。且慢,用至少2个虚拟机提供共享存储服务,去掉部署和维护成本不说,2个虚拟机的成本是明摆着的!所以经常有客户抱怨说把应用迁移到公有云上还不如运行在自己的数据中心划算。
面对这种情况,最理想的解决方案是:使用公有云的存储服务替代共享存储设备,即:把用户上传的文件写入/保存到存储服务中,而不是磁盘文件系统里面,以此摆脱对共享存储设备的依赖,降低成本,提升应用系统整体的可用性和可扩展性!
别骗我,这个方案要修改代码的!没错,代码肯定是要修改的,不过:
- 几乎所有的基于公有云的存储服务都提供了面向各种主流语言的SDK。
- 除了SDK,还有RESTful API,只要所使用的语言具备访问HTTP(HTTPS)服务的能力,就可以轻松访问存储服务。
- 使用存储服务的SDK/API替换磁盘文件系统读写,根据个人经验,需要修改的代码量通常不会超过100行。
- 主流的存储服务通常都会将读文件操作映射成HTTP GET方法(例如:每个文件都会对应一个唯一的URL地址),这在一定程度上降低了读取文件的复杂度,例如:在Web页面的image元素上可以直接引用存储服务中权限为public的图像文件,这就省去了从磁盘文件系统里面读取图像文件和通过HTTP服务发布图像文件的过程。
- 与虚拟机磁盘相比,存储服务的成本是很低的。而且其稳定性,可靠性也远高于在虚拟机的磁盘中存储文件。
上述理由看起来是完全合理的,还是还有一个问题,因为使用了特定的公有云存储服务,那么会不会导致被某个公有云提供商“绑架”呢?其实这个问题完全不需要担心的:
- 虽然业界对于公有云的存储服务并没有定义统一的标准和规范,但是在功能、SDK/API方面都或多或少的参照了AWS S3。基本可以认为AWS S3的API已经成为事实上的业界标准。
- 从代码设计角度来看,无论是磁盘文件系统还是公有云存储服务,都是一个持久保存文件的位置而已。就像同一个应用程序可以支持多种数据库一样,运用简单的工厂模式和外观模式,可以轻松实现对多种文件存储机制的支持。
这里推荐一个开源的项目:s3proxy,项目地址:https://github.com/andrewgaul/s3proxy
这个项目的亮点在于,能够让开发者使用S3 API访问其他的云存储服务!目前这个项目已经支持Azure Blob,Google Cloud Storage和OpenStack Swift等主流的云存储服务。在微软Build 2016大会上,还有一个通过s3proxy访问Azure Blob的现场演示。不过目前这个项目的问题是默认不支持AWS中国版和Azure中国版。由于s3proxy底层依赖Apache jclouds,因此要增加对AWS中国版和Azure中国版的支持,就需要对jclouds进行修改(其修改的细节部分不在本文中进行一一描述)。
s3proxy的本质是在本地提供了一个基于jetty的web服务,通过本地的web服务将aws s3的api调用请求转发到其他对应的云存储服务上(或者说是将aws s3 api调用翻译成其他云存储服务的api调用)。甚至可以通过aws s3的api来访问本地文件。因此,s3proxy在使用时需要定义一个本地的临时文件夹来作为文件中转。
由此看来,进行一次代价很小的代码修改,就能充分利用到公有云的特性,这样做还是非常值得的。当然也有一种情况是很令人郁(wu)闷(jie)的:由于现有应用系统的开发团队解散了,或者现有应用系统的供应商倒闭/跑了/不提供维护了,导致无法对代码进行修改!这种情况我还真遇到过,而且并不在少数!