存储的能力

概述

参考:

基于不同的 存储的基础设施架构,我们可以实现形形色色的存储能力,每种存储能力,可以存放的数据内容各不相同。

现阶段,可以提供的存储能力分为三种:

  • Block Storage(块存储)
  • File Storage(文件存储)
  • Object Storage(对象存储)

块存储、文件存储、对象存储这三者的本质差别是什么?

它们就是不同的接口。块存储就是最接近存储介质的接口,也就是包装最薄的,或者说没有包装。文件和对象存储都是对块存储的包装。可以简单认为对象存储就是不分层次的文件存储。或者把文件看作对象存储的进一步包装。

Block Storage(块存储)

参考:

说白了就是硬盘

File Storage(文件存储)

说白了就是 Filesystem(文件系统)

Object Based Storage(对象存储)

参考:

说白了就是任何东西,对象可以是任何东西。

Object Based Storage(基于对象的存储,简称 OBS) 是一种为计算机存储数据的能力。通常由分布式存储架构来实现。

与 File Storage 类似,只不过没有目录的层级结构,对象的获取,基于 RESTful 风格的 API 接口。

但是与文件存储不同,对象存储中的数据不支持在存储设备上直接修改,必须要先 GET 到要修改的对象,在本地修改完成后,再 PUT 或 POST 回去。所以,并不适合需要频繁读写的数据(例如关系型数据库的数据)。

而平时我们看到那些所谓的能在线修改的,其实是有一个客户端,我们在客户端操作,操作的时候,客户端是帮我们把对象 GET 出来的。

简单理解

1. 块存储

“虚拟座谈会”中王旭提到:块存储是给虚拟机用的。

这句话深刻地表达了什么是块存储。。不知道有没有被大家忽略过去。

对块存储最简单的理解方法就是:看产品。

例子:

  • Amazon 的 EC2 中就有块存储,叫做 EBS (Elastic Block Storage)。

什么鬼?

其实就是虚拟机挂载的一块虚拟磁盘。。。

推而广之,你会发现,自己平时用的 VMware、VirtualBox 都可以创建虚拟磁盘。能够造出这个东西,且构造的东西能被当作磁盘去用的,就叫做块存储。

再来一个例子:

  • RedHat 的 Ceph 中块存储产品的命令行接口是: create image, list image, delete image
  • 阿里云、腾讯云同样有类似 EBS 的功能

所以楼上的各位中 chen yue, 大华云存储对块存储的理解都是对的。

2. 对象存储和文件存储

之所以将这两个放在一起说,是因为这两个和楼上杨志丰的解读类似,主要是 API 不同。。。

对象存储:

  • 大多数对象存储的实现本质上是键值对存储系统
  • 采用扁平化的管理方式(根据键,找到值)
  • 值可以是任何东西,可以是小文件(小二进制片段),可以是大文件
  • 对象存储一般不支持追加写和更新,面向的是一次写入,多次读取的需求场景。
  • 多采用 RESTFul API

文件存储

  • 文件存储不考虑底层到底怎么实现的(很多其实就是对象存储上套一层目录管理层)
  • 采用目录结构管理数据
  • 一般要尽可能兼容 POSIX 文件系统 API

对于产品,仍然可以看 AWS 的相关内容。在对象存储方面,阿里云和腾讯云就有点扰乱概念了,里面频繁出现“管理海量文件”。。。那你到底是对象存储还是文件存储(虽然前面说了文件存储可以基于对象存储来做)

另外还可以看 Ceph,这孩子将自己的产品封装成了块存储、对象存储、文件存储三种。

知乎回答

回答一

这三者的本质差别是使用数据的“用户”不同:块存储的用户是可以读写块设备的软件系统,例如传统的文件系统、数据库;文件存储的用户是自然人;对象存储的用户则是其它计算机软件。

首先要说明一下的是,这三个概念都是分布式存储中的概念,由不同的网络存储协议实现。不过“网络”和“存储”的结合本身会对解释这三个概念的本质差异带来不便,下面的解释中我会先解释存储本身,之后再结合网络来说明。

块存储

传统的文件系统,是直接访问存储数据的硬件介质的。介质不关心也无法去关心这些数据的组织方式以及结构,因此用的是最简单粗暴的组织方式:所有数据按照固定的大小分块,每一块赋予一个用于寻址的编号。以大家比较熟悉的机械硬盘为例,一块就是一个扇区,老式硬盘是 512 字节大小,新硬盘是 4K 字节大小。老式硬盘用柱面-磁头-扇区号(CHS,Cylinder-Head-Sector)组成的编号进行寻址,现代硬盘用一个逻辑块编号寻址(LBA,Logical Block Addressing)。所以,硬盘往往又叫块设备(Block Device),当然,除了硬盘还有其它块设备,例如不同规格的软盘,各种规格的光盘,磁带等。

