当前位置: 首页 > news >正文

minio下载文件速度很慢的原因分析与说明

文章目录

  • 1.实战背景
  • 2.问题描述
  • 3.问题分析
  • 4.问题解决

1.实战背景

最近在做一个项目,需要用到minio来搭建文件系统,先简单说一下我在项目中设置的上传文件流程:

  1. 前端将分块文件逐一传给后端,后端再存储到 linux服务器的minio 当中。
  2. 所有分块文件存储完毕,后端从 minio 下载所有的分块文件到本地磁盘中。
  3. 后端进行合并文件处理,将合并后的文件通过上传到minio(SDK-Minio Java Client有自带分块上传方法)

我在当前的项目开发阶段,java后端服务是直接在本地进行运行,而minio服务则是在购买的轻量服务器中运行

2.问题描述

在上传文件流程的过程二中,我发现一个2MB的分块文件下载到本地磁盘需要两到三秒,而一个大文件肯定会有许多分块文件,这就导致了当前端向后端发送合并文件请求,后端需要花费大量的时间来处理,主要就是花费在了从Minio下载分块文件到本地磁盘上。

  • 一方面导致前端请求超时,无法获取到后端的处理后结果。
  • 另一方面长时间的等待后端处理,严重影响了用户的体验。

image-20230211033601239

3.问题分析

1️⃣ 首先我怀疑是使用的服务器本身性能的问题,于是又换了一个新的服务器(6Mbps宽带)用来只运行minio服务,然后发现没卵用,分块文件下载到本地速度还是一样慢。

2️⃣ 然后我做了许多的demo来进行下载测试,在这里我给出比较有代表性的测试案例:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.6.3</version>
</dependency>
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.3.0</version>
</dependency>
<dependency><groupId>me.tongfei</groupId><artifactId>progressbar</artifactId><version>0.5.3</version>
</dependency>
<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.8.1</version>
</dependency>
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import org.apache.tomcat.util.http.fileupload.IOUtils;import java.io.FileOutputStream;
import java.io.InputStream;/*** @author 狐狸半面添* @create 2023-02-11 3:47*/
public class MinioFileDownLoadTest {private final static MinioClient minioClient;static {minioClient = MinioClient.builder()// 指定连接的ip和端口(轻量服务器).endpoint("http://1.14.94.100:9000")// 指定 访问秘钥(也称用户id) 和 私有秘钥(也称密码).credentials("admin", "12345678").build();}public static void main(String[] args) throws Exception {// 平均用时:14036mstest01();}public static void test01() throws Exception {Long start = System.currentTimeMillis();// 拿到输入流,我存放在minio的该文件为 10.1 MB 大小InputStream inputStream = minioClient.getObject(GetObjectArgs.builder().bucket("waveedu").object("林屿森LIN - 小幸运【吉他】 (伴奏).mp3").build());// 拿到输出流,用于下载到本地,命名为 lucky.mp3FileOutputStream outputStream = new FileOutputStream("D:\\lucky.mp3");// 用于拷贝流IOUtils.copy(inputStream, outputStream);Long end = System.currentTimeMillis();System.out.println("用时:" + (end - start) + "ms");}
}

test01()就是我在项目中使用的下载分块文件的方式。我进行了多次测试执行该方法,可以看出确实很慢,10.1MB的文件也要14秒左右。

于是小可爱的我换了一种下载方式:

