日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MinIO分布式文件服务器搭建与入门

發布時間:2023/12/18 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MinIO分布式文件服务器搭建与入门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、介紹
    • 1、對象存儲和分布式文件簡介
    • 2、MinIO簡介
    • 3、MinIO特點
  • 二、MinIO安裝入門
    • 1、介紹
    • 2、快速安裝
      • 2.1 Windows
      • 2.2 Linux
      • 2.3 MacOS
      • 2.4 Docker(推薦)
    • 3、UI界面界面簡單使用
      • 3.1 新建存儲桶
      • 3.2 添加訪問規則
      • 3.3 上傳文件
      • 3.4 訪問文件
  • 三、SpringBoot整合MinIO
    • 1、引入項目依賴
    • 2、配置文件設置
    • 3、配置類設置
    • 4、工具類整合
      • 4.1 簡單整合MinIO上傳工具
      • 4.2 MinIO工具類

一、介紹

1、對象存儲和分布式文件簡介

阿里云OSS對象存儲:https://help.aliyun.com/product/31815.html

對象存儲服務OSS(Object Storage Service)是一種海量、安全、低成本、高可靠的云存儲服務,適合存放任意類型的文件。容量和處理能力彈性擴展,多種存儲類型供選擇,全面優化存儲成本。對象存儲最大的優勢就在于它可以存儲大容量的非結構化數據,例如圖片、視頻、日志文件、備份數據和容器/虛擬機鏡像等。對于大多數的企業來說,這可以說是最為理想的存儲媒介了

分布式文件系統是指文件系統管理的物理存儲資源不一定直接連接在本地節點上,而是通過計算機網絡與節點相連

2、MinIO簡介

MinIO 是一個基于 Go 實現的高性能、兼容 S3 協議的對象存儲。它采用 GNU AGPL v3 開源協議,項目地址是 https://github.com/minio/minio,官網是 https://min.io,中文官網是www.minio.org.cn
它適合存儲海量的非結構化的數據,例如說圖片、音頻、視頻等常見文件,備份數據、容器、虛擬機鏡像等等,小到 1 KB,大到 5 TB 都可以支持。

3、MinIO特點

minio原理和使用

  • 高性能:作為高性能對象存儲,在標準硬件條件下它能達到55GB/s的讀、35GG/s的寫速率

  • 可擴容:不同MinIO集群可以組成聯邦,并形成一個全局的命名空間,并跨越多個數據中心

  • 云原生:容器化、基于K8S的編排、多租戶支持

  • Amazon S3兼容:Minio使用Amazon S3 v2 / v4 API。可以使用Minio SDK,Minio Client,AWS SDK和AWS CLI訪問Minio服務器。

  • 可對接后端存儲: 除了Minio自己的文件系統,還支持DAS、 JBODs、NAS、Google云存儲和Azure Blob存儲。

  • SDK支持: 基于Minio輕量的特點,它得到類似Java、Python或Go等語言的sdk支持

  • Lambda計算: Minio服務器通過其兼容AWS SNS / SQS的事件通知服務觸發Lambda功能。支持的目標是消息隊列,如Kafka,NATS,AMQP,MQTT,Webhooks以及Elasticsearch,Redis,Postgres和MySQL等數據庫。

  • 有操作頁面

  • 功能簡單: 這一設計原則讓MinIO不容易出錯、更快啟動

  • 支持糾刪碼:MinIO使用糾刪碼、Checksum來防止硬件錯誤和靜默數據污染。在最高冗余度配置下,即使丟失1/2的磁盤也能恢復數據

    糾刪碼是一種用來重建丟失或損壞數據的數學算法。MinIO 使用 Reed-Solomon 碼將需要存儲的對象切分為可變數據塊和奇偶校驗塊。例如,在由 12 個驅動器構成的存儲架構中,對象分片范圍可以是 6 個數據塊、6 個奇偶校驗塊到 10 個數據塊、2 個奇偶校驗塊。

二、MinIO安裝入門

1、介紹

中文開發文檔:http://docs.minio.org.cn/docs/

