GridFS 基于MongoDB的分布式文件存储系统

什么是GridFS

GridFS是一种将大型文件存储在MongoDB的文件规范。所有官方支持的驱动均实现了GridFS规范。GridFS是MongoDB中的一个内置功能,可以用于存放文件。

为什么要使用GridFS

问题1:我之前将文件上传到文件系统中,比如通过FTP上传到文件服务器。并将文件地址存储到MySQL数据库,我觉得这个方式挺好的呀,为什么要使用GridFS?

答:文件系统到了后期会变的很难管理,同时不利于扩展,此外我想做分布式文件系统也显得不那么容易。而GridFS却正好相反,它基于MongoDB的文件系统,便于管理和扩展。

问题2:普通文件系统对于大文件处理比较麻烦,需要考虑文件系统自身的限制,GridFS提供了什么好方案?

答:GridFS 会将大文件对象分割成多个小的chunk(文件片段),一般为256k/块,每块chunk将作为MongoDB的一个文档(document)被存储在chunks集合中。这一点对于很大的内容文件非常有用。此外,GridFS和MongoDB的分片使得你的文件可以分布到多个服务器上,而且没有增加操作的复杂性。

问题3:我可以直接把文件的二进制流存到MongoDB么?

答: MongoDB默认的文件大小上限为16MB。所以,超过这个大小是有问题的。如果你的文件,比如图片、音频、视频等超过了16MB,那么你就应该使用GridFS。

GridFS 的两个集合

GridFS 使用两个集合来存储一个文件:fs.files与fs.chunks。我们可以使用下面命令来进行查看。

show collections

fs.files集合包含了文件的元数据。我们使用命令来查看

db.fs.files.findOne();

以下是刚上传文件的元数据信息的 fs.files 集合文档

{

"_id" : ObjectId("57fb553ac7fa9102e0000001"),

"chunkSize" : 261120,

"uploadDate" : ISODate("2016-10-10T08:45:50.051Z"),

"length" : 1.53513e+008,

"md5" : "9222e097e624800fdd9bfb568169ccad",

"filename" : "E:/jdk-7u79-linux-x64.tar.gz"

}

fs.chunks集合则存储实际的以256KB尺寸进行分割的文件块。如果你有分片的集合,那么文件块会分布到多台服务器上。

db.fs.chunks.getIndexes();

以下是刚上传文件的fs.chunks 集合文档

{

"0" : {

"v" : 1,

"key" : {

"_id" : 1

},

"name" : "_id_",

"ns" : "gridfs.fs.chunks"

},

"1" : {

"v" : 1,

"key" : {

"files_id" : 1,

"n" : 1

},

"name" : "files_id_1_n_1",

"ns" : "gridfs.fs.chunks"

}

}

GridFS 基本操作

上传文件

我们使用GridFS的put命令来存储一个文件。首先,调用MongoDB安装目录下bin的mongofiles.exe工具。然后,打开命令提示符,进入到MongoDB的安装目录的bin目录中,找到mongofiles.exe,并输入下面的代码:

mongofiles.exe -d gridfs put E:elasticsearch-1.7.0.zip

参数说明,–d 指定数据库gridfs

列出清单

使用以下命令来查看数据库中文件的文档

db.fs.files.find()

返回以下内容

/* 1 */

{

"_id" : ObjectId("57fb553ac7fa9102e0000001"),

"chunkSize" : 261120,

"uploadDate" : ISODate("2016-10-10T08:45:50.051Z"),

"length" : 1.53513e+008,

"md5" : "9222e097e624800fdd9bfb568169ccad",

"filename" : "E:/jdk-7u79-linux-x64.tar.gz"

}

/* 2 */

{

"_id" : ObjectId("57fb6c49c7fa9135d4000001"),

"chunkSize" : 261120,

"uploadDate" : ISODate("2016-10-10T10:24:09.654Z"),

"length" : 3.17848e+007,

"md5" : "882013a3d205289dddce22c904d3c476",

"filename" : "E:\elasticsearch-1.7.0.zip"

}

查找文件

