对象存储工具分享 | 豆包MarsCode AI 刷题

155 阅读3分钟

要求必须有一篇工具实用类文章分享,那我就分享个存储工具吧,因为最好写(不是

存储系统的分类

  • 单机存储
  • 单机数据库
  • 分布式数据库
  • 分布式存储

对于我们存储视频,图片,音频这类的需求,我们需要找到适合存储这类数据且海量支持的存储系统,在所有的存储系统中,显然分布式存储是最合适的

分布式存储选型

  • 分布式文件系统
  • 对象存储
海量易用便宜
分布式文件系统支持PB->EB海量存储,文件数量收Name Node限制开发略复杂,非云原生使用普通x86服务器,成本低
对象存储支持PB->EB海量存储,对象数量无限制Restful Http接口,开发简单,生态丰富使用普通x86服务器,具备冷热数据分级存储能力,成本更低

通过上面的对比,针对需求,我们自然而然的选择了对象存储~~

对象存储概览

Snipaste_2024-11-30_15-38-41.png

  • Bucket:存储对象的桶
  • Object:对象
    • Key:对象名
    • Data:对象内容
    • MetaData:对象元信息(对象大小,Content-Type等)

具体实现

对象存储很多厂商都支持,像阿里的OSS,腾讯COS,字节的TOS等,当然都是收费的  ̄ _  ̄

作为一名囊中羞涩的大学生,我果断选择了Minio︿( ̄︶ ̄)︿

Minio

MinIO 是一款号称世界上速度最快的对象存储服务,专为大规模数据存储和分析而设计。支持在各种环境中部署,包括物理服务器、虚拟机、容器等,最关键的是它的技术文档非常完善,非常容易上手;同时,对个人用户是完全开源免费的。

MinIO官网

根据官方文档的提示,在服务器上安装好Minio后,可以通过访问http://ip:9090访问到Minio服务控制台

Snipaste_2024-11-30_15-51-05.png

不同版本的Minio控制台UI可能不同

默认用户名密码:minioadmin / minioadmin

创建桶

Snipaste_2024-11-30_15-53-15.png

点击创建桶输入合适的桶名称即可

Snipaste_2024-11-30_15-58-10.png

在页面上可以看到我们创建的所有桶,对于新创建的桶可以点击Manage把桶的访问策略改成Public,这样我们往里面上传文件,所有人通过网址都能正常访问了

Java实现

获取api访问凭证

Snipaste_2024-11-30_17-45-29.png

引入依赖

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.2.1</version>
</dependency>

配置文件

minio:
  endpoint: http://81.70.144.36:9000
  accesskey: your accesskey
  secretkey: your accesskey
  bucket: your bucket

创建客户端

@Data
@Component
@ConfigurationProperties(prefix = "minio")
@Configuration
public class MinioConfig {

    private String endpoint;
    private String accessKey;
    private String secretKey;
    private String bucket;

    @Bean
    public MinioClient minioClient() {
        //构建MinioClient
        return MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey,secretKey)
                .build();
    }
}

然后我们就可以利用MinioClient来对桶中文件进行操作了,具体api调用参照官方文档Minio Java API

这里浅浅贴个普通上传文件的代码吧

/**
 * 单文件上传
 *
 * @param file 文件
 * @return Boolean
 */
public String upload(MultipartFile file) {
    String type = FileUtil.extName(file.getOriginalFilename());
    String name = UUID.randomUUID().toString(true).substring(0, 20) + StrUtil.DOT + type;
    String path = DateUtil.format(LocalDateTime.now(), "yyyy/MM/") + name;
    try {
        PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(config.getBucket()).object(path)
                .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
        //文件名称相同会覆盖
        minioClient.putObject(objectArgs);
    } catch (Exception e) {
        log.error(e.getMessage());
        return null;
    }
    return config.getEndpoint() + "/" + config.getBucket() + "/" + path;
}