由于 MinIO 是 Go 寫的,所以就一個運行程序,因此安裝部署 MinIO 就非常簡單。在文檔 https://min.io/download 中,有 Windows、Linux、MacOS、Docker、Kubernetes、Source 六種安裝方式。

2、快速安裝

2.1 Windows

需要在 Windows PowerShell 中執行。

## 國外資源,龜速下載,建議科學上網 setx MINIO_ROOT_USER admin Invoke-WebRequest -Uri "https://dl.min.io/server/minio/release/windows-amd64/minio.exe" -OutFile "C:\minio.exe" setx MINIO_ROOT_PASSWORD password C:\minio.exe server F:\Data --console-address ":9001" ## F:\Data 存儲目錄;--console-address 是 UI 界面的端口

2.2 Linux

## 國外資源,龜速下載 wget https://dl.min.io/server/minio/release/linux-amd64/minio chmod +x minio MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password ./minio server ./minio --console-address ":9001" ## /Users/yunai/minio 存儲目錄;--console-address 是 UI 界面的端口

2.3 MacOS

## 國外資源,龜速下載 wget https://dl.min.io/server/minio/release/darwin-amd64/minio chmod +x minio MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password ./minio server F:\Data --console-address ":9001" ## F:\Data 存儲目錄;--console-address 是 UI 界面的端口

2.4 Docker(推薦)

linux單個docker啟動

docker pull minio/minio # --console-address 是 UI 界面的端口 docker run --name minio -p 9000:9000 -p 9001:9001 -d --restart=always -e "MINIO_ACCESS_KEY=admin" -e "MINIO_SECRET_KEY=password" -v "~/minio/data":"/data" -v "~/minio/config":"/root/.minio" minio/minio server /data --console-address ":9001"

linux docker-compose啟動(推薦),首先編寫docker-compose.yml文件,最后在該目錄下docker-compose up -d成功啟動

version: '3' services:minio:image: minio/miniohostname: "minio"ports:- "9000:9000" # api 端口- "9001:9001" # 控制臺端口environment:MINIO_ACCESS_KEY: admin #管理后臺用戶名MINIO_SECRET_KEY: password #管理后臺密碼,最小8個字符volumes:- /home/deepsoft/minio/data:/data #映射當前目錄下的data目錄至容器內/data目錄- /home/deepsoft/minio/config:/root/.minio/ #映射配置目錄command: server --console-address ':9001' /data #指定容器中的目錄 /dataprivileged: truerestart: alwayslogging:options:max-size: "50M" # 最大文件上傳限制max-file: "10"driver: json-filenetworks:- minio networks:minio:name: minio

啟動成功后打開防火墻,瀏覽http://localhost:9001即可進入可視化頁面

3、UI界面界面簡單使用

https://docs.min.io/minio/baremetal/console/minio-console.html#

3.1 新建存儲桶

首先登錄http://localhost:9001,點擊 [Create Bucket] 按鈕,新建一個 Bucket 存儲桶,用于稍后文件的上傳

這里存儲桶名稱長度必須?少為3且不超過63個字符,不得包含?寫字符或下劃線,必須以?寫字母或數字開頭。

3.2 添加訪問規則

默認配置下,訪問存儲桶是需要請求授權的。但是在實際場景下,我們往往希望允許直接訪問,此時就需要添加一條 readonly 或readwrite訪問規則;或者直接在[Access Policy]直接設置public(不安全)

① 點擊右上角的 [Manage] 設置圖標,然后選擇 [Access Rules] 菜單。

② 點擊 [Add Access Rule] 按鈕,添加一條 Prefix 為 /或者* ,Access 為 readwrite的規則。

3.3 上傳文件

點擊 [Upload] 按鈕,點擊 [Upload File] 選項,選擇一個文件上傳

3.4 訪問文件

文件的訪問地址的格式為 <http://127.0.0.1:9000/{bucket}/{name}>,注意是 9000 端口。比如我的是http://192.168.31.34:9000/textbook/yuanshen.png

三、SpringBoot整合MinIO

1、引入項目依賴