可以看到 fs.chunks 集合中所有的区块,以下我们得到了文件的 _id 值,我们可以根据这个 _id 获取区块(chunk)的数据。

db.fs.chunks.find({files_id:ObjectId('57fb553ac7fa9102e0000001')});

以上实例中,查询返回了 50 个文档的数据,意味着文件被存储在50个区块中。

下载文件

我们使用GridFS的get命令来下载一个文件。

mongofiles.exe -d gridfs get E:elasticsearch-1.7.0.zip

Java 操作 GridFS

注意,以下是一个简单的入门案例,不适用于实际场景,实际场景需要考虑异常处理、IO流关闭、日志处理等。

使用的Maven版本

org.mongodb

mongo-java-driver

3.2.2

公共方法

public MongoDatabase mongoDatabase() throws Exception{

MongoClient mongoClient = new MongoClient(mongoHost, mongoPort);

return mongoClient.getDatabase(dbName);

}

上传文件

@Test

public void upload() throws Exception {

// 获取文件流

File file = new File("E:/zookeeper-3.4.8.tar.gz");

InputStream in = new FileInputStream(file);

// 创建一个容器,传入一个`MongoDatabase`类实例db

GridFSBucket bucket = GridFSBuckets.create(mongoDatabase());

// 上传

ObjectId fileId = bucket.uploadFromStream(UUID.randomUUID().toString(), in);

System.out.println("上传完成。 文件ID:"+fileId);

}

查找文件

@Test

public void findOne() throws Exception {

// 获取文件ID

String objectId = "57fbaffcec773716ecc54ef4";

// 创建一个容器,传入一个`MongoDatabase`类实例db

GridFSBucket bucket = GridFSBuckets.create(mongoDatabase());

// 获取内容

GridFSFindIterable gridFSFindIterable = bucket.find(Filters.eq("_id", new ObjectId(objectId)));

GridFSFile gridFSFile = gridFSFindIterable.first();

System.out.println("filename: " + gridFSFile.getFilename());

}

下载文件

@Test

public void download() throws Exception {

// 获取文件ID

String objectId = "57fbaffcec773716ecc54ef4";

// 获取文件流

File file = new File("D:/zookeeper-3.4.8.tar.gz");

// 创建一个容器,传入一个`MongoDatabase`类实例db

GridFSBucket bucket = GridFSBuckets.create(mongoDatabase());

// 创建输出流

OutputStream os = new FileOutputStream(file);

// 下载

bucket.downloadToStream(new ObjectId(objectId), os);

System.out.println("下载完成。");

}

删除文件

@Test

public void delete() throws Exception {

// 获取文件ID

String objectId = "57fbaffcec773716ecc54ef4";

// 创建一个容器,传入一个`MongoDatabase`类实例db

GridFSBucket bucket = GridFSBuckets.create(mongoDatabase());

// 删除

bucket.delete(new ObjectId(objectId));

System.out.println("删除完成。");

}

总结

GridFS是一种大型文件存储方式之一,有其一定的使用场景,务必根据实际场景选择技术方案。

现在主流的文件存储方案,例如云存储服务,以amazon的s3云服务,七牛云存储都是不错的选择。此外,例如还有阿里开源的tair等键值结构数据的解决方案。

