云原生存储别乱选:Object、Block、File 到底谁更适合你?

简介: 云原生存储别乱选:Object、Block、File 到底谁更适合你?

云原生存储别乱选:Object、Block、File 到底谁更适合你?

很多团队上云以后,都会遇到一个看起来特别简单、实际上很容易踩坑的问题:

“我们的数据到底该放对象存储、块存储,还是文件存储?”

刚开始的时候,很多人的判断方式非常直接:

业务文件?Object Storage。

数据库?Block Storage。

共享目录?File Storage。

乍一看,好像已经总结完了。

但真正到了生产环境,你会发现事情没这么简单。

为什么同样是“存数据”,对象存储便宜得离谱,数据库却不能直接往里面写?

为什么 Kubernetes 里面挂一个 PVC,看起来都是磁盘,背后却可能是完全不同的存储系统?

为什么有些系统用了共享文件存储以后,开发人员天天抱怨“怎么这么慢”?

说到底,不是 Object、Block、File 谁更高级,而是:

不同的数据,天然就应该用不同的存储方式。

存储选型这件事,本质上不是“哪个性能最高”,而是成本、性能、一致性、扩展性和使用方式之间的权衡

今天咱们就把这三个家伙掰开揉碎聊一遍。


一、先别急着选,先搞明白三种存储到底是什么

可以把它们想象成三个不同的仓库。

1. Object:像一个超大的快递仓库

对象存储最典型的特点,就是:

数据 + 元数据 + 唯一 Key

组成一个完整对象。

比如:

bucket:
  images/
    user001/avatar.png
    user002/avatar.png

  videos/
    2026/
      demo01.mp4

你不需要关心“这个文件到底放在哪块磁盘”。

你只需要告诉存储系统:

put_object(
    bucket="images",
    key="user001/avatar.png",
    data=file
)

以后再通过 Key 把它取出来:

get_object(
    bucket="images",
    key="user001/avatar.png"
)

它最大的优势就是:

扩展简单、容量巨大、成本低。

所以特别适合:

图片、视频、备份、日志、模型文件、安装包、归档数据、数据湖等。

例如你的 AI 系统里可能有:

model/
├── llama-8b/
├── embedding/
├── reranker/
└── checkpoints/

这种数据放 Object Storage,通常比拿高性能块存储硬扛更划算。


二、Block:像给服务器插了一块“硬盘”

块存储就比较容易理解了。

对操作系统来说,它基本就是一块磁盘。

例如:

lsblk

可能看到:

sda
├─sda1
└─sda2

sdb

然后你可以:

mkfs.ext4 /dev/sdb
mount /dev/sdb /data

对于应用来说,它根本不需要知道后面是什么云盘、SAN、分布式存储。

它只觉得:

“这是我的磁盘。”

所以数据库特别喜欢它。

比如 MySQL:

/data/mysql/
├── ibdata1
├── ib_logfile0
├── ib_logfile1
└── mydb/

数据库自己控制:

  • Page
  • WAL
  • Buffer Pool
  • fsync
  • 随机读写
  • 顺序读写

这种场景,Block Storage 就非常合适。

因为数据库最怕的不是“容量不够”,而是:

IOPS 不稳定、延迟太高、fsync 不靠谱。


三、File:像公司里的共享网络盘

文件存储最大的特点,就是:

多个机器可以同时看到一个目录。

例如:

/data/share

服务器 A:

touch /data/share/a.txt

服务器 B:

ls /data/share

马上就能看到:

a.txt

这就是 File Storage 的价值。

典型协议包括:

NFS
SMB

Kubernetes 里也经常会看到这种模式:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: shared-pv
spec:
  accessModes:
    - ReadWriteMany
  nfs:
    server: 10.0.0.10
    path: /data/share

然后多个 Pod 可以一起挂:

Pod A ─┐
Pod B ─┼──> NFS
Pod C ─┘

这对于共享配置、共享素材、传统应用迁移特别方便。

但问题也很明显:

共享方便,性能和一致性就需要付出代价。


四、真正难选的地方来了:性能不是唯一标准

很多人做存储选型,第一反应就是:

“哪个性能最高?”

其实这是一个很容易掉坑里的问题。