注意7.x和8.x版本有一定差異,這里在pom.xml引入最新版

<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.0</version> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency>

2、配置文件設置

在application.yml中設置

# Tomcat server:port: 8888spring:# 配置文件上傳大小限制servlet:multipart:max-file-size: 100MBmax-request-size: 100MB# Minio配置 minio:url: http://localhost:9000accessKey: minioadminsecretKey: minioadminbucketName: test

3、配置類設置

讀取配置文件的信息,這里的存儲桶名稱可以設置多個

@Configuration @ConfigurationProperties(prefix = "minio") @Data public class MinioConfig {/*** 服務地址*/private String url;/*** 用戶名*/private String accessKey;/*** 密碼*/private String secretKey;/*** 存儲桶名稱*/private String TextBookBucketName;@Beanpublic MinioClient getMinioClient(){return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();} }

設置返回類

@Data public class FileVO {/*** 展示url*/private String previewUrl;/*** 存數據庫的uri*/private String uri; }

4、工具類整合

4.1 簡單整合MinIO上傳工具

@RestController @RequestMapping("/file") public class FileController{@Resourceprivate MinioClient minioClient;@Resourceprivate MinioConfig minioConfig;/*** 上傳文件*/@PostMapping("/upload")public CommonResult upload(@RequestParam("file") MultipartFile file) throws Exception {//可以直接原來的文件名,也可以自定義//String originalFilename = file.getOriginalFilename();// 文件名String originalFilename = file.getOriginalFilename();// 新的文件名 = 時間戳.后綴名String fileName = System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));// 上傳minioClient.putObject(PutObjectArgs.builder()// 存儲桶.bucket(minioConfig.getTextBookBucketName())// 文件名 ,可以添加路徑,會自動創建.object(fileName)// 文件內容.stream(file.getInputStream(), file.getSize(), -1)// 文件類型.contentType(file.getContentType()).build());FileVO fileVO = new FileVO();fileVO.setUri("/" + minioConfig.getTextBookBucketName()+ "/" + fileName);fileVO.setPreviewUrl(minioConfig.getUrl()+"/" + fileVO.getUri());// 拼接路徑return new CommonResult(fileVO);}/*** 刪除文件*/@DeleteMapping("/delete")public void delete(@RequestParam("path") String path) throws Exception {minioClient.removeObject(RemoveObjectArgs.builder()// 存儲桶.bucket(minioConfig.getTextBookBucketName())// 文件名,可以文件名.object(path).build());} }

4.2 MinIO工具類

首先創建工具類,這里很多操作都在工具類里了,需要用到的地方通過MinioUtils.xxx()方法調用即可。另外,工具類中傳遞的endpoint、bucketName、accessKey、ecretKey等參數,都是在minio后臺可以拿到的,沒有的話也可以自己設置,同時要保證后臺的存儲桶是開放的,默認代碼創建的都是私有的

@Slf4j public class MinIOUtils {private static MinioClient minioClient;private static String endpoint;private static String bucketName;private static String accessKey;private static String secretKey;private static Integer imgSize;private static Integer fileSize;private static final String SEPARATOR = "/";public MinIOUtils() {}public MinIOUtils(String endpoint, String bucketName, String accessKey, String secretKey, Integer imgSize, Integer fileSize) {MinIOUtils.endpoint = endpoint;MinIOUtils.bucketName = bucketName;MinIOUtils.accessKey = accessKey;MinIOUtils.secretKey = secretKey;MinIOUtils.imgSize = imgSize;MinIOUtils.fileSize = fileSize;createMinioClient();}/*** 創建基于Java端的MinioClient*/public void createMinioClient() {try {if (null == minioClient) {log.info("開始創建 MinioClient...");minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();createBucket(bucketName);log.info("創建完畢 MinioClient...");}} catch (Exception e) {log.error("[Minio工具類]>>>> MinIO服務器異常:", e);}}/*** 獲取上傳文件前綴路徑* @return*/public static String getBasisUrl() {return endpoint + SEPARATOR + bucketName + SEPARATOR;}/****************************** Operate Bucket Start ******************************//*** 啟動SpringBoot容器的時候初始化Bucket* 如果沒有Bucket則創建* @throws Exception*/private static void createBucket(String bucketName) throws Exception {if (!bucketExists(bucketName)) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());}}/*** 判斷Bucket是否存在,true:存在,false:不存在* @return* @throws Exception*/public static boolean bucketExists(String bucketName) throws Exception {return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());}/*** 獲得Bucket的策略* @param bucketName* @return* @throws Exception*/public static String getBucketPolicy(String bucketName) throws Exception {return minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build());}/*** 獲得所有Bucket列表* @return* @throws Exception*/public static List<Bucket> getAllBuckets() throws Exception {return minioClient.listBuckets();}/*** 根據bucketName獲取其相關信息* @param bucketName* @return* @throws Exception*/public static Optional<Bucket> getBucket(String bucketName) throws Exception {return getAllBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();}/*** 根據bucketName刪除Bucket,true:刪除成功; false:刪除失敗,文件或已不存在* @param bucketName* @throws Exception*/public static void removeBucket(String bucketName) throws Exception {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());}/****************************** Operate Bucket End ******************************//****************************** Operate Files Start ******************************//*** 判斷文件是否存在* @param bucketName 存儲桶* @param objectName 文件名* @return*/public static boolean isObjectExist(String bucketName, String objectName) {boolean exist = true;try {minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());} catch (Exception e) {log.error("[Minio工具類]>>>> 判斷文件是否存在, 異常:", e);exist = false;}return exist;}/*** 判斷文件夾是否存在* @param bucketName 存儲桶* @param objectName 文件夾名稱* @return*/public static boolean isFolderExist(String bucketName, String objectName) {boolean exist = false;try {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());for (Result<Item> result : results) {Item item = result.get();if (item.isDir() && objectName.equals(item.objectName())) {exist = true;}}} catch (Exception e) {log.error("[Minio工具類]>>>> 判斷文件夾是否存在,異常:", e);exist = false;}return exist;}/*** 根據文件前置查詢文件* @param bucketName 存儲桶* @param prefix 前綴* @param recursive 是否使用遞歸查詢* @return MinioItem 列表* @throws Exception*/public static List<Item> getAllObjectsByPrefix(String bucketName,String prefix,boolean recursive) throws Exception {List<Item> list = new ArrayList<>();Iterable<Result<Item>> objectsIterator = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());if (objectsIterator != null) {for (Result<Item> o : objectsIterator) {Item item = o.get();list.add(item);}}return list;}/*** 獲取文件流* @param bucketName 存儲桶* @param objectName 文件名* @return 二進制流*/public static InputStream getObject(String bucketName, String objectName) throws Exception {return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());}/*** 斷點下載* @param bucketName 存儲桶* @param objectName 文件名稱* @param offset 起始字節的位置* @param length 要讀取的長度* @return 二進制流*/public InputStream getObject(String bucketName, String objectName, long offset, long length)throws Exception {return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length).build());}/*** 獲取路徑下文件列表* @param bucketName 存儲桶* @param prefix 文件名稱* @param recursive 是否遞歸查找,false:模擬文件夾結構查找* @return 二進制流*/public static Iterable<Result<Item>> listObjects(String bucketName, String prefix,boolean recursive) {return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());}/*** 使用MultipartFile進行文件上傳* @param bucketName 存儲桶* @param file 文件名* @param objectName 對象名* @param contentType 類型* @return* @throws Exception*/public static ObjectWriteResponse uploadFile(String bucketName, MultipartFile file,String objectName, String contentType) throws Exception {InputStream inputStream = file.getInputStream();return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).contentType(contentType).stream(inputStream, inputStream.available(), -1).build());}/*** 上傳本地文件* @param bucketName 存儲桶* @param objectName 對象名稱* @param fileName 本地文件路徑*/public static ObjectWriteResponse uploadFile(String bucketName, String objectName,String fileName) throws Exception {return minioClient.uploadObject(UploadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build());}/*** 通過流上傳文件** @param bucketName 存儲桶* @param objectName 文件對象* @param inputStream 文件流*/public static ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) throws Exception {return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(inputStream, inputStream.available(), -1).build());}/*** 創建文件夾或目錄* @param bucketName 存儲桶* @param objectName 目錄路徑*/public static ObjectWriteResponse createDir(String bucketName, String objectName) throws Exception {return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(new ByteArrayInputStream(new byte[]{}), 0, -1).build());}/*** 獲取文件信息, 如果拋出異常則說明文件不存在** @param bucketName 存儲桶* @param objectName 文件名稱*/public static String getFileStatusInfo(String bucketName, String objectName) throws Exception {return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build()).toString();}/*** 拷貝文件** @param bucketName 存儲桶* @param objectName 文件名* @param srcBucketName 目標存儲桶* @param srcObjectName 目標文件名*/public static ObjectWriteResponse copyFile(String bucketName, String objectName,String srcBucketName, String srcObjectName) throws Exception {return minioClient.copyObject(CopyObjectArgs.builder().source(CopySource.builder().bucket(bucketName).object(objectName).build()).bucket(srcBucketName).object(srcObjectName).build());}/*** 刪除文件* @param bucketName 存儲桶* @param objectName 文件名稱*/public static void removeFile(String bucketName, String objectName) throws Exception {minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());}/*** 批量刪除文件* @param bucketName 存儲桶* @param keys 需要刪除的文件列表* @return*/public static void removeFiles(String bucketName, List<String> keys) {List<DeleteObject> objects = new LinkedList<>();keys.forEach(s -> {objects.add(new DeleteObject(s));try {removeFile(bucketName, s);} catch (Exception e) {log.error("[Minio工具類]>>>> 批量刪除文件,異常:", e);}});}/*** 獲取文件外鏈* @param bucketName 存儲桶* @param objectName 文件名* @param expires 過期時間 <=7 秒 (外鏈有效時間(單位:秒))* @return url* @throws Exception*/public static String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().expiry(expires).bucket(bucketName).object(objectName).build();return minioClient.getPresignedObjectUrl(args);}/*** 獲得文件外鏈* @param bucketName* @param objectName* @return url* @throws Exception*/public static String getPresignedObjectUrl(String bucketName, String objectName) throws Exception {GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).method(Method.GET).build();return minioClient.getPresignedObjectUrl(args);}/*** 將URLDecoder編碼轉成UTF8* @param str* @return* @throws UnsupportedEncodingException*/public static String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException {String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25");return URLDecoder.decode(url, "UTF-8");}/****************************** Operate Files End ******************************/}

創建controller層,這里要首先初始化靜態類才能使用

@RestController @RequestMapping("/file") @Slf4j public class FileController {@Resourceprivate MinioClient minioClient;@Autowiredprivate MinioConfig minioConfig;@PostConstructpublic void initializeMinIO(){// 新建minIOnew MinIOUtils(minioConfig.getUrl(),minioConfig.getTextBookBucketName(),minioConfig.getAccessKey(),minioConfig.getSecretKey(),1000,1000);}/*** 上傳文件*/@PostMapping("/resourceFileUpload")public CommonResult resourceFileUpload(@RequestParam("dirPath")String dirPath,@RequestParam("file") MultipartFile file) throws Exception {if(file == null){return new CommonResult<>("參數錯誤");}// 路徑String path;if(StringUtils.isBlank(dirPath)){path = file.getOriginalFilename();}else{path = dirPath + "/" + file.getOriginalFilename();}// 上傳MinIOUtils.uploadFile(minioConfig.getTextBookBucketName(), file, path, file.getContentType());FileVO fileVO = new FileVO();fileVO.setUri("/" + minioConfig.getTextBookBucketName()+ "/" + path);fileVO.setPreviewUrl(minioConfig.getUrl()+"/" + fileVO.getUri());log.info("文件上傳成功!");return new CommonResult<>(fileVO);} }

參考文章

SpringBoot+Minio搭建

16 分鐘搭建高性能的文件服務器

總結

以上是生活随笔為你收集整理的MinIO分布式文件服务器搭建与入门的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。