    public static void test02() throws Exception {Long start = System.currentTimeMillis();// 使用minio客户端提供的downloadObject方法进行下载minioClient.downloadObject(DownloadObjectArgs.builder()// 指定 bucket 存储桶.bucket("waveedu")// 指定 哪个文件.object("林屿森LIN - 小幸运【吉他】 (伴奏).mp3")// 指定存放位置与名称.filename("D:\\lucky.mp3").build());Long end = System.currentTimeMillis();System.out.println(end - start);}

我发现第一次执行该test02()方法下载的耗时和test01()的耗时一样,但之后再执行test02()时发现都只需要0.2秒!

于是我天真的以为就是不应该使用流拷贝的方式,而是应该使用test02()的方式。但修改项目中的下载方式后,几番折腾下来下载分块代码的时间和原来还是一样,依旧2MB的分块文件下载到本地磁盘需要两到三秒。我真哭醉了😭😭😭。

3️⃣ 于是又几番demo测试和源码分析后,我发现了为什么test02()第一次执行的耗时和test01()一样。

我们先看看 downloadObject 方法的对我们而言的关键源码:

image-20230211043521167

简单点说,实际上就是 downloadObject 方法中也是使用流拷贝方式进行下载,但在下载之前先会去判断 D:\lucky.mp3 是否已经在本地磁盘存在,如果存在并且与minio中 waveedu 桶的文件 林屿森LIN - 小幸运【吉他】 (伴奏).mp3 所占字节大小一致,就认为是相同文件,没必要再从minio下载。因此第一次执行完test02()方法后之后再执行都是会直接判断出 fileSize == stat.size()为true ,就return了,不会再流拷贝。

而我的test01()是没有走这个判断的,不管本地指定位置存不存在,都会进行流拷贝从minio下载文件。

4️⃣ 发现了不是项目所用的下载方法的原因后,我开始思考是不是人品的问题,于是进行反复无脑愚蠢的重启服务器和重启项目,很显然,没得屁用。

5️⃣ 再到最后,我开始考虑是不是由于对轻量服务器是外网访问,而导致传输速度很慢,因此我依旧使用test01()的方法,在我本地linux虚拟机中启动minio服务,来测试下载速度:

import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import org.apache.tomcat.util.http.fileupload.IOUtils;import java.io.FileOutputStream;
import java.io.InputStream;/*** @author 狐狸半面添* @create 2023-02-11 15:10*/
public class NativeLinuxTest {public static void main(String[] args) throws Exception {MinioClient minioClient = MinioClient.builder()// 指定连接的ip和端口(该ip是本地虚拟机的虚拟Ip).endpoint("http://192.168.65.130:9000")// 指定 访问秘钥(也称用户id) 和 私有秘钥(也称密码).credentials("minioadmin", "minioadmin").build();Long start = System.currentTimeMillis();// 拿到输入流,我存放在minio的该文件为 10.1 MB 大小InputStream inputStream = minioClient.getObject(GetObjectArgs.builder().bucket("waveedu").object("林屿森LIN - 小幸运【吉他】 (伴奏).mp3").build());// 拿到输出流,用于下载到本地,命名为 lucky.mp3FileOutputStream outputStream = new FileOutputStream("D:\\lucky.mmp3");// 用于拷贝流IOUtils.copy(inputStream, outputStream);Long end = System.currentTimeMillis();// 平均用时 0.2 到 0.3 秒System.out.println("用时:" + (end - start) + "ms");}
}

可以看到每次调用该拷贝流的方法都是只需要 0.2 到 0.3 秒左右,因此这也就证明了是由于后端项目启动在本地,而minio服务放在了轻量服务器,后端项目从minio下载文件必须外网访问的缘故。

4.问题解决

但这个问题在我们项目部署后肯定不存在的,因为我们的项目,也包括数据库、minio服务、redis服务肯定都是部署在同一局域网中(如果项目不大的话,简单点操作就是将所有服务放在一台服务器上)。这样的好处就是可以极大的加快数据传输速率。

相关文章:

minio下载文件速度很慢的原因分析与说明

文章目录1.实战背景2.问题描述3.问题分析4.问题解决1.实战背景 最近在做一个项目&#xff0c;需要用到minio来搭建文件系统&#xff0c;先简单说一下我在项目中设置的上传文件流程&#xff1a; 前端将分块文件逐一传给后端&#xff0c;后端再存储到 linux服务器的minio 当中。…...

基于comsol软件弯曲单模光纤模拟仿真

在本节中&#xff0c;主要基于实验室实际光纤单模圆柱光纤进行模拟&#xff0c;与comsol案例库文件在分析过程和建模有些差异&#xff1a; 模拟主要通过以下三个步骤进行&#xff1a;模型的几何构建、物理场的添加研究、结构处理分析来进行。 下面是第一步骤&#xff1a;几何…...

如何开启多个独立Chrome浏览器

一、简介 作为测试或者开发人员&#xff0c;有些情况下会用到 Chrome 浏览器&#xff0c;但有时是同一个 Chrome 浏览器无法为我们提供隔离开的不同环境。这样 我们就需要清理 cache 、切换账号等&#xff0c;降低了我们的工作效率。今天的主题是如何开启多个独立的 Chrome 浏…...

erp5开源制造业erp主要业务会计分录处理

erp5开源制造业erp主要业务会计分录处理 采购业务的会计分录 收到发票时 借&#xff1a;材料采购 (1201) 应交税费-应交增值税&#xff08;进项税&#xff09;(21710101) 贷&#xff1a;应付账款 (2121) 付款时 借&#xff1a;应付账款 (2121) 贷&#xff1a;银行存款 (1002) 入…...

技能树基础——17四平方和(拉格朗日定理,嵌套循环)

题目&#xff1a;四平方和定理&#xff0c;又称为拉格朗日定理&#xff1a;每个正整数都可以表示为至多4个正整数的平方和。如果把0包括进去&#xff0c;就正好可以表示为4个数的平方和。比如&#xff1a;5 0^ 2 0^ 2 1^ 2 2^27 1^ 2 1^ 2 1^ 2 2^2 &#xff08;^符号表…...

JPA、EJB、事物管理---相关内容整理

目录 ■前言 ■实现原理&#xff1a;容器管理事务 ■代码实现简单描述&#xff1a; 1.JPA ■定义 ■1.1.配置文件 ■1.2.OSS jar ■1.3.一些OPA的类&#xff08;举例&#xff09; ■1.4. jpa 框架在实体类&#xff08;Entity&#xff09;中添加非数据库字段的属性--…...

C语言学习笔记(一):了解C语言

什么是C语言 C语言是一种高级编程语言&#xff0c;最早由丹尼斯里奇在1972年开发。它是一种通用编程语言&#xff0c;提供了高级编程语言的方便和易用性&#xff0c;同时又有较低级别的编程语言的灵活性和效率。C语言在许多操作系统、编译器和应用程序开发中广泛使用&#xff…...

回头看——《智能家居项目小结》

openAI兴起&#xff0c;于是拿着之前小组合作的项目&#xff08;承认优化较差&#xff09;&#xff0c;交给AI试着帮忙优化下&#xff11;.功能函数&#xff08;TCP_SER_INIT&#xff09;优化源代码&#xff1a;int TCP_SER_INIT(int *tcpsocket, const char *ip, const char *…...

社交登陆OAuth2.0

QQ、微博、github 等网站的用户量非常大&#xff0c;别的网站为了 简化自我网站的登陆与注册逻辑&#xff0c;引入社交登陆功能&#xff1b; 步骤&#xff1a; 1&#xff09;、用户点击 QQ 按钮 2&#xff09;、引导跳转到 QQ 授权页 3&#xff09;、用户主动点击授权&#xff…...

C++005-C++选择与分支2

文章目录C005-C选择与分支2条件语句C实现else if 语句题目描述 根据成绩输出成绩等级ABCDEif嵌套语句题目描述 输出三个数中的最大值题目描述 模拟游戏登录switch语句三元运算符题目描述 输出三个数中的最大值-基于3元运算符题目描述 根据1-7输出星期1-星期日案例练习题目描述 …...

IPFS 简介及概述

文章目录 IPFS 简介IPFS 包含的协议内容及其理解IPFS 和 BitTorrent 区别IPFS 简介 星际文件系统(InterPlanetary File System). IPFS 是一个分布式的网络文件系统, 点到点超媒体协议. 可以让我们的互联网速度更快, 更加安全, 并且更加开放. IPFS协议的目标是取代传统的互联网…...

初学者必读:讲解 VC 下如何正确的创建、管理及发布项目

Visual C 的项目文件组成&#xff0c;以及如何正确的创建及管理项目。 本内容是初学者必须要掌握的。不能正确的管理项目&#xff0c;就不能进一步写有规模的程序。 一、项目下各种常见文件类型的功能 1. 代码文件 扩展名为 .cpp、.c、.h 等。 通常情况下&#xff0c;项目…...

剑指offer(中等)

目录 二维数组中的查找 重建二叉树 矩阵中的路径 剪绳子 剪绳子② 数值的整数次方 表示数值的字符串 树的子结构 栈的压入、弹出序列 从上到下打印二叉树① 从上到下打印二叉树③ 二叉搜索树的后序遍历序列 二叉树中和为某一值的路径 复杂链表的复制 二叉搜索树与…...

微软发布会精华回顾:“台式电脑”抢了风头

Lightbot北京时间2016年10月26日晚10点&#xff0c;微软在纽约发布了名为 Surface Studio 的一体机、名为 Surface Dial 的配件以及外观未变的顶配版 Surface Book。同时&#xff0c;微软宣布了 Windows 10 下一个重要版本——“Creators Update”的数项新功能&#xff0c;包括…...

CF1561C Deep Down Below 题解

CF1561C Deep Down Below 题解题目链接字面描述Deep Down Below题面翻译题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示思路TLE算法具体思想TLE特例AC思想代码实现备注题目 链接 https://www.luogu.com.cn/problem/CF1561C 字面描述 Deep Down Below 题面翻译…...

秒杀项目之服务调用分布式session

目录 nginx动静分离 服务调用 创建配置zmall-cart购物车模块 创建配置zmall-order订单模块 服务调用 spring session实战 什么是Spring Session 为什么要使用Spring Session 错误案例展示 配置spring-session 二级域名问题 用户登录 nginx动静分离 第1步&#xff…...

聊聊什么是架构,你理解对了吗?

什么是架构?软件有架构?建筑也有架构?它们有什么相同点和不同点? 下面咱们就介绍一下,容易混淆的几个概念 一、系统与子系统 系统 泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体。它的意思是 “总体”、“整体”或“联盟” 子系…...

java多线程开发

1.并发和并行 并发&#xff1a;同一时间段内多个任务同时进行。 并行&#xff1a;同一时间点多个任务同时进行。 2.进程线程 进程&#xff08;Process&#xff09;&#xff1a;进程是程序的一次动态执行过程&#xff0c;它经历了从代码加载、执行、到执行完毕的一个完整过程…...

杂记7--opencv的ar码模块学习

背景&#xff1a;项目需要用到marker知识&#xff0c;所以到官网上临时补一些知识。 概要&#xff1a;主要介绍marker一些接口的含义&#xff0c;纯属个人理解&#xff0c;有误则希望大佬不吝赐教 1、 涉及ar码操作学习&#xff0c;其头文件为&#xff1a; #include <op…...

[项目设计]高并发内存池

目录 1、项目介绍 2、高并发内存池整体框架设计 3、thread cache <1>thread cache 哈希桶对齐规则 <2>Thread Cache类设计 4、Central Cache <1>Central Cache类设计 5、page cache <1>Page Cache类设计 6、性能分析 <1>定长内存池实现…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要&#xff0c;uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件&#xff0c;需要安装才能使用。 一、安装扩展插件 安装方法&#xff1a; 1.访问uniapp官方文档组件部分&#xff1a;组件使用的入门教程 | uni-app官网 点击左侧…...