Minio 上传下载文件除了需要 Bucket 还需要指定文件名,其中文件名可以是一个包含 Path 的文件名,例如 fileName
可以是 1/2/3/4/5.jpg
也可以是 5.jpg
。其 API 有:
// 上传
minioClient.putObject(bucket, fileName, inputStream, file.length(), contentType);
// 下载
minioClient.getObject(bucket, fileName);
最近同事老是讨论 Minio 上传下载路径规划,我就比较好奇多层 Path 是否对性能有影响,于是本地测试了一下多层 Path,和单层 Path 是否对 Minio 上传下载有性能影响。简单编写了如下程序。使用一张 3KB 的图片进行上传下载,程序主要区别点在于是否是多层 Path 的控制,其中多层 Path 用:1/2/3/4/5.jpg
,单层 Path 用: 5.jpg
。
public static void main(String[] args) throws Exception {
String endPoint = "http://192.168.38.68:9000";
String userName = "minio";
String password = "minio";
String bucket = "test";
String fileName = "C:\\Users\\14345\\Pictures\\3_qq_24598601.jpg"; // 3KB
String mulPath = "1/2/3/4/5.jpg";
String singlePath = "5.jpg";
String contentType = "image/jpg";
int number = 200;
MinioClient minioClient = new MinioClient(endPoint, userName, password);
File file = new File(fileName);
long writeTime = 0;
int count = number;
while (count-- > 0) {
try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
long writeStartTime = System.currentTimeMillis();
minioClient.putObject(bucket, mulPath, inputStream, file.length(), contentType);
long writeEndTime = System.currentTimeMillis();
writeTime += writeEndTime - writeStartTime;
} catch (Exception e) {
LOGGER.error("upload error!", e);
}
}
System.out.println("多层上传文件" + number + "次耗时:" + writeTime + " ms");
writeTime = 0;
count = number;
while (count-- > 0) {
try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
long writeStartTime = System.currentTimeMillis();
minioClient.putObject(bucket, singlePath, inputStream, file.length(), contentType);
long writeEndTime = System.currentTimeMillis();
writeTime += writeEndTime - writeStartTime;
} catch (Exception e) {
LOGGER.error("upload error!", e);
}
}
System.out.println("单层上传文件" + number + "次耗时:" + writeTime + " ms");
InputStream inputStream = null;
count = number;
long readStartTime = System.currentTimeMillis();
while (count-- > 0) {
inputStream = minioClient.getObject(bucket, mulPath);
}
long readEndTime = System.currentTimeMillis();
inputStream = null;
System.out.println("多层读取文件" + number + "次耗时:" + (readEndTime - readStartTime) + " ms");
count = number;
readStartTime = System.currentTimeMillis();
while (count-- > 0) {
inputStream = minioClient.getObject(bucket, singlePath);
}
readEndTime = System.currentTimeMillis();
inputStream = null;
System.out.println("单层读取文件" + number + "次耗时:" + (readEndTime - readStartTime) + " ms");
}
先多次执行后,再通过修改 number
变量多次执行程序,输出结果如下:
第一次执行程序:
多层上传文件10次耗时:1229 ms
单层上传文件10次耗时:761 ms
多层读取文件10次耗时:416 ms
单层读取文件10次耗时:426 ms
第二次执行程序:
多层上传文件10次耗时:1377 ms
单层上传文件10次耗时:731 ms
多层读取文件10次耗时:394 ms
单层读取文件10次耗时:424 ms
第三次执行程序:
多层上传文件10次耗时:1161 ms
单层上传文件10次耗时:924 ms
多层读取文件10次耗时:414 ms
单层读取文件10次耗时:440 ms
第四次执行程序:
多层上传文件100次耗时:9645 ms
单层上传文件100次耗时:8434 ms
多层读取文件100次耗时:4078 ms
单层读取文件100次耗时:4037 ms
第五次执行程序:
多层上传文件100次耗时:9120 ms
单层上传文件100次耗时:7706 ms
多层读取文件100次耗时:4227 ms
单层读取文件100次耗时:4198 ms
第六次执行程序:
多层上传文件100次耗时:9293 ms
单层上传文件100次耗时:7732 ms
多层读取文件100次耗时:4179 ms
单层读取文件100次耗时:4144 ms
第七次执行程序:
多层上传文件200次耗时:18375 ms
单层上传文件200次耗时:15072 ms
多层读取文件200次耗时:8278 ms
单层读取文件200次耗时:8054 ms
第八次执行程序:
多层上传文件200次耗时:18771 ms
单层上传文件200次耗时:15892 ms
多层读取文件200次耗时:8309 ms
单层读取文件200次耗时:8343 ms
第九次执行程序:
多层上传文件200次耗时:18746 ms
单层上传文件200次耗时:17699 ms
多层读取文件200次耗时:8324 ms
单层读取文件200次耗时:8145 ms
对应上述结果绘制了如下统计表:
通过对统计表分析得出下图(不同 Path 层下写文件耗时统计图):
通过对统计表分析得出下图(不同 Path 层下读文件耗时统计图):
从上可以看出,在读写的文件大小相同时,Path 层数对 Minio 写文件是有一定影响的,但影响不大,并且随着上传文件的次数的增长上传耗时也会随之增长,而对与 Minio 读文件基本是无影响的。
进一步分析同一 Path 层数下读写文件耗时统计图,如下所示:
通过上述分析的同一 Path 层数下读写文件耗时统计图可以看出在相同文件大小和同一 Path 层数的前提下,读写次数对读写的性能的基本上是线性递增的。
综上所述,通过从 Minio 上传文件或下载文件,在文件大小相同的情况下,在上传文件时,多层 Path 设计相对于单层 Path 对性能有一定影响,在 Path 层数一定的前提下是呈线性递增的;而在下载文件时,多层 Path 和 单层 Path 对性能的影响基本一样。