因为存储不是跑分游戏。

真正应该看的是:

业务访问模式
        ↓
数据规模
        ↓
读写方式
        ↓
一致性要求
        ↓
共享要求
        ↓
性能要求
        ↓
最终成本

比如:

一个 10MB 的图片,偶尔下载一次。

和:

一个数据库每秒进行几万次随机 IO。

虽然都是“存文件”,但完全是两码事。


五、一个简单粗暴的判断方法

我自己比较推荐一个特别接地气的判断方式。

先问自己三个问题。

第一个问题:需要像磁盘一样直接使用吗?

需要。

优先考虑:

Block Storage

例如:

MySQL
PostgreSQL
Redis
Elasticsearch

这些系统通常希望直接控制底层块设备。


第二个问题:是不是很多机器都要访问同一个目录?

是。

优先考虑:

File Storage

比如:

共享文件
用户上传目录
传统应用文件目录
CI/CD 工作空间
多个 Pod 共享数据

第三个问题:是不是大量非结构化数据?

是。

优先考虑:

Object Storage

例如:

图片
视频
日志
备份
AI 模型
数据集
历史归档

这个思路虽然简单,但在实际项目里面非常好用。


六、Kubernetes 里面,这三个存储更容易把人绕晕

Kubernetes 里经常出现:

PV
PVC
StorageClass
CSI

刚接触的时候特别容易产生一个错觉:

“PVC 不就是一块硬盘吗?”

其实不是。

PVC 只是告诉 Kubernetes:

“我想要一份什么样的存储。”

例如:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce

  resources:
    requests:
      storage: 100Gi

背后真正提供存储的,可能是:

云块存储
Ceph RBD
NFS
分布式文件系统
其他 CSI Storage

所以你看到:

PVC = 100Gi

并不代表:

PVC = 某一块真实硬盘

这里千万别搞混。


七、Object Storage 看起来便宜,但千万别拿它当万能硬盘

对象存储最大的诱惑就是:

便宜,而且容量几乎可以无限扩。

于是就有人想:

“既然这么便宜,我所有东西都放 Object Storage 不就行了?”

然后开始踩坑。

比如某个应用原来这样:

with open("/data/test.json", "r") as f:
    data = json.load(f)

然后有人想迁移:

/data/test.json

直接变成:

Object Storage

结果代码改成:

data = client.get_object(
    Bucket="data",
    Key="test.json"
)

这时候问题马上来了。

传统文件系统有:

open
read
write
seek
rename
mkdir
lock

而对象存储的核心思维其实是:

PUT Object
GET Object
DELETE Object
LIST Object

两者的模型根本不一样。

所以:

Object Storage 不是“更大的硬盘”,它是完全不同的数据访问模型。

这一点特别重要。


八、反过来,把数据库塞进对象存储,也一样难受

比如:

MySQL
PostgreSQL
MongoDB

这类系统非常依赖:

随机 IO
低延迟
fsync
WAL
局部更新
高频读写

假设数据库一个 Page 只有几 KB。

如果每次小修改都搞成:

下载对象
修改
重新上传整个对象

这是什么感觉?

基本等于:

拿快递仓库当内存条用。

理论上可以折腾,实际上会非常难受。

所以数据库、缓存、搜索引擎这种系统,通常更适合使用高性能 Block Storage,或者使用其自身面向对象/分布式存储的专用架构。


九、File Storage 最大的坑:共享不等于高性能

File Storage 特别适合:

ReadWriteMany

也就是:

多个 Pod
    ↓
共享目录

看起来非常舒服。

但是假设 100 个 Pod 同时:

打开文件
写文件
刷新
关闭

后端又只有一个共享文件系统。

这时候性能瓶颈就可能出现。

特别是大量小文件场景。

例如:

/opt/data/
├── 000001.json
├── 000002.json
├── 000003.json
├── ...
└── 500000.json

看着没多少数据,但是 metadata 操作可能非常多。

所以实际项目里经常会出现一种情况:

容量一点问题没有,IO 延迟却已经爆了。

这就是为什么做存储选型的时候:

不要只盯着 TB,要看 IOPS、吞吐、延迟和访问模式。


十、真正生产环境,往往不是三选一,而是“三个一起用”

