『7x24小时有问必答』

前言

在互联网业务中,小文件(几KB到几百MB)的存储需求无处不在——用户头像、商品图片、日志片段、配置文件等,数量动辄百万甚至上亿。然而,传统文件系统或通用对象存储在面对海量小文件时,常常遭遇元数据膨胀、I/O密集、吞吐下降等性能瓶颈。
本文推荐一款完全自研、基于 Java 的分布式小文件存储系统。该系统不仅功能完整,更在架构设计和生产级优化上下足功夫,真正实现了"高效、稳定、可扩展"。

项目介绍

项目是一个面向海量小文件场景的分布式存储系统,使用 Java 语言从零开发,不依赖 HDFS、MinIO 等外部组件。
核心目标是解决小文件在上传、下载、存储过程中遇到的各类性能问题。系统采用主从架构,包含 NameNode(元数据管理)、DataNode(数据存储)、BackupNode(高可用备份)等核心角色,并支持多节点集群部署,适用于中小规模互联网企业的实际业务场景。

项目功能

1、文件上传:客户端可通过 API 将小文件上传至集群,系统自动完成路由、落盘与元数据注册。
2、文件下载:根据文件唯一标识快速定位 DataNode 并返回内容。
3、文件持久化存储:所有文件以结构化方式存储于本地磁盘,支持断电恢复。
4、用户鉴权:通过简单的用户名/密钥机制控制访问权限。
5、目录管理:支持创建、遍历虚拟目录结构,提升使用体验。

项目特点

1、网络层统一升级:早期教学版本混用原生 NIO 与 gRPC,正式版全面迁移到 Netty 框架,通信更高效、代码更清晰。
2、自定义文件传输协议:定义了包含包类型、元数据、二进制内容的标准化网络包格式,适用于客户端-DataNode、NameNode-BackupNode 等多种传输场景。
3、分块传输机制:当响应数据超过单包上限时,自动拆分为多个数据块传输,客户端重组后返回完整结果,有效避免内存溢出。
4、NameNode 联邦架构:将全局目录树切分为多个子树,由不同 NameNode 节点管理,显著降低单节点内存压力,提升横向扩展能力。
5、高可用设计:采用 BackupNode + NameNode 主备模式,定期同步 FsImage,主节点故障时可快速切换,保障服务连续性。
6、生产级问题闭环:已在压测中识别并解决 OOMKiller 杀死进程、带宽打满超时、DataNode 流量不均、CPU 100%、刷盘导致吞吐骤降等典型问题。

项目技术

开发语言:Java(占比 93.3%),辅以少量 JavaScript 用于管理界面。
网络通信:基于 Netty 实现异步非阻塞 I/O,统一全链路通信模型。
序列化:采用 Protobuf 高效序列化元数据与控制消息。
元数据管理:自研 FsImage 格式,支持增量 checkpoint 与联邦分片。
部署架构:支持多 DataNode 动态注册,通过 hostname 区分节点,避免冲突;NameNode 与 BackupNode 集成在同一模块,便于运维。

项目效果

生产级技术架构

网络升级

小文件系统的网络部分原本实现比较杂乱,这是由于讲课的时候需要讲解各种技术的使用方式和演示最底层的开发是使用那些API。所以在课程中的网络分别使用了原生NIO和gRpc 但是我们做技术选型的时候选择统一网络请求方式,统一采用Netty作为网络通讯框架,改造前后对比如图:

文件传输协议

在集群中会有几种场景需要进行文件传输,比如上传、下载文件是客户端和DataNode之间进行文件传输,BackupNode和NameNode之间也要进行FsImage的文件传输。所以设计了一套文件传输的协议。文件传输的网络包包括包类型、文件元数据、文件内容二进制数据,如图:

分块传输设计

如图所示,当发送一个请求的时候,假如服务端写回的响应较大(超过最大消息长度),此时可以根据请求是否支持分块传输来决定是否需要拆包传输,可以将1个包拆分为n个包,然后传输给NetClient, NetClient收到包的时候,会根据一定的机制判断整个包是否传输完整,当收到了所有的响应包之后,再将所有的响应包合并成一个包,然后返回给用户。
NameNode联邦架构
为了解决大规模海量小文件带来的内存增长压力,开发了NameNode的联邦架构,简单来说,就是通过多个NameNode节点组成集群,每个NameNode节点保存整个内存目录树的一部分数据。

线上性能参数回放

项目源码

编译步骤
cd  ruyuan-dfs/ruyuan-dfs-common

mvn protobuf:compile && mvn install

温馨提示:Apple M1 用户需在  pom.xml  或 Maven  settings.xml  中添加  <os.detected.classifier>osx-x86_64</os.detected.classifier>  以兼容 Protobuf 插件。
启动流程
修改  conf/namenode.properties、backupnode.properties、datanode.properties  中的  base.dir  为本地路径;
启动 NameNode:运行  com.ruyuan.dfs.namenode.NameNode,传入 JVM 参数  -Dlogback.configurationFile=conf/logback-namenode.xml  和程序参数  conf/namenode.properties;
启动 BackupNode 与多个 DataNode(注意配置不同  datanode.id、端口及 hostname,可通过  /etc/hosts  映射);
创建测试用
   curl -H  "Content-Type: application/json"  -X POST -d  '{"username": "admin","secret": "admin"}'  "http://localhost:8081/api/user"

运行  ruyuan-dfs-client  模块中的  FileSystemTest  单元测试,验证全流程功能。
Gitee:https://gitee.com/suzhou-mopdila-information/ruyuan-dfs

总结

这款自研分布式小文件存储系统,不仅是代码的堆砌,更是对分布式系统核心问题的深入实践。它从真实业务痛点出发,通过联邦架构、Netty 网络、分块传输、高可用设计等手段,有效攻克了海量小文件的性能难关。作为开源项目,它兼具学习价值与落地潜力,非常适合希望掌握分布式存储原理或寻找轻量级存储方案的开发参考与使用。

关键词

作者:小码编匠
出处:gitee.com/smallcore/DotNetCore
声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!

END

往
期
精
彩

备注【开源】
方便大家交流、资源共享和共同成长
纯技术交流群、需要的小伙伴请扫码

有收获?不妨分享让更多人受益
关注「程序员开源栈」,共同提升技术实力

点分享
点收藏
点在看
点点赞

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码