当前位置:网站首页>干货|如何在海量文件系统中选择合适自己的文件系统
干货|如何在海量文件系统中选择合适自己的文件系统
2022-08-02 09:06:00 【InfoQ】
前言

数据类型划分
结构化数据:

非结构化数据:

半结构化数据:

分布式文件系统


技术选型
- 易用性:该文件系统主要用于博客图片等海量小文件存储,对应文件系统应该是轻量级的,且易于搭建和管理
- 可靠性:使用文件系统进行统一文件管理,那么就要保证考虑单点故障问题,保障文件的高可用性
- 拓展性:随着时间积累,小文件的累计也会变成"大文件",因此文件系统的是否易于拓展也是选型中一重要考虑指标
- 社区活跃度:社区活跃度高的第三方组件,社区的文档、采坑经验、更新迭代等会更加完善,能够帮助快速集成,定位问题,减少风险。
- 节约成本:存储海量文件,占用的磁盘空间大小、访问时需要的资源也不容小觑,节约成本也是选型需要考虑的又一重要因素
Seaweedfs
- 存储数十亿的文件(storeage billions of files)
- 快速获取文件(serve the files fast)
- O(1)磁盘读取速度

Seaweedfs组成

Seaweedfs核心概念介绍
- Node:系统抽象节点,具体实现有DataCenter、Rack、DataNode,可以理解成编程语言中的接口。
- DataCenter:数据中心,对应现实生活中的机房,可以存在多个。
- Rack:机架,对应现实生活中机房存放服务器的机架,一个DataCenter中可以存在多个Rack,但是一个Rack只能属于一个DataCenter。
- DataNode:具体的存储节点,用于管理、存储逻辑卷(Volume)
- Master:用于管理文件卷与服务器磁盘的映射(即管理存储文件和fid之间的映射关系)
- Volume:逻辑卷,存储的逻辑结构,在它之下是使用Needle来存储具体的文件
- Needle:逻辑卷中实际的存储对象,存储真实文件
- Collection:文件集,可以分布在多个逻辑卷上,如果在存储文件的时候没有指定collection,则默认使用""

Seaweedfs特点分析
- 易用性:Seaweedfs支持使用二进制(解压运行即可)、Docker、编译源码等方式部署,支持Restful API风格完成增删改等操作,简单方便,且提供了可视化界面,方便运维和管理。
- 可靠性:Seaweedfs支持多Master节点和备份机制,能够有效避免单点故障
- 拓展性:Seaweedfs一个Master节点下可挂载多个Volume节点,空间不足时,可以添加磁盘或者机器启动新的Volume实现拓展存储。
- 社区活跃性:Seaweedfs作为Apache基金会下的开源项目,在Github上已经14.9K的star,且官方提供了详细的项目介绍文档和部署文档,社区活跃度相比同类产品也是非常不错。
- 节约成本:Seaweedfs官方描述,每个文件的元数据只有40字节的磁盘存储开销。O(1)磁盘读取,且对大数据量的小文件存储进行了优化,意味着能用更少的空间存储更多的资源,节省开支成本。

实战-使用Seaweedfs搭建文件服务器
- Weed master :开启一个master服务器
- Weed volume :开启一个volume 服务器
- Weed filer :开启一个指向一个或多个master服务器的file服务器
- Weed upload:上传一个或多个文件
- Weed server:启动一个服务器,包括一个volume服务器和自动选举一个master服务器
搭建Seaweedfs文件服务器
- rz -be xx.seaweedfs.tar.gz 上传文件
- tar -zxvf seaweedfs-0.99.tar.gz 解压文件

- /usr/local/seaweedfs0.99/seaweedfs/sbin/weed master -mdir=/usr/local/seaweedfs0.99/seaweedfs/data/master -port=9333 -defaultReplication=000 -ip=xxx主服务IP地址 启动master主服务
- /usr/local/seaweedfs0.99/seaweedfs/sbin/weed volume -dataCenter=dataCenter1 -rack=rack1 -dir=/usr/local/seaweedfs0.99/seaweedfs/data/volume -max=5 -mserver=主服务IP地址:9333(端口) -port=9040 -ip=服务ip地址- 启动volume服务

- http://ip地址:9333/