这是我特别想强调的一点。

很多成熟系统根本不会说:

“我们公司统一使用 Object Storage。”

或者:

“全部用 Block Storage。”

更加合理的方式其实是:

                ┌──────────────┐
                │   Kubernetes │
                └──────┬───────┘
                       │
        ┌──────────────┼───────────────┐
        ↓              ↓               ↓
     Block           File            Object
        │              │               │
     数据库          共享目录         图片/视频
     Redis           用户文件         日志
     ES              配置共享         模型
                                     备份

比如一个 AI 平台。

你可能这样设计:

MySQL
   ↓
Block Storage

模型服务临时缓存
   ↓
Block Storage

多个推理 Pod 共享配置
   ↓
File Storage

模型权重
   ↓
Object Storage

训练数据集
   ↓
Object Storage

训练日志
   ↓
Object Storage

这才是比较合理的组合。


十一、别忘了成本:性能不是免费的

这可能是很多技术人员最容易忽略的一件事情。

假设三种存储:

Object:便宜
File:中等
Block:昂贵

当然,实际价格会因云厂商、规格、区域以及性能等级不同而变化。

但总体来说:

越接近传统磁盘语义、越强调低延迟和高 IOPS,成本通常越高。

所以千万不要:

所有数据
   ↓
最高规格 SSD
   ↓
“性能好就完事了”

这种架构上线以后,账单可能比技术债还先找上门。

特别是:

日志
历史文件
备份
模型
大数据集
归档数据

这些东西如果全部放高性能 Block Storage,很多时候属于:

用跑车运砖头。


十二、我更推荐一个“冷热分层”的思路

比如:

                数据
                 │
        ┌────────┴────────┐
        ↓                 ↓
      热数据            冷数据
        │                 │
     Block/File        Object
        │                 │
    高频访问            低频访问
    低延迟              低成本

再进一步,可以搞成:

SSD Block
   ↓
File Storage
   ↓
Object Storage
   ↓
Archive

真正需要高性能的数据才放在第一层。

不常用的数据不断往后迁。

这样做最大的好处不是“技术先进”,而是:

成本终于能控制住。


十三、最后送大家一张非常实用的选择表

场景 推荐存储
MySQL / PostgreSQL Block
Redis 持久化 Block
Elasticsearch Block
用户上传图片 Object
视频 Object
日志归档 Object
数据湖 Object
模型文件 Object
多 Pod 共享目录 File
NFS 共享文件 File
传统应用文件系统 File
高并发随机 IO Block
大文件顺序读写 Object / Block
大量历史数据 Object

当然,这张表不是“绝对真理”。

真正选型还是得结合:

访问频率
访问方式
读写比例
IOPS
吞吐
延迟
一致性
共享需求
数据生命周期
成本

来判断。


写在最后

做云原生这么久,我越来越觉得一个事情特别有意思:

很多所谓的“架构问题”,最后其实都是“选择问题”。

Object、Block、File 没有谁能“一统天下”。

Object Storage 擅长的是:

海量、便宜、非结构化数据。

Block Storage 擅长的是:

低延迟、高 IOPS、像磁盘一样使用。

File Storage 擅长的是:

多节点共享访问。

真正成熟的架构,不是非要选出一个“最牛”的存储。

而是:

让不同的数据,住进最适合自己的房子。

数据库没必要住进对象仓库。

几 TB 的历史日志,也没必要天天占着高性能 SSD。

多个 Pod 需要共享目录的时候,也别非得让每个 Pod 都自己背一块磁盘。

说到底,云原生存储选型就一句大白话:

该省钱的时候别烧钱,该要性能的时候别抠门,该共享的时候别硬搞单机。

技术架构真正的高级感,往往不是用了多少新技术,而是:

知道什么时候该用什么技术,而且知道为什么。

—— Echo_Wish

目录
相关文章
人工智能 缓存 前端开发
11661 58
人工智能 JavaScript 开发工具
4639 17
开发工具 Swift git
1875 6
Web App开发 人工智能 API
1129 1
人工智能 Java BI
1266 1
人工智能 JavaScript 测试技术
2097 2
人工智能 JavaScript 测试技术
1066 4
缓存 JavaScript Shell
2042 3