精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

基于Mongodb的分布式文件存儲實現

存儲 存儲架構
基于 MongoDB GridFS 的分布式文件存儲方案,憑借其獨特的文件分塊存儲原理和與 MongoDB 分布式架構的緊密結合,為我們提供了一種高效、可靠的文件存儲方式。

基于mongo GridFS實現文件上傳下載

分布式文件存儲的方案有很多,今天分享一個基于mongodb數據庫來實現文件的存儲,mongodb支持分布式部署,以此來實現文件的分布式存儲。

基于 MongoDB GridFS 的分布式文件存儲實現:從原理到實戰

一、引言

當系統存在大量的圖片、視頻、文檔等文件需要存儲和管理時,對于分布式系統而言,如何高效、可靠地存儲這些文件是一個關鍵問題。MongoDB 的 GridFS 作為一種分布式文件存儲機制,為我們提供了一個優秀的解決方案。它基于 MongoDB 的分布式架構,能夠輕松應對海量文件存儲的挑戰,同時提供了便捷的文件操作接口。

二、GridFS 原理剖析

GridFS 是 MongoDB 中用于存儲大文件的一種規范。它將文件分割成多個較小的 chunks(默認大小為 256KB),并將這些 chunks 存儲在 fs.chunks 集合中,而文件的元數據(如文件名、大小、創建時間、MIME 類型等)則存儲在 fs.files 集合中。這樣的設計不僅能夠突破 MongoDB 單個文檔大小的限制(默認 16MB),還能利用 MongoDB 的分布式特性,實現文件的分布式存儲和高效讀取。

例如,當我們上傳一個 1GB 的視頻文件時,GridFS 會將其切分為約 4096 個 256KB 的 chunks,然后將這些 chunks 分散存儲在不同的 MongoDB 節點上,同時在 fs.files 集合中記錄文件的相關信息。

三、Spring Boot 集成 GridFS

在實際項目中,我們通常使用 Spring Boot 與 MongoDB 結合,下面是具體的集成步驟與代碼示例。

3.1 添加依賴

在 pom.xml 文件中添加 Spring Boot 與 MongoDB 相關依賴:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

3.2 配置 MongoDB 連接

在 application.properties 中配置 MongoDB 的連接信息:

spring.data.mongodb.uri=mongodb://localhost:27017/fs
spring.data.mongodb.database=fs

3.3 編寫服務類

使用 GridFsTemplate 和 GridFSBucket 來實現文件的上傳、下載、刪除等操作:

@Service
publicclass MongoFsStoreService implements FsStoreService {

    privatefinal GridFsTemplate gridFsTemplate;

    private GridFSBucket gridFSBucket;

    public MongoFsStoreService(GridFsTemplate gridFsTemplate) {
        this.gridFsTemplate = gridFsTemplate;
    }

    @Autowired(required = false)
    public void setGridFSBucket(GridFSBucket gridFSBucket) {
        this.gridFSBucket = gridFSBucket;
    }

    /**
     * 上傳文件
     * @param in
     * @param fileInfo
     * @return
     */
    @Override
    public FileInfo uploadFile(InputStream in, FileInfo fileInfo){
        ObjectId objectId = gridFsTemplate.store(in, fileInfo.getFileId(), fileInfo.getContentType(), fileInfo);
        fileInfo.setDataId(objectId.toString());
        return fileInfo;
    }

    /**
     *
     * @param in
     * @param fileName
     * @return
     */
    @Override
    public FileInfo uploadFile(InputStream in, String fileName) {
        FileInfo fileInfo = FileInfo.fromStream(in, fileName);
        return uploadFile(in, fileInfo);
    }

    /**
     *
     * @param fileId
     * @return
     */
    @Override
    public File downloadFile(String fileId){
        GridFsResource gridFsResource = download(fileId);
        if( gridFsResource != null ){
            GridFSFile gridFSFile = gridFsResource.getGridFSFile();
            FileInfo fileInfo = JsonHelper.convert(gridFSFile.getMetadata(), FileInfo.class);

            try(InputStream in = gridFsResource.getInputStream()) {
                return FileHelper.newFile( in, fileInfo.getFileId() ); //
            } catch (IOException e) {
                thrownew RuntimeException(e);
            }
        }
        returnnull;
    }

    /**
     * 查找文件
     * @param fileId
     * @return
     */
    public GridFsResource download(String fileId) {
        GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(GridFsCriteria.whereFilename().is(fileId)));
        if (gridFSFile == null) {
            returnnull;
        }

        if( gridFSBucket == null ){
            return gridFsTemplate.getResource(gridFSFile.getFilename());
        }
        GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
        returnnew GridFsResource(gridFSFile, downloadStream);
    }

    /**
     * 刪除文件
     * @param fileId
     */
    @Override
    public void deleteFile(String fileId) {
        gridFsTemplate.delete(Query.query(GridFsCriteria.whereFilename().is(fileId)));
    }

}

3.4 創建控制器

提供 REST API 接口,方便外部調用:

@RestController
@RequestMapping("/mongo")
publicclass MongoFsStoreController {

    privatefinal MongoFsStoreService mongoFsStoreService;

    public MongoFsStoreController(MongoFsStoreService mongoFsStoreService) {
        this.mongoFsStoreService = mongoFsStoreService;
    }

    /**
     *
     * @param file
     * @return
     */
    @RequestMapping("/upload")
    public ResponseEntity<Result> uploadFile(@RequestParam("file") MultipartFile file){
        try(InputStream in = file.getInputStream()){
            FileInfo fileInfo = convertMultipartFile(file);
            return ResponseEntity.ok( Result.ok(mongoFsStoreService.uploadFile(in, fileInfo)) );
        }catch (Exception e){
            return ResponseEntity.ok( Result.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()) );
        }
    }

    private FileInfo convertMultipartFile(MultipartFile file){
        FileInfo fileInfo = new FileInfo();
        fileInfo.setType(FilenameUtils.getExtension(file.getOriginalFilename()));
        fileInfo.setFileId(UUID.randomUUID().toString() + "." + fileInfo.getType()); //
        fileInfo.setFileName(file.getOriginalFilename());
        fileInfo.setSize(file.getSize());
        fileInfo.setContentType(file.getContentType());
        fileInfo.setCreateTime(new Date());
        return fileInfo;
    }

    /**
     *
     * @param fileId
     * @param response
     */
    @RequestMapping("/download")
    public void downloadFile(@RequestParam("fileId") String fileId, HttpServletResponse response){
        File file = mongoFsStoreService.downloadFile(fileId);
        if( file != null ){
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
            try {
                FileUtils.copyFile(file, response.getOutputStream());
            } catch (IOException e) {
                thrownew RuntimeException(e);
            }
        }
    }

    @RequestMapping("/download/{fileId}")
    public ResponseEntity<InputStreamResource> download(@PathVariable("fileId") String fileId) throws IOException {
        GridFsResource resource = mongoFsStoreService.download(fileId);
        if( resource != null ){
            GridFSFile gridFSFile = resource.getGridFSFile();
            FileInfo fileInfo = JsonHelper.convert(gridFSFile.getMetadata(), FileInfo.class);

            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileInfo.getFileName() + "\"")
                    .contentLength(fileInfo.getSize())
//                    .contentType(MediaType.parseMediaType(fileInfo.getContentType()))
                    .body(new InputStreamResource(resource.getInputStream()));
        }
//        return ResponseEntity.noContent().build();
        return ResponseEntity.internalServerError().build();
    }

    /**
     *
     * @param fileId
     * @return
     */
    @RequestMapping("/delete")
    public ResponseEntity<String> deleteFile(@RequestParam("fileId") String fileId){
        mongoFsStoreService.deleteFile(fileId);
        return ResponseEntity.ok("刪除成功");
    }

四、實戰中的常見問題與解決方案

4.1 文件下載時的內存管理

在下載文件時,GridFSDownloadStream 提供了流式處理的能力,避免一次性將整個文件加載到內存中。我們可以通過 GridFsResource 將流包裝后直接返回給客戶端,實現邊讀邊傳,從而節省內存。例如:

// 正確:直接返回 InputStreamResource,邊讀邊傳
return ResponseEntity.ok()
       .body(new InputStreamResource(resource.getInputStream()));

而應避免將整個文件讀取到字節數組中再返回,如以下錯誤示例:

// 錯誤:將整個文件加載到內存再返回
byte[] content = resource.getInputStream().readAllBytes(); 
return ResponseEntity.ok()
       .body(content);

五、總結

基于 MongoDB GridFS 的分布式文件存儲方案,憑借其獨特的文件分塊存儲原理和與 MongoDB 分布式架構的緊密結合,為我們提供了一種高效、可靠的文件存儲方式。通過 Spring Boot 的集成,我們能夠快速在項目中實現文件的上傳、下載、查詢和刪除等功能。在實際應用過程中,我們需要關注內存管理、數據類型轉換、時間類型處理等常見問題,并采用合適的解決方案。隨著技術的不斷發展,GridFS 也在持續優化和完善,將為更多的分布式文件存儲場景提供強大的支持。

對于中小文件存儲,GridFS 是一個簡單高效的選擇;對于超大規模文件或需要極致性能的場景,可以考慮結合對象存儲(如 MinIO、S3)使用。

責任編輯:武曉燕 來源: Java技術指北
相關推薦

2010-09-09 08:42:28

MongoDB

2017-04-13 10:51:09

Consul分布式

2017-10-17 08:33:31

存儲系統分布式

2022-10-27 10:44:14

分布式Zookeeper

2017-07-18 09:51:36

文件存儲系統

2013-08-29 13:46:18

MongoDBSession.Net

2017-10-27 08:40:44

分布式存儲剪枝系統

2020-09-27 06:52:22

分布式存儲服務器

2009-06-19 14:23:41

RMIJava分布式計算

2023-01-06 09:19:12

Seata分布式事務

2017-05-11 14:05:25

Consul分布式信號量

2015-04-21 09:39:03

javajava分布式爬蟲

2017-10-24 11:28:23

Zookeeper分布式鎖架構

2024-08-12 16:20:27

2015-05-12 13:03:54

開源分布式存儲HDFS

2018-02-22 08:42:04

分布式存儲安全

2022-11-06 19:28:02

分布式鎖etcd云原生

2018-10-29 12:51:35

分布式存儲元數據

2021-10-22 05:42:38

分布式存儲三副本系統

2015-07-02 13:26:35

分布式存儲云存儲云平臺
點贊
收藏

51CTO技術棧公眾號

久久国产精品无码网站| 你懂的视频欧美| 尤物av一区二区| 99久久精品免费看国产一区二区三区| 校园春色 亚洲| 日韩av网址大全| 欧美亚洲免费在线一区| 超碰97在线看| 瑟瑟在线观看| 狠狠色狠狠色综合日日91app| 欧美激情免费视频| 亚洲精品色午夜无码专区日韩| 日韩专区视频| 亚洲午夜电影在线观看| 日韩久久精品一区二区三区| 99国产精品一区二区三区 | 国产福利一区二区三区视频在线| 韩国三级电影久久久久久| 公肉吊粗大爽色翁浪妇视频| 亚洲网址在线观看| 欧美日韩情趣电影| 波多野结衣乳巨码无在线| 麻豆网站在线观看| 国产亚洲一本大道中文在线| 成人在线观看av| 91精品国自产| 日韩av电影天堂| 69av在线视频| 久久久精品一区二区涩爱| 欧美在线观看视频一区| 日韩精品在线视频观看| 久久久久亚洲av无码网站| 88xx成人网| 欧美视频免费在线观看| 成人在线观看你懂的| 亚洲欧美成人影院| 亚洲男人的天堂在线观看| 亚洲国产日韩综合一区| 国产69久久| 久久日一线二线三线suv| 国产九区一区在线| 亚洲AV无码一区二区三区性| 国产在线精品国自产拍免费| 国产精品网红福利| 天堂在线精品视频| 古装做爰无遮挡三级聊斋艳谭| 超碰在线影院| 国产网站一区二区三区| 免费国产一区| 天堂中文资源在线观看| www.一区二区| 国产一区精品在线| 无码精品黑人一区二区三区| 亚洲精品日产| 国产精品视频在线看| 欧美一区二区福利在线| 妺妺窝人体色777777| bt在线麻豆视频| 国产精品美女视频| 亚洲最大免费| 韩国中文字幕在线| 国产精品久99| 在线观看欧美亚洲| 国产三区在线观看| 中文欧美字幕免费| 日韩精品第一页| 国产高清在线看| 中文一区一区三区高中清不卡| 亚洲精品一区二区三区樱花| 性开放的欧美大片| 国产精品久久久久久久久免费樱桃| 日本一区二区三区视频在线播放 | 精品一区二区在线视频| 91精品视频免费| 亚洲第一天堂影院| 97se亚洲国产综合自在线不卡| 精品视频免费观看| 成人高清免费在线播放| 国产精品福利一区二区三区| 亚洲一卡二卡三卡四卡无卡网站在线看| 日本综合在线| 亚洲在线成人精品| 精品国产无码在线| 久久日韩视频| 亚洲成av人影院在线观看网| 欧美 日韩精品| 精品美女一区| 精品国产乱码久久久久久牛牛 | 精品国产伦一区二区三区| 不卡一区在线观看| 日韩精品久久久毛片一区二区| 午夜免费播放观看在线视频| 亚洲制服丝袜在线| 国产精彩免费视频| 亚洲一区二区三区四区电影| 亚洲免费视频一区二区| 国产精品麻豆一区| 99精品免费| 成人欧美一区二区三区在线| 色呦呦中文字幕| 国产精品久久久久久久久图文区| 丰满少妇大力进入| 亚洲美女色播| 亚洲人成电影在线播放| 免费在线视频观看| 青椒成人免费视频| 国产伦精品一区| 看电影就来5566av视频在线播放| 亚洲欧美欧美一区二区三区| 日韩在线视频在线观看| 六九午夜精品视频| 日韩成人久久久| 永久免费看片直接| 亚洲永久免费| 99视频免费观看蜜桃视频| 国产福利在线| 亚洲成人一区在线| www.日本久久| 999久久久91| 国产精品成人国产乱一区| 中文字幕人妻一区| 久久在线视频免费观看| 青草成人免费视频| 欧美视频一二区| 亚洲丝袜精品丝袜在线| 国产一线二线三线在线观看| 欧美黑人巨大videos精品| 久久成人精品视频| 91亚洲欧美激情| 久久精品一区二区| 黑人糟蹋人妻hd中文字幕 | 欧美极品日韩| gogo高清午夜人体在线| 日韩亚洲欧美综合| 亚洲伦理一区二区三区| 奇米色一区二区三区四区| 久久综合九色综合网站| 2021中文字幕在线| 精品成人佐山爱一区二区| 久草国产在线观看| 国产成人综合自拍| 三级在线免费观看| 亚洲午夜国产成人| 欧美成人一区在线| 草逼视频免费看| 一区二区三区av电影| 韩国三级与黑人| blacked蜜桃精品一区| 欧美在线激情视频| 免费一级在线观看| 色94色欧美sute亚洲线路二| 色欲av无码一区二区三区| 国产亚洲精品v| 欧美xxxx黑人又粗又长密月| 亚洲日本天堂| 一区二区三区日韩在线| 中文在线资源天堂| 中文字幕一区av| 欧美xxxxxbbbbb| 黑丝一区二区| 精品国产一区二区三区四区vr| 久久男人av资源站| 亚洲欧洲xxxx| 亚洲无码久久久久| 亚洲精品中文在线影院| 欧洲熟妇的性久久久久久| 日韩视频二区| 午夜一区二区三区| 欧美日韩午夜电影网| 欧美精品成人在线| 深夜福利视频在线免费观看| 精品日韩视频在线观看| 国产男女猛烈无遮挡a片漫画| 久久午夜精品| 在线观看成人免费| 国产精品对白| 国产精品极品尤物在线观看| 国产一区久久精品| 亚洲精品www| 国产精品露脸视频| 亚洲自拍偷拍图区| 国产精久久一区二区三区| 韩国v欧美v日本v亚洲v| 成人毛片100部免费看| 国产伦理久久久久久妇女 | 久久精品影视伊人网| 男人天堂网在线视频| 一本久久精品一区二区| 一区二区国产精品精华液| 99国产一区二区三精品乱码| 向日葵污视频在线观看| 红桃视频亚洲| 亚洲一卡二卡区| 美女午夜精品| 91久久精品国产| 高端美女服务在线视频播放| 亚洲精品mp4| 国产精品久久免费| 欧美午夜激情视频| 免费一级a毛片夜夜看| 国产片一区二区| 国产精久久久久| 蜜桃视频在线观看一区| 成人毛片一区二区| 午夜精品毛片| 日韩福利一区二区三区| 亚洲国产中文在线| 国产精品成人va在线观看| 国产探花视频在线观看| 视频在线观看99| 日韩美女一级视频| 精品国产乱码久久久久久闺蜜 | 日韩欧美一区二区视频在线播放 | 综合激情网五月| 亚洲婷婷综合色高清在线| 最近中文字幕免费视频| 成人高清视频在线观看| 黄色一级片免费播放| 免费观看在线色综合| 欧美丰满熟妇bbbbbb百度| 欧美片第1页综合| 国产又大又长又粗又黄| 精品久久美女| 欧美xxxx黑人又粗又长密月| 都市激情久久| 成人黄色生活片| 黄页免费欧美| 国产精品美女久久久免费| 在线看片福利| 韩国国内大量揄拍精品视频| 午夜激情在线| 日韩网站在线观看| 高清日韩av电影| 亚洲色图50p| 青青久草在线| 精品五月天久久| 手机福利在线| 亚洲美女中文字幕| 你懂的在线看| 亚洲视频777| 男女污污视频在线观看| 亚洲精品999| 天天插天天干天天操| 精品欧美一区二区久久| av免费观看网址| 欧美一区二区人人喊爽| av在线资源观看| 日韩欧美一级片| 黑人乱码一区二区三区av| 精品99久久久久久| 神马午夜一区二区| 日韩大片免费观看视频播放| 天堂av在线播放| 亚洲欧洲偷拍精品| eeuss影院www在线播放| 最近免费中文字幕视频2019| www黄在线观看| 日韩一区二区三区xxxx| caoporn免费在线视频| 久久国产精品久久久| 欧美xxxx免费虐| 91av视频在线免费观看| 国模套图日韩精品一区二区| 国产精品成人aaaaa网站| 欧美成人高清视频在线观看| 91深夜福利视频| 第四色在线一区二区| 久久久久久国产精品免费免费| 亚州av一区| 欧美亚洲另类在线一区二区三区| 欧洲视频一区| 日韩精品在在线一区二区中文| 91麻豆精品国产91久久久平台| 亚洲色图都市激情| 亚洲美女色禁图| 999在线免费视频| 国产一区二区三区综合| 国产精品一区二区人妻喷水| 久久久久久久精| 永久av免费网站| 亚洲成av人片一区二区| 天天综合久久综合| 91精品国产综合久久福利| 神马午夜电影一区二区三区在线观看| 亚洲三级av在线| a级片国产精品自在拍在线播放| 欧美激情久久久| 高清av一区| 国产精品免费在线| 欧美色图一区| 欧美一级免费播放| 美女www一区二区| 一本色道久久hezyo无码| 亚洲国产精品传媒在线观看| 九九热精彩视频| 色噜噜狠狠色综合欧洲selulu| 国产女人高潮毛片| 国产婷婷97碰碰久久人人蜜臀 | 91精品国产91久久久久| 国产伊人久久| 久久精品国产综合精品| 国产精品福利在线观看播放| 黄页免费在线观看视频| 精品一区二区三区久久| 丝袜美腿中文字幕| 一区二区不卡在线视频 午夜欧美不卡在| 国产婷婷色一区二区在线观看| 欧美一区二区三区不卡| 男同在线观看| 久久全球大尺度高清视频| 六九午夜精品视频| 日韩精品国内| 一本色道久久| jjzz黄色片| 亚洲色图都市小说| 成人黄色免费网| 亚洲欧美日韩区| а√天堂中文资源在线bt| 91精品视频网站| 久久视频国产| 波多野结衣天堂| 久久久久久久久久看片| 国产精品7777777| 日韩欧美国产午夜精品| 黄色精品免费看| 国产精品一香蕉国产线看观看| 日韩系列在线| 国模无码视频一区二区三区| 东方欧美亚洲色图在线| 少妇aaaaa| 欧美日韩成人综合在线一区二区| 精品视频二区| 51久久精品夜色国产麻豆| 粉嫩av一区二区| 欧美国产视频一区| 国产成人在线观看免费网站| 午夜免费激情视频| 91麻豆精品国产91久久久使用方法 | 熟女熟妇伦久久影院毛片一区二区| 久久亚洲欧洲| 一级黄色片大全| 欧美日韩国产在线看| 婷婷伊人综合中文字幕| 国产69精品久久久久99| 国产精品天天看天天狠| 国产精品久久国产| 成人激情校园春色| 日韩少妇裸体做爰视频| 亚洲国产精品资源| 亚洲一区资源| 日韩美女一区| 麻豆国产欧美日韩综合精品二区| 秋霞网一区二区三区| 欧美精选在线播放| a免费在线观看| 国产伦精品一区二区三区四区免费 | 黄色av网址在线| 91精品国产电影| 中国av一区| 中文字幕网av| 亚洲视频免费在线| 国产成人自拍一区| 欧美亚洲第一区| 成人同人动漫免费观看| 久久成年人网站| 亚洲一区二区3| 欧美挠脚心网站| 国产精品美女免费看| 99精品视频在线观看播放| 古装做爰无遮挡三级聊斋艳谭| 亚洲3atv精品一区二区三区| 牛牛澡牛牛爽一区二区| 国产日韩综合一区二区性色av| 综合日韩在线| 亚洲调教欧美在线| 欧美色手机在线观看| 91蜜桃在线视频| 久久成人资源| 男人的j进女人的j一区| 久久久精品99| 亚洲欧美在线磁力| 青青伊人久久| 大伊香蕉精品视频在线| 久久人人超碰精品| 国产视频在线观看视频| 91精品国产色综合久久不卡98口| 亚州av日韩av| 杨幂一区二区国产精品| 欧美性猛交xxxx免费看漫画| 美女黄视频在线观看| 激情小说综合网| 精品在线播放免费| 亚洲不卡视频在线观看| 久久亚洲成人精品| 丝袜美腿综合| 中文字幕第三区| 在线视频欧美精品| 大桥未久在线播放| 亚洲欧洲免费无码| 91免费国产在线观看|