早些时候的企业级架构普遍采用网络文件系统,这其中最为著名的就是Sum的NFS了。微软也有类似的网络文件系统,也就是SMB。网络文件系统的原理很简单,其目的就是将存储系统上的文件系统映射到计算节点(比如Web服务器)。这样可以实现存储资源的共享,提高存储资源的利用率。具体映射方式如下所示。
但是文件系统有个天然的缺点。由于文件系统空间组织的特点,导致对文件访问的时候需要比较多次的磁盘访问。
以Ext4文件系统为例,文件系统将磁盘空间分为两个主要的区域,一个是元数据区,用于存储文件inode等信息;另外一个是数据区,用于存储文件的数据,也就是用户数据,具体如下图所示。
这样,当我们访问一个文件的时候,首先需要找到文件对应的inode,然后根据inode信息找到数据的位置,并读取数据。这个过程可能要涉及到2-3次的磁盘访问。对于互联网应用来说,多次磁盘访问会显著降低性能,影响用户的体验。
当然,除此之外还有其它一些问题,比如横向扩展能力等。其实本质上来说,文件系统的目的是一个通用的存储形态,其目的是为了适用大多数的应用场景(比如文件锁,扩展属性,ACL等等)。而网络文件系统为了保证与文件系统语义的一致性,也需要实现这些特性,这就导致网络文件系统比较臃肿。
对象存储解决的问题
由于上述缺点,传统的网络文件系统是完全无法满足互联网领域应用的。我们举一个例子,以FaceBook为例,其每秒钟都有几十万次的照片检索请求。其存储的照片总量每天新增3.5亿张,对应的存储增量大概在300TB左右。如果对应物理设备,每天大概需要新增上百块硬盘。
这种问题在任何互联网公司都会遇到的问题。比如国内的头条,淘宝或者京东等等,在它们的平台上每天也要产生海量的图片访问。传统存储很难满足其性能和扩展性的要求。
虽然互联网应用对性能和容量的要求极高,但是对其它特性却没什么特别的要求。甚至可以说它对其它特性基本上没有太多要求。由于其存储的主要是图片,而且对图片的存储是一次存储,多次访问,没有修改。
为了解决上述问题,对象存储应运而生。可以看出对象存储解决的问题很集中,如何保证横向扩展能力、降低访问延时。而不需要实现文件系统的其它额外特性(后面我们会介绍对象存储还有一些高级特性)。下面是维基百科对对象存储的定义。
Object storage (also known as object-based storage) is a computer data storage architecture that manages data as objects
从定义可以看出,对象存储在数据处理层面的特点是将待处理的数据看做一个整体,这也就是为什么把它称为对象,而不是文件了。
其实对象存储也并非全部如此简单,很多对象存储也实现了比较复杂的功能特性。比如S3对象存储可以支持大数据处理、扩展属性和二次处理(比如照片的转换,水印等)等特性。
对象存储的常见架构
为了让大家对对象存储有更加深刻的理解,我们介绍一下常见对象存储的架构。虽然亚马逊的S3非常出名,但是并没有公开太多技术信息,其架构也无从了解。今天本文将介绍一下比较流行的其它对象存储的架构。
Swift对象存储
首先介绍一下开源对象存储Swift的架构。Swift是OpenStack的一个子项目,是非常流行的开源对象存储软件。Swift在OpenStack中主要用作虚拟机镜像,其特点也是存储大对象。对于小对象则想多弱势。
Swift最主要的是实现横向扩展能力,其前端有一个Proxy组件,该组件实现了数据的分发服务。该组件可以具备多个实例,每个实例可以安装在一台物理服务器。由于Proxy可以横向扩展,因此不会成为性能瓶颈。
在Proxy中最核心的算法是进行数据放置的一致性哈希算法。该算法实现了将一个对象映射到物理设备的过程。为了保证整个系统的可靠性和可用性,Swift将设备划分为若干等级,比如Zone,Host和Disk。通过不同设备的分发,实现故障域的隔离。
如上图哈希算法,首先将物理设备映射到哈希环上;当有对象访问的时候根据对象名称计算出哈希值,然后将对象映射到具体的物理设备上。
Haystack对象存储
Facebook这对其照片应用开发了Haystack对象存储。Haystack与前面Switf的差异是其存储的是小对象。因为图片通常在10MB以下,大部分在KB级别。因此Haystack除了保证系统的横向扩展能力外,其最主要的是实现对小文件的处理。
前面我们说过,对于小文件的性能问题,普通文件系统的问题在于多次读盘操作。而Haystack正式解决了该问题。
Haystack的做法非常简单,它将多个小文件作为一个大文件的局部数据,这个局部数据称为needle。同时Haystack构建了一个描述needle在大文件中位置的索引文件。由于索引文件比较小,因此可以一次性的加载到内存当中。
通过这种方式,当客户端需要访问数据的时候,在存储节点可以直接从内存中得到数据的位置,并一次从磁盘上读取数据。这样访问存储的性能得到大幅的提升。
由于篇幅有限,本文先介绍到这里,关于存储技术的更多细节,还请关注本号。本号后续还会步步深入,介绍关于存储技术的诸多细节。