本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。
引言
这三个名词我相信了解过存储相关知识的朋友都不陌生,作为主要的三种数据存储方式,我想我们需要对它们之间的优劣势以及适用场景进行一些有效的思考。
犹记得以前讨论过结构化数据,非结构化数据,半结构化数据的区别[3],那么我们这篇文章讨论的块存储、文件存储、对象存储和前者的联系到底是什么呢?
区别
在[5]中给出了以下几种回答:
- 使用数据的“用户”不同。对象存储的用户则是其它计算机软件;文件存储的用户是人;块存储的用户是可以读写块设备的软件系统。
- 对应的访问协议不同。对象存储是GET/PUT;文件存储为LOOKUP/ACCESS/READ/WRITE/CREATE/REMOVE/RENAME;块存储为 Read/Write/Read Capacity/Inquiry。
- 操作的对象不同。对象存储是对象,一般的形式就是KV;文件存储为文件或者文件夹;块存储为块设备,这里因为一个设备的各种资源又上限,所以可以把多个物理块设备组合成一个逻辑块设备。
- 块存储读写快,不利于共享(不同机器对于块设备的访问必须遵循同一协议,这也意味着不同文件系统间的数据是共享不了的,比如磁盘的组织格式是FAT32,但是机器的文件系统是EXT4,那当然没办法共享数据了),文件存储读写慢(多级的路径解析,磁盘中的索引解析,主要是因为元数据和数据本身存储在一起),利于共享。对象存储读写快,利于共享,不过最重要的是更好的满足特定非结构化数据的存储要求的,这也许就是nosql火星燎原的原因吧。
关系
其实这三者的关系并没有想象的那么不密切。一般的分布式键值存储底层的存储都是自己实现的存储引擎和一致性协议,要么跑一个一致性协议,要么CRAQ,当然无主架构就需要矢量时钟来进行保证一致性了,比如Dynamo。类似于Bigtable这样的nosql(表格化数据)底层的存储则是基于GFS这种文件存储架构的。
再比如说redis,底层的持久化使用RDB和AOF,而这些都是文件,这不也是对象存储基于文件存储的一个简单例子吗。
当然也很好想象,一切的一切最终总需要存盘的,所以个人认为所谓的块存储、文件存储、对象存储虽然看起来关系不大,但是其实是关系密切的。它们的本质就是一个分布式存储架构通过不同的访问协议向外界提供的不同接口罢了,所以一个分布式系统同时提供这三种存储模式也没什么奇怪的了,毕竟只是加一个协议罢了。
[5]中逸凌的留言很有意思,这里引用一下:
块存储给你就是一块未格式化的硬盘分区。文件存储就是给你一个格式化过的硬盘分区(可能是本地也可以是网络上的)。 对象存储给你的是一个存非结构化数据键值数据库。
芦中人的回答也很有意思:
块存储这个是基础的,操作系统的课程里都有,所谓block, 就是事实上事实上是磁盘读写时,不是一个byte一个一个byte读的,而是一个sector一个sector读的,抽象到操作系统这层,其实对应于block是为了体现sector,有时候操作系统一个sector 太离散,就把邻近的几个sector 拼一个block,在转一圈时一把读到内存或者刷回去,如果一个block 是4k,8k,它可能包含了几个连续的磁盘上的sector, 这个就是逻辑块,到了flash, 因为一把物理擦除是一个更大单位,所以逻辑block 可能比物理擦护块小,无论如何,块是一个定长的,有固定地址或者位置的存储单位,它在操作系统里衍生于块设备按照sector操作的事实,在现代存储栈如此复杂,各种虚拟化背景下,块的语意就是定长和地址。不管说api模拟层面还是往硬件这边追溯。文件的概念,我觉得是个功能单位,比如你能把一堆数据,通过一定方式打开它处理它,它就抽象了我们生活中一个有意义的数据集合和如何处理它,谁有权限等等这些元信息,更加接近实现一点,文件和文件目录按照树组织起来,每个树的节点一个inode,表示一个目录或者一个文件,所以简单一点纯粹文件语义就是一个有意义的数据集合和处理它的元信息放在一起,因为传统文件系统的实现都是树的,所以文件在实现上语义包括了命名空间的层次性,它的命名空间是从根到这个节点整个路径。对象存储本质上从接口上,相对于文件系统,就是命名空间摊平了,你讨论ceph里一个对象,不管网关过来,还是底层, 都是一个id就能找到一个对象,命名空间是平的,其实更确切的对象存储在实现上说是相对于文件,一个名字空间,一个id找到一份数据,元信息和数据分离,大的对象设备或者分布式软件有一个专门的元信息或者叫控制信息的服务器。具体去看ceph 设计文档和emc的公开文档。
至于为什么现在分布式对象存储如此火爆,大概是因为因为块存储是给计算机用的,对象存储是其他组件用的。独立服务所提供的存储系统,访问都来自网络,自然是做对象存储。
与结构化数据,非结构化数据,半结构化数据的区别
这篇文章讨论的块存储、文件存储、对象存储在[4]中看来其实都可以存储非结构化数据;对象存储还可以存储半结构化数据;而结构化数据只能交给关系型数据库的存储引擎来搞定了。
如何选择
[8]中大神描述的非常透彻,这三种存储类型在非分布式场景下可以抽象为硬盘,文件系统和KV数据库,所以单机下业务需求需要用哪一个,分布式场景下也就这样用。
在实现上来讲的话分布式存储可以大体分为两个部分,就分布式系统的架构和单机存储引擎。分布式架构现在仍是一个看上去比较活跃的领域,GFS,Ceph,Bigtable,spanner,redis cluster,memcache都是不错的架构方案。
而单机存储引擎也很有意思了,我们可以使用文件系统接口,也可以直接使用块设备接口,甚至于直接基于键值接口。当然这些接口服务均可以采用其他分布式组件来提供。
如此看来,一个优秀的架构是非常重要的,分布式下块存储、文件存储、对象存储的性能直接与架构挂钩,因为这三种接口我们都可以通过封装一层协议来提供服务。
总结
依以上讨论看来,分布式存储系统其实就是在传统的单机接口(存储也可以基于其他分布式系统)上进行一层包装,提供在一定的一致性,可靠性,可扩展性下的不同接口类型的服务(块存储、文件存储、对象存储)。
笔者水平有限,文中表达的观点不一定是正确的,请读者自行分辨优劣。
参考: