MongoDB GridFS 将文件大小增加了三倍

app*_*l3r 5 mongodb files mongodb-3.6

我真的很喜欢使用 mongodb 来存储我的数据,最近我尝试了 GridFS,它确实适合我的用例。

我的问题是空间要求,这看起来很奇怪。我在 Amazon S3 中有大约 107GB 的图像,大约有 100 万个文件(所有图像,大部分是小图像)。我制作了一个简单的 Java 项目,从 S3 下载图像并将它们插入到两个单独的 MongoDB GridFS 集合(单服务器、3.6.5、64 位、Windows Server 2016)中。问题是,当上传/下载完成时,GridFS 集合在服务器上占用超过 300GB 的存储空间。对于此类收藏来说,这是可以接受的还是我应该担心三倍的尺寸?

注意:我只是使用 Java Mongo 驱动程序(Spring Boot)插入图像,没有任何重大更改,问题出在图像块上。我不删除或更新任何图像(不过,我为 MD5 字段定义了唯一索引,以忽略图像重复),因此压缩和修复不会更改集合大小。据我所知,集合并没有过度预分配(我不认为我的问题与此类似:Huge size on mongodb's gridfs. Should I Compact?

此外,目前它是单个 mongodb 服务器,没有副本集。

非常感谢您的帮助!

war*_*yen -1

将 MongoDB Java 驱动程序依赖项添加到项目的 pom.xml 文件中:

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>4.4.2</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

在应用程序配置类中创建 MongoDB 客户端 bean:

@Configuration
public class MongoConfig {

    @Value("${spring.data.mongodb.uri}")
    private String mongoUri;

    @Bean
    public MongoClient mongoClient() {
        ConnectionString connectionString = new ConnectionString(mongoUri);
        MongoClientSettings settings = MongoClientSettings.builder()
                .applyConnectionString(connectionString)
                .build();
        return MongoClients.create(settings);
    }

    @Bean
    public MongoDatabase mongoDatabase(MongoClient mongoClient) {
        return mongoClient.getDatabase("your_database_name");
    }
}
Run Code Online (Sandbox Code Playgroud)

定义一个服务类来处理 GridFS 操作:

@Service
public class GridFsService {

    private final MongoDatabase mongoDatabase;
    private final GridFSBucket gridFSBucket;

    public GridFsService(MongoDatabase mongoDatabase) {
        this.mongoDatabase = mongoDatabase;
        this.gridFSBucket = GridFSBuckets.create(mongoDatabase);
    }

    public ObjectId uploadFile(String filename, InputStream inputStream, String contentType) throws IOException {
        GridFSUploadOptions options = new GridFSUploadOptions()
                .chunkSizeBytes(256 * 1024) // Set the desired chunk size
                .metadata(new Document("contentType", contentType)); // Set additional metadata if needed

        return gridFSBucket.uploadFromStream(filename, inputStream, options);
    }

    public GridFSDownloadStream downloadFile(ObjectId fileId) {
        return gridFSBucket.openDownloadStream(fileId);
    }
}
Run Code Online (Sandbox Code Playgroud)

在应用程序逻辑中使用 GridFsService 来上传和下载文件:

@Service
public class YourService {

    private final GridFsService gridFsService;

    public YourService(GridFsService gridFsService) {
        this.gridFsService = gridFsService;
    }

    public void uploadFile(MultipartFile file) throws IOException {
        try (InputStream inputStream = file.getInputStream()) {
            gridFsService.uploadFile(file.getOriginalFilename(), inputStream, file.getContentType());
        }
    }

    public InputStream downloadFile(ObjectId fileId) {
        GridFSDownloadStream downloadStream = gridFsService.downloadFile(fileId);
        return downloadStream.getInputStream();
    }
}
Run Code Online (Sandbox Code Playgroud)