要求必须有一篇工具实用类文章分享,那我就分享个存储工具吧,因为最好写(不是
存储系统的分类
- 单机存储
- 单机数据库
- 分布式数据库
- 分布式存储
对于我们存储视频,图片,音频这类的需求,我们需要找到适合存储这类数据且海量支持的存储系统,在所有的存储系统中,显然分布式存储是最合适的
分布式存储选型
- 分布式文件系统
- 对象存储
| 海量 | 易用 | 便宜 | |
|---|---|---|---|
| 分布式文件系统 | 支持PB->EB海量存储,文件数量收Name Node限制 | 开发略复杂,非云原生 | 使用普通x86服务器,成本低 |
| 对象存储 | 支持PB->EB海量存储,对象数量无限制 | Restful Http接口,开发简单,生态丰富 | 使用普通x86服务器,具备冷热数据分级存储能力,成本更低 |
通过上面的对比,针对需求,我们自然而然的选择了对象存储~~
对象存储概览
- Bucket:存储对象的桶
- Object:对象
- Key:对象名
- Data:对象内容
- MetaData:对象元信息(对象大小,Content-Type等)
具体实现
对象存储很多厂商都支持,像阿里的OSS,腾讯COS,字节的TOS等,当然都是收费的  ̄ _  ̄
作为一名囊中羞涩的大学生,我果断选择了Minio︿( ̄︶ ̄)︿
Minio
MinIO 是一款号称世界上速度最快的对象存储服务,专为大规模数据存储和分析而设计。支持在各种环境中部署,包括物理服务器、虚拟机、容器等,最关键的是它的技术文档非常完善,非常容易上手;同时,对个人用户是完全开源免费的。
根据官方文档的提示,在服务器上安装好Minio后,可以通过访问http://ip:9090访问到Minio服务控制台
不同版本的Minio控制台UI可能不同
默认用户名密码:minioadmin / minioadmin
创建桶
点击创建桶输入合适的桶名称即可
在页面上可以看到我们创建的所有桶,对于新创建的桶可以点击Manage把桶的访问策略改成Public,这样我们往里面上传文件,所有人通过网址都能正常访问了
Java实现
获取api访问凭证
引入依赖
<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;
}