至于哪些块组成一个文件,哪些块记录的是目录/子目录信息,这是文件系统的事情。不同的文件系统有不同的组织结构,这个就不展开了。为了方便管理,硬盘这样的块设备通常可以划分为多个逻辑块设备,也就是我们熟悉的硬盘分区(Partition)。反过来,单个介质的容量、性能有限,可以通过某些技术手段把多个物理块设备组合成一个逻辑块设备,例如各种级别的 RAID,JBOD,某些操作系统的卷管理系统(Volume Manager)如 Windows 的动态磁盘、Linux 的 LVM 等。

补充一下的是,块设备的使用对象除了传统的文件系统以及一些专用的管理工具软件如备份软件、分区软件外,还有一些支持直接读写块设备的软件如数据库等,但一般用户很少这样使用。

在网络存储中,服务器把本地的一个逻辑块设备——底层可能是一个物理块设备的一部分,也可能是多个物理块设备的组合,又或者多个物理块设备的组合中的一部分,甚至是一个本地文件系统上的一个文件——通过某种协议模拟成一个块设备,远程的客户端(可以是一台物理主机,也可以是虚拟机,某个回答所说的块设备是给虚拟机用是错误的)使用相同的协议把这个逻辑块设备作为一个本地存储介质来使用,划分分区,格式化自己的文件系统等等。这就是块存储,比较常见的块存储协议是 iSCSI。

文件存储

文件存储的用户是自然人,最容易理解。计算机中所有的数据都是 0 和 1,存储在硬件介质上的一连串的 01 组合对我们来说完全无法去分辨以及管理。因此我们用“文件”这个概念对这些数据进行组织,所有用于同一用途的数据,按照不同应用程序要求的结构方式组成不同类型的文件(通常用不同的后缀来指代不同的类型),然后我们给每一个文件起一个方便理解记忆的名字。而当文件很多的时候,我们按照某种划分方式给这些文件分组,每一组文件放在同一个目录(或者叫文件夹)里面,当然我们也需要给这些目录起一个容易理解和记忆的名字。而且目录下面除了文件还可以有下一级目录(称之为子目录或者子文件夹),所有的文件、目录形成一个树状结构。我们最常用的 Windows 系统中,打开资源管理器就可以看到以这种方式组织起来的无数个文件和目录。在 Linux 可以用 tree 命令列出以某个文件夹为根节点列出一棵树:

为了方便查找,从根节点开始逐级目录往下,一直到文件本身,把这些目录、子目录、文件的名字用特殊的字符(例如 Windows/DOS 用“\”,类 Unix 系统用“/”)拼接起来,这样的一串字符称之为路径,例如 Linux 中的“/etc/systemd/system.conf”或者 Windows 中的“C:\Windows\System32\taskmgr.exe”。人类用路径作为唯一标识来访问具体的文件。而由作为自然人的程序员所编写的各种软件程序,绝大部分也使用这种方式来访问文件。

把存储介质上的数据组织成目录-子目录-文件这种形式的数据结构,用于从这个结构中寻找、添加、修改、删除文件的程序,以及用于维护这个结构的程序,组成的系统有一个专用的名字:文件系统(File System)。文件系统有很多,常见的有 Windows 的 FAT/FAT32/NTFS,Linux 的 EXT2/EXT3/EXT4/XFS/BtrFS 等。而在网络存储中,底层数据并非存储在本地的存储介质,而是另外一台服务器上,不同的客户端都可以用类似文件系统的方式访问这台服务器上的文件,这样的系统叫网络文件系统(Network File System),常见的网络文件系统有 Windows 网络的 CIFS(也叫 SMB)、类 Unix 系统网络的 NFS 等。而文件存储除了网络文件系统外,FTP、HTTP 其实也算是文件存储的某种特殊实现,都是可以通过某个 url 来访问一个文件。

对象存储

对象存储其实介于块存储和文件存储之间。文件存储的树状结构以及路径访问方式虽然方便人类理解、记忆和访问,但计算机需要把路径进行分解,然后逐级向下查找,最后才能查找到需要的文件,对于应用程序来说既没必要,也很浪费性能。

