基于Python实现的分布式文件系统
作者:天天进步2015
一、项目简介
在很多业务系统中,用户上传的文档、日志、图片、模型文件会快速增长。如果所有文件都放在单台服务器上,容量、可靠性和扩展性都会成为瓶颈。本项目以“基于 Python 的分布式文件系统”为主题,构建一个可运行的全栈项目:后端使用 FastAPI 提供认证、节点管理和文件分片接口,数据库使用 SQLite 保存用户、文件元数据和分片位置,前端使用 Vue 3 + Vite 构建管理页面。
项目不是简单的算法演示,而是包含完整注册、登录、Token 鉴权、节点上下线、文件上传、分片副本、文件读取校验等功能的全栈应用。为了便于本地运行,示例把真实分布式节点抽象为数据库中的 StorageNode,并把分片内容保存到 SQLite;实际生产系统可以把该层替换为对象存储、磁盘节点或远程 Agent。
二、技术栈
- 后端:Python 3、FastAPI、SQLAlchemy、Pydantic、Passlib bcrypt
- 数据库:SQLite
- 前端:Vue 3、Vite、Fetch API、单文件组件
- 鉴权:HTTP Bearer Token,自定义签名和过期时间
- 打包部署:后端 uvicorn,前端 npm run dev / vite build
三、系统架构
系统采用前后端分离架构:
Vue 3 前端
├── 注册/登录页面
├── 集群节点管理
├── 文件上传与读取
└── 带 Token 的 API 请求
│ HTTP JSON
▼
FastAPI 后端
├── Auth:用户、密码哈希、Token
├── Node:存储节点注册、上下线
├── File:文件元数据、分片、副本、校验
└── SQLAlchemy ORM
│
▼
SQLite 数据库
├── users
├── storage_nodes
├── stored_files
└── file_chunks
核心流程如下:用户登录后上传逻辑文件,后端计算文件 SHA-256,把内容按固定长度切片,并根据副本数把每个分片分配到多个在线节点;读取文件时按 chunk_index 取每个分片的一个可用副本,重组后再次校验文件哈希。
四、功能模块
- 用户认证模块:注册、登录、获取当前用户;密码使用 bcrypt 哈希存储,业务接口通过 Bearer Token 保护。
- 存储节点模块:初始化演示节点,支持新增节点、查看节点容量、切换节点上线/下线。
- 文件管理模块:上传文本文件、按 64 字符切片、生成副本、查看文件列表、读取文件内容、删除文件。
- 集群看板模块:展示节点数量、在线节点数量、当前用户文件数量、全局分片数量。
- 前端状态模块:localStorage 保存登录态,请求自动携带 Authorization Header,退出登录会清理会话。
五、数据库/数据模型设计
users
保存用户登录信息:
| 字段 | 说明 |
|---|---|
| id | 用户 ID |
| username | 唯一用户名 |
| password_hash | bcrypt 哈希后的密码 |
| created_at | 注册时间 |
storage_nodes
保存集群节点元数据:
| 字段 | 说明 |
|---|---|
| id | 节点 ID |
| name | 节点名称 |
| address | 节点地址 |
| capacity_mb | 节点容量 |
| used_mb | 已用容量估算 |
| online | 是否在线 |
stored_files
保存逻辑文件元数据:文件名、大小、完整文件校验和、期望副本数、所属用户。
file_chunks
保存文件分片副本:分片所属文件、所在节点、分片序号、分片内容、分片校验和。
六、后端接口设计
| 方法 | 路径 | 认证 | 说明 |
|---|---|---|---|
| GET | /api/health | 否 | 健康检查 |
| POST | /api/auth/register | 否 | 注册并返回 Token |
| POST | /api/auth/login | 否 | 登录并返回 Token |
| GET | /api/auth/me | 是 | 当前用户信息 |
| GET | /api/stats | 是 | 集群统计 |
| GET | /api/nodes | 是 | 节点列表 |
| POST | /api/nodes | 是 | 新增节点 |
| PATCH | /api/nodes/{node_id} | 是 | 更新节点状态 |
| GET | /api/files | 是 | 我的文件列表 |
| POST | /api/files | 是 | 上传并分片存储文件 |
| GET | /api/files/{file_id} | 是 | 读取并重组文件 |
| DELETE | /api/files/{file_id} | 是 | 删除文件 |
七、前端页面设计
前端使用 Vue 3 单文件组件 App.vue,包含两个主要状态:未登录状态和已登录状态。
- 未登录:展示登录/注册表单,可切换模式。
- 已登录:展示顶部用户信息和退出按钮。
- 统计卡片:显示节点、在线节点、文件和分片数量。
- 上传区域:输入文件名、内容、副本数后提交。
- 节点区域:查看节点地址、容量和在线状态,支持上下线。
- 文件区域:展示文件 checksum、分片副本数量,支持读取和删除。
API 调用封装在 frontend/src/api.js 中,自动从 localStorage 读取 Token 并附加到请求头。
八、核心代码讲解
1. 数据库连接
backend/app/database.py 创建 SQLite 引擎和 Session:
SQLALCHEMY_DATABASE_URL = "sqlite:///./dfs.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
FastAPI 通过 get_db() 依赖为每个请求提供数据库会话。
2. 用户密码哈希与 Token
crud.py 使用 Passlib 的 bcrypt 保存密码哈希,避免明文密码落库。登录成功后生成带用户 ID、过期时间、随机 nonce 和 SHA-256 签名的 Token,接口通过 get_current_user 依赖解析并校验。
def hash_password(password: str) -> str:
return pwd_context.hash(password)
def verify_password(password: str, password_hash: str) -> bool:
return pwd_context.verify(password, password_hash)
3. 文件切片与副本分配
上传文件时,后端先查询在线节点,再把内容按 CHUNK_SIZE 切片。每个分片根据副本数写入不同节点,形成多副本分布。
chunks = [content[i : i + CHUNK_SIZE] for i in range(0, len(content), CHUNK_SIZE)]
for idx, chunk in enumerate(chunks):
for replica in range(real_replica_count):
node = online_nodes[(idx + replica) % len(online_nodes)]
db.add(FileChunk(file_id=file.id, node_id=node.id, chunk_index=idx, data=chunk, checksum=sha256_text(chunk)))
4. 文件读取与完整性校验
读取文件时,系统按分片序号选择第一个副本并拼接,再与文件级 checksum 比对。如果校验失败,说明分片数据不完整或被篡改。
content = "".join(first_replica_by_index[index] for index in sorted(first_replica_by_index))
if sha256_text(content) != file.checksum:
raise HTTPException(status_code=500, detail="文件校验失败")
5. 前端鉴权请求
api.js 统一封装请求,登录后所有受保护接口都会携带 Token:
const token = getToken()
if (token) headers.Authorization = `Bearer ${token}`
九、部署与运行步骤
1. 运行后端
cd project/backend python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
后端默认地址为 http://127.0.0.1:8000,Swagger 文档地址为 http://127.0.0.1:8000/docs。
2. 运行前端
cd project/frontend npm install npm run dev
前端默认地址为 http://127.0.0.1:5173。如果后端地址不同,可以通过 VITE_API_BASE 环境变量配置。
3. 使用流程
- 打开前端页面,注册用户。
- 登录后查看默认三个存储节点。
- 上传一个文本文件,观察文件列表中的分片副本数量。
- 切换某个节点下线,再继续上传文件,观察副本分布变化。
- 点击读取文件,后端会重组分片并校验内容。
十、项目总结
本项目用较小的代码量实现了分布式文件系统的关键业务闭环:认证鉴权、元数据管理、节点管理、文件切片、副本冗余和完整性校验。它适合作为全栈课程、毕业设计或工程实践的基础版本。后续可以继续扩展真实文件上传、断点续传、节点健康检查、后台副本修复、用户空间配额、对象存储接入、审计日志和 Prometheus 监控等能力。
以上就是基于Python实现的分布式文件系统的详细内容,更多关于Python分布式文件系统的资料请关注脚本之家其它相关文章!