java gridfs_GridFS 基于MongoDB的分布式文件存储系统相关推荐

  1. java电商项目搭建-------分布式文件存储系统(fastDFS)

    人之所以痛苦,那是因为你在成长.--------magic_guo 微服务项目,由于访问量和系统的高可用性能,会将上传的文件图片等存放在搭建的分布式文件存储系统:现在比较流行的文件存储系统有fastD ...

  2. 如何基于.NET Core构建分布式文件存储系统?

    最近被安排开发文件存储微服务,要求是能够通过配置来无缝切换我们公司内部研发的文件存储系统,FastDFS,MongDb GridFS,阿里云OSS,腾讯云OSS等.根据任务紧急度暂时先完成了通过配置来 ...

  3. 盘点分布式文件存储系统____分布式文件存储系统简介

    盘点分布式文件存储系统 在项目的数据存储中,结构化数据通常采用关系型数据库,非结构化数据(文件)的存储就有很多种方式,服务器本地存储.Nas挂载.ftp等等,今天就来盘点一下,分布式文件存储系统. 一 ...

  4. Day134-136.尚品汇:平台属性接口、SPU、跨域问题、配置持久化、MinIO 分布式文件存储系统

    目录 Day 02 商品后台管理系统 1. 商品基本知识 2. 回顾Mybatis 3. 添加平台属性接口 (多表查询) Day 03 完成后台平台属性管理.SPU 1. 修改平台属性 2. gate ...

  5. 分布式文件存储系统Minio使用总结

    分布式文件存储系统Minio使用总结 1.分布式文件系统应用: 1.1.Minlo 介绍: Minlo 是一个基于Apache License v2.0开源协议的对象存储服务.它兼容亚马逊S3云存储服 ...

  6. 分布式文件存储系统MinIO笔记

    文章目录 一.MinIO介绍 1.文件系统应用场景 2.MinIO介绍 3.MinIO优点 4.MinIO的基础概念 5.纠删码EC(Erasure Code) 6.存储形式 7.存储方案 二.Min ...

  7. 大数据开发:分布式文件存储系统简介

    在分布式存储技术体系当中,分布式文件存储是其中的分类之一,也是大数据架构当中常常用到的.得益于Hadoop的高人气,Hadoop原生的HDFS分布式文件系统,也广泛为人所知.但是分布式文件存储系统,并 ...

  8. day36~37_HDFS分布式文件存储系统

    HDFS分布式文件存储系统 一.HDFS概述 (一)HDFS产生背景 随着数据量越来越大,在一个文件系统下无法存储海量数据,普通硬件支持的操作系统即使扩展磁盘也会遇到瓶颈,迫切需要水平横向扩展来解决数 ...

  9. fastdfs安装_用asp.net core结合fastdfs打造分布式文件存储系统

    今天主要是对开发过程,以及对FastDFS这个通用的分布式文件存储服务的单机及集群安装部署过程做个总结.希望对想要自建分布式文件系统的朋友有所帮助. 什么是FastDFS 这里先简单介绍下分布式文件存 ...

最新文章

  1. gin context和官方context_gin 源码阅读(一) -- 启动
  2. spring依赖注入原理(转载)
  3. 神策数据荣登 2020 IDC 中国 Fintech 50 强榜单
  4. ElasticSearch搜索引擎常见面试题总结
  5. 集群系统 刀片服务器,刀片服务器集群原理
  6. mysql数据库进行更新、插入显示中文乱码问题
  7. linux磁盘管理不用LVM,[linux] LVM磁盘管理(针对xfs和ext4不同文件系统)
  8. c语言 数组指针传递给函数_嵌入式开发-C语言-指针与数组
  9. 美国的知名的人工智能研究机构或者实验室
  10. iframe标签用法详解
  11. CSS运用中所体会到的方法
  12. 如何把设计稿转换成html,将设计稿转换成WEB页面职业者
  13. 双显示器如何设置上下显示和鼠标上下进入第二屏幕?
  14. highcharts特殊定制:x轴文字竖直显示(兼容各浏览器)
  15. 英雄算法联盟 - 六月集训排行榜 (截止今日第31天)
  16. python中del什么意思_python del函数是什么以及如何使用?
  17. 几则小故事(网上收集)
  18. python知识点智能问答_基于检索的智能问答
  19. node.js使用Sequelize实现多表连接查询
  20. PilotPi:树莓派运行PX4配置方法

热门文章

  1. Ubuntu系统安装ifort编译器
  2. 阿里这么牛逼,Leader是如何带兵打仗的?
  3. 电商用户购买行为预测-排名48-0.23
  4. 分布式session
  5. 【漏洞学习——XSS】Destoon B2B网站管理系统存储xss
  6. 修改ubuntu docker timezone
  7. 力扣226:反转二叉树
  8. python实现二叉树翻转_如何从左到右反转二叉树?
  9. grafana mysql demo_通过官网模板轻松实现Grafana的可视化界面配置(以MySQL监控项为例)...
  10. Android使用WCDB+Room 总结