而块存储是排它的,服务器上的某个逻辑块被一台客户端挂载后,其它客户端就无法访问上面的数据了。而且挂载了块存储的客户端上的一个程序要访问里面的数据,不算类似数据库直接访问裸设备这种方式外,通常也需要对其进行分区、安装文件系统后才能使用。除了在网络上传输的数据包效率更高以外,并不比使用文件存储好多少,客户端的文件系统依然需要对路径分解,然后逐级查找才能定位到某一个具体的文件。

是否可以用不排它但又类似块设备访问的方式呢?理论上是可以的,但对块设备的访问方式虽然比文件存储快,其实也很麻烦——一个文件往往是由多个块组成,并且很可能是不连续的。例如要读取一个文件,可能需要发出这样的指令:

  • 读取从编号 A₁ 开始的 N₁ 个块;
  • 读取从编号 A₂ 开始的 N₂ 个块;
  • 读取从编号 A₃ 开始的 N₃ 个块;
  • …………
  • 读取从编号 Ai 开始的 Ni 个块。

最后自行把这 i 个连续的块自行拼接成一个文件,这才完成了一个文件的读取操作。为了发出这些指令,访问文件的软件系统需要记录下这个文件分成多少个部分,每个部分的起始块编号是多少,有多少块,顺序如何。不单是读取操作,删除、写入、修改操作也是如此,非常麻烦复杂。而且往往一个文件可能需要被多个系统访问使用,这就更麻烦了。

为了解决这中麻烦,使用一个统一的底层存储系统,管理这些文件和底层介质的组织结构,然后给每个文件一个唯一的标识,其它系统需要访问某个文件,直接提供文件的标识就可以了。存储系统可以用更高效的数据组织方式来管理这些标识以及其对应的存储介质上的块。

当然,对于不同的软件系统来说,一次访问需要获取的不一定是单个我们传统意义上的文件,根据不同的需要可能只是一个/组值,某个文件的一部分,也可能是多个文件的组合,甚至是某个块设备,统称为对象。这就是对象存储。

回答二

这三种存储,分别对应了不同的访问协议,这也就决定了他们的本质差别。

先说一下文件存储,主要操作对象是文件和文件夹。以 NFS 为例,文件相关的接口包括:LOOKUP/ACCESS/READ/WRITE/CREATE/REMOVE/RENAME 等等,文件夹相关的接口包括:MKDIR/RMDIR/READDIR 等等。同时也会有 FSSTAT/FSINFO 等接口用于提供文件系统级别的信息。POSIX,SAMBA 等也是文件存储协议。协议更注重接口的灵活,以及访问权限控制。

块存储,主要操作对象是磁盘。以 SCSI 为例,主要接口有 Read/Write/Read Capacity/Inquiry 等等。FC,iSCSI,也是块存储协议。和文件存储相比,没有文件和目录树的概念,一般协议也不会定义磁盘的创建和删除操作。协议更注重传输控制。

对象存储,主要操作对象是对象(Object)。以 S3 为例,主要接口有 PUT/GET/DELETE 等。和文件和对象存储相比,没有随机读写的接口。和文件存储相比,没有目录树的概念。协议更注重简洁。

回答三

看了目前赞最多的“繁星亮”君的回答,感觉解释的还是不甚清楚。

大家可以看看这个解释,简单明了:

虚拟座谈会:有关分布式存储的三个基本问题

引用下“豪迈”的观点:

分布式存储的应用场景相对于其存储接口,现在流行分为三种:

  1. 对象存储: 也就是通常意义的键值存储,其接口就是简单的 GET、PUT、DEL 和其他扩展,如七牛、又拍、Swift、S3
  2. 块存储: 这种接口通常以 QEMU Driver 或者 Kernel Module 的方式存在,这种接口需要实现 Linux 的 Block Device 的接口或者 QEMU 提供的 Block Driver 接口,如 Sheepdog,AWS 的 EBS,青云的云硬盘和阿里云的盘古系统,还有 Ceph 的 RBD(RBD 是 Ceph 面向块存储的接口)
  3. 文件存储: 通常意义是支持 POSIX 接口,它跟传统的文件系统如 Ext4 是一个类型的,但区别在于分布式存储提供了并行化的能力,如 Ceph 的 CephFS(CephFS 是 Ceph 面向文件存储的接口),但是有时候又会把 GFS,HDFS 这种非 POSIX 接口的类文件存储接口归入此类。

最后修改 March 25, 2025: clearup (feb59d93)