第2-1-5章 docker安裝MinIO實現文件存儲服務-springboot整合minio-minio全網最全的資料
- 2022 年 11 月 9 日
- 筆記
- docker, docker-compose, Go, JAVA, minio, springboot, 中台戰略與組件化開發, 文件存儲服務
1. MinIO介紹
MinIO 是一個基於Apache License v2.0開源協議的對象存儲服務。它兼容亞馬遜S3雲存儲服務介面,非常適合於存儲大容量非結構化的數據,例如圖片、影片、日誌文件、備份數據和容器/虛擬機鏡像等,而一個對象文件可以是任意大小,從幾kb到最大5T不等。
MinIO是一個非常輕量的服務,可以很簡單的和其他應用的結合,類似 NodeJS, Redis 或者 MySQL。
官方文檔://docs.minio.org.cn/docs 舊一點
//docs.min.io/ 新
2. MinIO應用場景
2.1 單主機單硬碟模式
2.2 單主機多硬碟模式
2.3 多主機多硬碟分散式
3. MinIO特點
-
高性能:作為高性能對象存儲,在標準硬體條件下它能達到55GB/s的讀、35GB/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的磁碟也能恢複數據
4. 存儲機制
Minio使用糾刪碼erasure code和校驗和checksum。 即便丟失一半數量(N/2)的硬碟,仍然可以恢複數據。
糾刪碼是一種恢復丟失和損壞數據的數學演算法
5. docker安裝MinIO
- 首先下載MinIO的Docker鏡像:
-
先說下版本選擇,這個可以自己去dockerhub上查看版本
-
由於minio更新迭代比較快,所以根據自己需要來選擇版本,我用的是RELEASE.2022-09-22T18-57-27Z.fips這個版本
-
docker pull minio/minio:RELEASE.2022-09-22T18-57-27Z.fips
- 下載完成後使用如下命令運行MinIO服務,注意使用
--console-address
指定MinIO Console的運行埠(否則會隨機埠運行):
docker run \
-p 9000:9000 \
-p 9001:9001 \
--name minio \
-d --restart=always \
-e "MINIO_ROOT_USER=admin" \
-e "MINIO_ROOT_PASSWORD=admin123456" \
-v /mydata/minio/data:/data \
-v /mydata/minio/config:/root/.minio \
minio/minio:RELEASE.2022-09-22T18-57-27Z.fips server /data --console-address ":9001"
6. docker-compose安裝MinIO
version: '3'
services:
minio:
image: minio/minio:RELEASE.2022-09-22T18-57-27Z.fips
container_name: minio
environment:
MINIO_ROOT_USER: admin
MINIO_ROOT_PASSWORD: admin123456
command: server /data --console-address ":9001"
volumes:
- /mydata/minio/data:/data
- /mydata/minio/config:/root/.minio
ports:
- 9000:9000
- 9001:9001
- 運行成功後就可訪問MinIO Console的管理介面了,輸入帳號密碼
admin:admin123456
即可登錄,訪問地址://192.168.86.101:9000
7. MinIO Console使用
MinIO Console是MinIO自帶的可視化管理工具,新版的功能還是很強大的。不僅支援了存儲桶、文件的管理,還增加了用戶、許可權、日誌等管理功能。
-
在存儲文件之前,我們首先得創建一個存儲桶
-
創建成功後,再上傳一個文件
- 上傳成功後如果你想從外部訪問文件的話,需要把訪問策略設置為公開,這裡的策略除了公開和私有兩種,也支援custom了。
- 之後把地址改為外網訪問地址即可訪問圖片
8. 客戶端使用
其實對於對象存儲來說,MinIO Console的功能還是不夠用的,所以官方還提供了基於命令行的客戶端MinIO Client(簡稱mc),下面我們來講講它的使用方法。
8.1 常用命令
我們先來熟悉下mc的命令,這些命令和Linux中的命令有很多相似之處。
命令 | 作用 |
---|---|
ls | 列出文件和文件夾 |
mb | 創建一個存儲桶或一個文件夾 |
rb | 刪除一個存儲桶或一個文件夾 |
cat | 顯示文件和對象內容 |
pipe | 將一個STDIN重定向到一個對象或者文件或者STDOUT |
share | 生成用於共享的URL |
cp | 拷貝文件和對象 |
mirror | 給存儲桶和文件夾做鏡像 |
find | 基於參數查找文件 |
diff | 對兩個文件夾或者存儲桶比較差異 |
rm | 刪除文件和對象 |
events | 管理對象通知 |
watch | 監聽文件和對象的事件 |
policy | 管理訪問策略 |
session | 為cp命令管理保存的會話 |
config | 管理mc配置文件 |
update | 檢查軟體更新 |
version | 輸出版本資訊 |
8.2 安裝及配置
由於MinIO服務端中並沒有自帶客戶端,所以我們需要安裝並配置完客戶端後才能使用,這裡以Docker環境下的安裝為例。
- 下載MinIO Client 的Docker鏡像
docker pull minio/mc:latest
- 在Docker容器中運行mc
docker run -it --entrypoint=/bin/sh minio/mc
- 運行完成後我們需要進行配置,將我們自己的MinIO服務配置到客戶端上去,配置的格式如下
mc config host add <ALIAS> <YOUR-S3-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY>
- 對於我們的MinIO服務可以這樣配置
mc config host add minio //192.168.86.101:9000 admin admin123456
8.3 常用操作
下面這些就用macro大神的教程,我就不繼續實操了,我本地沒有裝客戶端,因為通過console控制台管理足夠日常使用了
- 查看存儲桶和查看存儲桶中存在的文件
# 查看存儲桶
mc ls minio
# 查看存儲桶中存在的文件
mc ls minio/blog
- 創建一個名為
test
的存儲桶
mc mb minio/test
- 共享
avatar.png
文件的下載路徑
mc share download minio/blog/avatar.png
- 查找
blog
存儲桶中的png文件
mc find minio/blog --name "*.png"
- 設置
test
存儲桶的訪問許可權為只讀
。
# 目前可以設置這四種許可權:none, download, upload, public
mc policy set download minio/test/
# 查看存儲桶當前許可權
mc policy list minio/test/
9. 兼容AWS S3
當我們對接第三方服務要用到對象存儲時,這些服務往往都是支援AWS S3的。比如說一個直播的回放功能,需要對象存儲來存儲回放的影片,由於MinIO兼容AWS S3的大多數API,我們可以直接拿它當AWS S3來使用。
- 我們可以下載個AWS S3的客戶端來試試,MinIO到底能不能支援S3的API,這裡使用的是
S3 Browser
,下載地址://s3browser.com/
- 安裝好
S3 Browser
之後,添加一個Account,輸入相關登錄資訊,注意選擇Account類型為S3 Compatible Storage
- 連接成功後,我們可以看見之前我們創建的存儲桶和上傳的文件
S3 Browser
這個工具功能還是很強大的
- 如果你想修改存儲桶的訪問許可權的話直接通過
Permissions
標籤修改即可。
10. 利用Java客戶端調用MinIO
參考文檔://docs.min.io/docs/java-client-api-reference.html
10.1 引入依賴
在service-product模組中添加依賴
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.0</version>
</dependency>
10.2 添加配置文件
minio:
endpointUrl: //IP:9000
accessKey: admin
secreKey: admin123456
bucketName: file
10.3 編寫java程式
@RestController
@RequestMapping("admin/product")
public class FileUploadController {
// 獲取文件上傳對應的地址
@Value("${minio.endpointUrl}")
public String endpointUrl;
@Value("${minio.accessKey}")
public String accessKey;
@Value("${minio.secreKey}")
public String secreKey;
@Value("${minio.bucketName}")
public String bucketName;
// 文件上傳控制器
@PostMapping("fileUpload")
public Result fileUpload(MultipartFile file) throws Exception{
// 準備獲取到上傳的文件路徑!
String url = "";
// 使用MinIO服務的URL,埠,Access key和Secret key創建一個MinioClient對象
// MinioClient minioClient = new MinioClient("//play.min.io", "Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG");
MinioClient minioClient =
MinioClient.builder()
.endpoint(endpointUrl)
.credentials(accessKey, secreKey)
.build();
// 檢查存儲桶是否已經存在
boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
if(isExist) {
System.out.println("Bucket already exists.");
} else {
// 創建一個名為asiatrip的存儲桶,用於存儲照片的zip文件。
minioClient.makeBucket(MakeBucketArgs.builder()
.bucket(bucketName)
.build());
}
// 定義一個文件的名稱 : 文件上傳的時候,名稱不能重複!
String fileName = System.currentTimeMillis()+ UUID.randomUUID().toString();
// 使用putObject上傳一個文件到存儲桶中。
// minioClient.putObject("asiatrip","asiaphotos.zip", "/home/user/Photos/asiaphotos.zip");
minioClient.putObject(
PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(
file.getInputStream(), file.getSize(), -1)
.contentType(file.getContentType())
.build());
// System.out.println("/home/user/Photos/asiaphotos.zip is successfully uploaded as asiaphotos.zip to `asiatrip` bucket.");
// 文件上傳之後的路徑: //192.168.86.101:9000/file/xxxxxx
url = endpointUrl+"/"+bucketName+"/"+fileName;
System.out.println("url:\t"+url);
// 將文件上傳之後的路徑返回給頁面!
return Result.ok(url);
}
}