2、存储类型对比:对象存储、文件存储、块存储的区别与适用场景

聊到云存储选型,我经常被问到的一个问题是:「这三种存储到底怎么选?」

说实话,这个问题没有标准答案。但如果你搞懂了它们各自的脾气秉性,选型就变成了一件顺理成章的事。

今天我就结合自己踩过的坑,把对象存储、文件存储、块存储这三兄弟掰开揉碎了讲清楚。

2.1 先看一张对比表,心里有个底

维度 对象存储 文件存储 块存储
访问方式 HTTP/HTTPS (RESTful API) NFS / CIFS / SMB iSCSI / FC / NVMe-oF
数据组织 Bucket + Object + Key 目录树 + 文件 LUN / 卷 + 块
协议 S3 / Swift / OSS NFS v3/v4 / SMB 2/3 SCSI / NVMe
典型延迟 几十毫秒级 几毫秒级 微秒级
扩展性 无限扩展(EB级) 有限扩展(PB级) 有限扩展(受限于SAN)
适用场景 备份归档、静态网站、大数据 共享目录、日志、代码仓库 数据库、虚拟机磁盘、高性能计算

一句话总结:对象存储管「存不存得下」,文件存储管「好不好找」,块存储管「快不快」。

2.2 对象存储:海量数据的归宿

对象存储,说白了就是把数据当成一个「黑盒子」来存。你不需要关心它存在哪个硬盘上,也不需要关心目录结构。

每个对象都有一个唯一的Key,通过HTTP API就能读写。我最早接触对象存储是在2015年做图片社交App的时候,那时候每天几千万张图片上传,传统NAS根本扛不住。

我的经验:对象存储最适合「写一次、读多次、很少修改」的数据。比如用户头像、视频文件、日志归档。我曾经帮一家视频网站做过冷热数据分层,把90天前的视频全部迁移到对象存储,成本直接降了70%。

核心特点:

  • 扁平命名空间:没有目录树,只有Bucket和Object。你想想看,几十亿个文件如果用目录树管理,光遍历一次就要命了。
  • 强一致性 vs 最终一致性:大部分对象存储是最终一致性的。嗯,这里要注意——如果你需要「写完立刻读到」,比如交易流水,那对象存储可能不太合适。
  • 元数据丰富:每个对象可以附带自定义元数据,比如图片的拍摄时间、GPS坐标。这个特性在做数据湖时特别好用。
# 用AWS S3 SDK上传一个文件,就这么简单
import boto3

s3 = boto3.client('s3')
s3.upload_file(
    'local_image.jpg', 
    'my-bucket', 
    'images/2024/01/01/local_image.jpg',
    ExtraArgs={'Metadata': {'author': 'zhangsan', 'date': '2024-01-01'}}
)

避坑指南:我曾经遇到过一个问题——对象存储的List操作在大规模数据下非常慢。如果你有上亿个对象,别指望用List API来遍历,那会等到你怀疑人生。正确的做法是用事件通知或数据库记录索引。

2.3 文件存储:最熟悉的陌生人

文件存储,其实就是我们每天都在用的「文件夹+文件」模式。Windows的共享文件夹、Linux的NFS挂载,都属于这一类。

为什么说它「熟悉又陌生」?因为大家都会用,但很少有人深究它的性能瓶颈。

核心特点:

  • 层次化目录:从根目录到子目录,一层层往下找。这种结构对人类友好,但对机器不友好——深度嵌套的目录会严重影响性能。
  • 文件锁:支持多客户端并发读写时的文件锁机制。我记得有一次做HPC集群,就是因为NFS的锁机制没配置好,导致多个计算节点同时写同一个日志文件,数据全乱了。
  • POSIX兼容:大部分文件存储兼容POSIX接口,这意味着你现有的Linux应用几乎不需要修改就能用。

适用场景:文件存储最适合「需要共享访问、目录结构清晰、中等规模」的场景。比如公司内部的共享文档、代码仓库、日志收集。

性能瓶颈在哪里?

文件存储的瓶颈通常出在元数据服务器上。你想想看,每次打开一个文件,都要先查目录、再查权限、再查文件属性。如果文件数量超过几千万,元数据服务器就会成为瓶颈。

# 查看NFS挂载点的性能指标
# 重点关注:ops/s 和 latency
nfsstat -s | grep -E "ops|latency"

# 如果发现延迟飙升,先检查网络
# 我曾经遇到过交换机MTU配置不一致导致NFS性能下降50%的案例

我的建议:如果你用文件存储,尽量控制单个目录下的文件数量,不要超过1万个。超过这个数,ls命令都会变慢。我曾经帮一个客户优化过,他们一个目录下放了50万个日志文件,ls都要等30秒。

2.4 块存储:性能怪兽

块存储,是三种存储里性能最强的,也是配置最复杂的。

它不关心你存的是什么文件,它只关心「块」的读写。每个块大小固定(通常是512字节或4KB),通过SCSI协议或NVMe协议访问。

核心特点:

  • 低延迟:微秒级的延迟,比文件存储快一个数量级。为什么?因为块存储跳过了文件系统层,直接操作裸设备。
  • 高IOPS:一块NVMe SSD可以轻松达到百万级IOPS。我做过一个数据库优化项目,把存储从NFS换成块存储后,数据库查询延迟从5ms降到了0.3ms。
  • 快照与克隆:块存储支持秒级快照和克隆,这在虚拟化环境中特别有用。比如你要给100台虚拟机同时部署环境,用块存储的克隆功能,几分钟就能搞定。

避坑指南:我曾经踩过一个坑——块存储的容量规划。因为块存储是按「预分配」方式使用的,你创建了一个1TB的卷,即使只用了100GB,它也会占用1TB的物理空间。所以一定要做好容量监控,否则磁盘满了都不知道。

适用场景:

  • 数据库(MySQL、PostgreSQL、Oracle)
  • 虚拟机磁盘(VMware、KVM)
  • 高性能计算(HPC)
  • 容器持久化存储(StatefulSet)
# 用iSCSI挂载一个块存储设备
# 先发现目标
iscsiadm -m discovery -t sendtargets -p 192.168.1.100

# 登录
iscsiadm -m node -T iqn.2024-01.com.example:storage.target01 -l

# 查看挂载后的设备
lsblk | grep sd

# 格式化并挂载(注意:块存储需要自己管理文件系统)
mkfs.ext4 /dev/sdb
mount /dev/sdb /mnt/data

2.5 如何选型?我的决策框架

说了这么多,到底怎么选?我一般用三个问题来判断:

  1. 你的数据有多大? 超过PB级,直接选对象存储。TB级以内,文件存储或块存储都可以。
  2. 你的延迟要求有多高? 微秒级,必须块存储。毫秒级,文件存储够用。秒级,对象存储没问题。
  3. 你的访问模式是什么? 写一次读多次,对象存储。频繁读写且需要共享,文件存储。随机读写且要求高IOPS,块存储。

最后说一句:实际项目中,这三种存储往往是混合使用的。比如一个典型的互联网应用架构:

  • 数据库跑在块存储上(高性能)
  • 应用日志存在文件存储上(共享访问)
  • 用户上传的图片存在对象存储上(海量存储)

没有最好的存储,只有最合适的组合。

好了,这一章就到这里。下一章我会讲对象存储的架构设计,包括数据分片、纠删码、一致性哈希这些核心技术。到时候见。