1 背景与演进
1.1 为什么需要分布式文件系统
| 阶段 |
特点 |
优缺点 |
| 单机时代 |
项目目录下建立静态文件夹 |
简单但文件与代码耦合,流量大时影响业务 |
| 独立文件服务器 |
图片服务器 + Nginx 独立部署 |
性能分离但存在单机瓶颈 |
| 分布式文件系统 |
存储 + 仲裁 + 容灾三系统配合 |
高可用、可扩展,但复杂度较高 |
1.2 适用场景
FastDFS 特别适合以中小文件(建议范围:4KB < file_size < 500MB)为载体的在线服务:
2 FastDFS 概述
2.1 核心特性
- 轻量级:纯 C 实现,支持 Linux、FreeBSD 等 UNIX 系统
- 文件一对一:文件不分块存储,与 OS 文件系统一一对应
- 去重:相同内容文件只保存一份,节约磁盘空间
- HTTP 支持:内置 Web Server 或配合 Nginx/Apache
- 在线扩容:支持动态扩展存储容量
- 主从文件:支持主从文件机制
- 高性能:V2.0 采用 libevent 网络通信,支持大并发
2.2 架构定位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ┌─────────────────────────────────────────────────────┐ │ Client │ │ (业务请求发起方) │ └─────────────────────┬───────────────────────────────┘ │ ┌───────▼───────┐ │ Tracker │ │ (调度中心) │ └───────┬───────┘ │ ┌─────────────┼─────────────┐ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │Storage 1│ │Storage 2│ │Storage N│ │ (Group1)│ │ (Group1)│ │ (Group2)│ └─────────┘ └─────────┘ └─────────┘
|
3 核心概念
3.1 服务角色
| 角色 |
职责 |
特点 |
| Tracker Server |
调度、负载均衡 |
内存记录所有 storage 状态,无持久化,易扩展 |
| Storage Server |
文件存储 |
以组为单位组织,文件属性(meta-data)一并保存 |
| Client |
业务请求发起 |
通过专有 API 与 tracker/storage 交互 |
3.2 核心术语
| 术语 |
说明 |
| Group / Volume |
卷/组,同组内服务器文件完全相同,互为备份 |
| Meta-data |
文件属性,Key-Value 键值对(如:width=1024) |
| FID |
File ID,文件唯一标识 |
3.3 Storage 组织结构
1 2 3 4 5 6 7 8 9
| Storage Server ├── /data/disk1/ # 数据存储目录1 │ ├── 00/ │ │ ├── 00/ │ │ ├── 01/ │ │ └── ... │ └── FF/ ├── /data/disk2/ # 数据存储目录2 └── ...
|
- 每个存储目录创建 2 级子目录(每级 256 个)
- 总共 65536 个文件目录
- 文件按 hash 路由到对应子目录
4 上传机制
4.1 上传流程
1 2 3 4 5 6
| ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Client │────▶│ Tracker │────▶│ Storage │────▶│ 写入磁盘 │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ ▼ ▼ 返回 ip:port 生成 file_id
|
4.2 选择策略
1. 选择 Group
| 规则 |
说明 |
| Round robin |
所有 group 间轮询 |
| Specified group |
指定确定 group |
| Load balance |
剩余空间多的 group 优先 |
2. 选择 Storage Server
| 规则 |
说明 |
| Round robin |
group 内所有 storage 间轮询 |
| First server ordered by IP |
按 IP 排序 |
| First server ordered by priority |
按优先级排序 |
3. 选择 Storage Path
| 规则 |
说明 |
| Round robin |
多个存储目录间轮询 |
| 剩余空间优先 |
剩余存储空间最多的目录优先 |
4.3 FileId 生成
1
| FileId = base64(storage_ip + 文件创建时间 + 文件大小 + crc32 + 随机数)
|
4.4 文件名组成
1
| 文件名 = group + 虚拟磁盘路径 + 两级子目录 + file_id + 文件后缀
|
示例:
1
| group1/M00/00/00/wKgBaE9u4O6Ab7SDAAvgG5Q3vw428.jpg
|
5 下载机制
5.1 下载流程
1 2 3
| ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Client │────▶│ Tracker │────▶│ Storage │────▶│ 返回文件 │ └──────────┘ └──────────┘ └──────────┘ └──────────┘
|
5.2 Storage 选择策略
Tracker 按以下优先级选择可读的 storage:
| 优先级 |
条件 |
说明 |
| 1 |
源头 storage |
文件上传时的源服务器,肯定包含文件 |
| 2 |
同步完成 |
文件创建时间 + 最大同步时间 < 当前时间 |
| 3 |
同步时间戳 |
文件创建时间 < storage 同步时间戳 |
| 4 |
延迟阈值 |
当前时间 - 文件创建时间 > 同步延迟阈值 |
6 同步机制
6.1 同步原理
1 2 3 4 5 6
| ┌──────────┐ binlog ┌──────────┐ │Storage A │ ───────────────▶ │Storage B │ └──────────┐ └──────────┘ │ │ └─────────── 上报 ──────────────┘ Tracker
|
- Storage 写文件后,后台异步同步到同组其他 server
- 同步信息以 binlog 形式记录(不包含文件数据)
- 同步进度以时间戳方式记录
6.2 时钟同步要求
集群内所有服务器时钟必须保持同步,否则同步进度计算会出错。
7 文件定位(FID)
7.1 FID 组成
1
| FID = group + 虚拟磁盘路径 + 两级子目录 + file_id + 文件后缀
|
7.2 快速定位原理
| 步骤 |
操作 |
说明 |
| 1 |
解析 group |
tracker 定位到目标 storage group |
| 2 |
解析路径 |
根据虚拟磁盘路径定位存储目录 |
| 3 |
解析目录 |
根据两级子目录定位具体目录 |
| 4 |
查找文件 |
根据文件名定位文件 |
8 集群部署
8.1 典型架构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ┌─────────────────────────────────────┐ │ Nginx │ │ (负载均衡/静态资源) │ └─────────────────┬───────────────────┘ │ ┌──────────────────────────┼──────────────────────────┐ │ │ │ ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐ │ Tracker1 │ │ Tracker2 │ │ Tracker3 │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ ┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐ │ Group1 │ │ Group2 │ │ Group3 │ │ S1 S2 S3 │ │ S4 S5 S6 │ │ S7 S8 S9 │ └─────────────┘ └─────────────┘ └─────────────┘
|
8.2 部署建议
| 配置项 |
建议 |
| Tracker 数量 |
至少 2 台,实现高可用 |
| Group 内 Storage |
3 台以上,互为备份 |
| 存储目录 |
多磁盘挂载,充分利用空间 |
| 时钟同步 |
所有节点配置 NTP 服务 |
9 Java 客户端使用
9.1 Maven 依赖
1 2 3 4 5
| <dependency> <groupId>org.csource</groupId> <artifactId>fastdfs-client-java</artifactId> <version>1.29-RELEASE</version> </dependency>
|
9.2 配置文件
1 2 3
| fastdfs.tracker_list=192.168.1.100:22122,192.168.1.101:22122 fastdfs.connect_timeout_in_seconds=5 fastdfs.network_timeout_in_seconds=30
|
9.3 上传示例
1 2 3 4 5 6 7 8
| TrackerClient trackerClient = new TrackerClient(); TrackerServer trackerServer = trackerClient.getConnection(); StorageServer storageServer = null;
StorageClient storageClient = new StorageClient(trackerServer, storageServer); String[] result = storageClient.upload_file("/path/to/file.jpg", "jpg", null); System.out.println("Group: " + result[0]); System.out.println("Path: " + result[1]);
|
10 总结
10.1 核心优势
- 高性能:轻量级设计,支持高并发
- 高可用:多 tracker、多 storage 集群支持
- 可扩展:在线扩容,灵活增加存储节点
- 低成本:开源免费,硬件要求低
10.2 适用场景
- 中小文件为主的在线服务
- 需要高可用存储的业务系统
- 对成本敏感但需要分布式存储的场景
10.3 参考资源