JAVA程序集成Seaweedfs完成程序操作文件系统
- Gitee地址:轮子之王
- Github地址:轮子之王
// 依赖
<dependency>
<groupId>org.lokra.seaweedfs</groupId>
<artifactId>seaweedfs-client</artifactId>
<version>0.7.3.RELEASE</version>
</dependency>
// seaweedfs文件服务器信息
seaweedfs:
host: 127.0.0.1
port: 9333
/**
* @description: 上传单个文件到文件服务器
* @param: file
* @return: 文件的fid + 文件的请全访问地址
* @author: it
*/
public String uploadFile(MultipartFile file) throws Exception {
FileSource fileSource = getFileSource();
FileTemplate fileTemplate = new FileTemplate(fileSource.getConnection());
// 上传文件
FileHandleStatus handleStatus = fileTemplate.saveFileByStream(file.getOriginalFilename(), file.getInputStream(), contentType);
// 获取上传文件的访问地址
String fileUrl = fileTemplate.getFileUrl(handleStatus.getFileId());
// 关闭当前连接
fileSource.shutdown();
return handleStatus.getFileId() + StrUtil.DASHED + fileUrl;
}
/**
* @description: 根据文件ID删除文件
* @author: it
*/
public void deleteFileByFid(String fileId) throws Exception {
FileSource fileSource = getFileSource();
FileTemplate fileTemplate = new FileTemplate(fileSource.getConnection());
fileTemplate.deleteFile(fileId);
fileSource.shutdown();
}
/**
* @description: 根据文件下载文件
* @param: fid
* @param: response
* @param: fileName
* @author: it
*/
public void downloadFileByFid(HttpServletResponse response, HttpServletRequest request, String fid, String fileName) throws Exception {
FileSource fileSource = getFileSource();
FileTemplate fileTemplate = new FileTemplate(fileSource.getConnection());
StreamResponse fileStream = fileTemplate.getFileStream(fid);
// 设置响应头
response.setContentType(CommonConstant.CONTENT_TYPE);
response.setCharacterEncoding(CommonConstant.UTF_8);
String encodeFileName = buildingFileNameAdapterBrowser(request, fileName);
response.setHeader(CommonConstant.CONTENT_DISPOSITION, CommonConstant.ATTACHMENT_FILENAME + encodeFileName);
// 读取并写入到响应输出
InputStream inputStream = fileStream.getInputStream();
byte[] fileByte = new byte[inputStream.available()];
inputStream.read(fileByte);
response.getOutputStream().write(fileByte);
response.getOutputStream().flush();
fileSource.shutdown();
}



写在最后
- Gitee地址:轮子之王
- Github地址:轮子之王
边栏推荐
- ORBSLAM代码阅读
- Rust 从入门到精通03-helloworld
- 力扣:第 304 场周赛
- 软件exe图标变记事本或浏览器、360压缩打不开的几种应急解决方法
- What attributes and methods are available for page directives in JSP pages?
- Scala类型转换
- sql concat(),如何才能拼接表的名字
- Daily practice of dynamic programming (2)
- EPSANet: An Efficient Pyramid Split Attention Block on Convolutional Neural Network
- 腾讯T8架构师,教你学中小研发团队架构实践PDF,高级架构师捷径
猜你喜欢

State Management in Jetpack Compose

AutoJs学习-实现科赫雪花

UVM之sequence机制

The use of thread pool and analysis of ThreadPoolExecutor source code

智能网络安全网卡|这是不是你要的安全感

Spend 2 hours a day to make up for Tencent T8, play 688 pages of SSM framework and Redis, and successfully land on Meituan

PyQt5(一) PyQt5安装及配置,从文件夹读取图片并显示,模拟生成素描图像

不用Swagger,那我用啥?

Redis数据结构

RetinaFace: Single-stage Dense Face Localisation in the Wild
随机推荐
2022牛客暑期多校训练营4(ADHKLMN)
膜拜,Alibaba分布式系统开发与核心原理解析手册
next permutation
XML简介
Hikari连接池源码解读
AI目标分割能力,无需绿幕即可实现快速视频抠图
pycharm的基本使用教程(1)
HCIP笔记第十三天
tf中tensor的大小输出
js引擎运行中的预解析(变量提升和函数提升)及相关实操案例
JSP页面中page指令contentPage/pageEncoding具有什么功能呢?
Fiddler(七) - Composer(组合器)克隆或者修改请求
AutoJs学习-实现科赫雪花
Bigder:41/100生产bug有哪些分类
Nodejs3day(express简介,express创建基本Web服务器,托管静态资源,nodemon下载及出现的问题,中间件,编写GET,POST,JSONP接口)
利用minlm比较句子之间的相似度
Codeforces Round #811 (Div. 3)无DF
恋爱十不要
Jenkins--基础--6.3--Pipeline--语法--脚本式
RetinaFace: Single-stage Dense Face Localisation in the Wild