MinIO linux安裝并整合spring boot

一、簡(jiǎn)介

MinIO 是一個(gè)基于Apache License v2.0開源協(xié)議的對(duì)象存儲(chǔ)服務(wù)。它兼容亞馬遜S3云存儲(chǔ)服務(wù)接口,非常適合于存儲(chǔ)大容量非結(jié)構(gòu)化的數(shù)據(jù),例如圖片、視頻、日志文件、備份數(shù)據(jù)和容器/虛擬機(jī)鏡像等,而一個(gè)對(duì)象文件可以是任意大小,從幾kb到最大5T不等。

二、環(huán)境

ip 端口
100 9000
102 9000

我這里服務(wù)器就只用了兩臺(tái),會(huì)用來(lái)做 MinIO的分布式文件。

三、單機(jī)

wget https://dl.min.io/server/minio/release/linux-amd64/minio
# 賦予執(zhí)行權(quán)限
chmod +x minio
# 啟動(dòng) 并設(shè)置數(shù)據(jù)存儲(chǔ)位置(單機(jī))
./minio server /data

四、分布式

建議編寫腳本如下 start.sh

# 端口打開 9000
/sbin/iptables -I INPUT -p tcp --dport 9000 -j ACCEPT
# 重新設(shè)置密鑰
export MINIO_ACCESS_KEY=minio
export MINIO_SECRET_KEY=minio@2020
# 啟動(dòng)并指定分布式服務(wù)器,這里會(huì)有坑 可以看 5 標(biāo)題
./minio server \
http://10.240.30.100/home/MinIO/data{1...4}  http://10.240.30.102/home/MinIO/data{1...4}

{1...4} 的意思是會(huì)在 /home/MinIO/ 生產(chǎn)4個(gè)文件 data1 data2 data3 data3,其中 "..." 必須為3個(gè)點(diǎn),得以獲得最佳的糾刪碼分布。啟動(dòng)成功后會(huì)有一個(gè) VIP做為網(wǎng)關(guān)。我自己使用VIP一旦崩潰,無(wú)法轉(zhuǎn)移,具體原因尚不清楚。

糾刪碼 是一種恢復(fù)丟失和損壞數(shù)據(jù)的數(shù)學(xué)算法,來(lái)保護(hù)數(shù)據(jù)免受硬件故障和無(wú)聲數(shù)據(jù)損壞。 即便您丟失一半數(shù)量的硬盤,您仍然可以恢復(fù)數(shù)據(jù)。內(nèi)部會(huì)根據(jù)你提供的磁盤數(shù)量或節(jié)點(diǎn)數(shù)量,去分配數(shù)據(jù)和奇偶校驗(yàn)塊,一般是對(duì)半開,確保對(duì)硬盤故障提供最佳保護(hù)。Minio糾刪碼的設(shè)計(jì)目標(biāo)是為了性能和盡可能的使用硬件加速。

五、分布式出現(xiàn)的問題

我很疑惑他是怎么知道我的 nginx1.18.0,我并沒有給 MinIO 配置過相關(guān)nginx信息。

API: SYSTEM()
Time: 17:53:35 CST 12/25/2020
DeploymentID: e660d5ad-c358-4aca-bdb5-f9859348b8c6
Error: <html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
 (*errors.errorString)
       2: cmd/notification.go:468:cmd.(*NotificationSys).updateBloomFilter.func1()
       1: pkg/sync/errgroup/errgroup.go:55:errgroup.(*Group).Go.func1()

改到如下配置即可解決

/sbin/iptables -I INPUT -p tcp --dport 9000 -j ACCEPT
export MINIO_ACCESS_KEY=minio
export MINIO_SECRET_KEY=minio@2020
./minio server \
http://10.240.30.102/home/MinIO/data1  http://10.240.30.100/home/MinIO/data1 \
http://10.240.30.102/home/MinIO/data2  http://10.240.30.100/home/MinIO/data2

之前我設(shè)置的是每個(gè)節(jié)點(diǎn)會(huì)創(chuàng)建4個(gè)目錄,現(xiàn)在改為2個(gè)目錄,并沒有在報(bào)錯(cuò)。在官網(wǎng)看到如下:

MinIO選擇最大的EC(糾刪碼)集大小,該大小劃分為驅(qū)動(dòng)器總數(shù)或給定的節(jié)點(diǎn)總數(shù)-確保保持統(tǒng)一分布,即每個(gè)節(jié)點(diǎn)每集合參與相等數(shù)量的驅(qū)動(dòng)器。

我理解的意思是,在分布式中可能單個(gè)節(jié)點(diǎn)的磁盤數(shù)量根據(jù)分布式的節(jié)點(diǎn)數(shù)量而定。

六、特性及注意

  1. 在分布式中,如果有16個(gè)節(jié)點(diǎn),其中8個(gè)節(jié)點(diǎn)蹦了,依然可以查看,但無(wú)法編輯或上傳,只有在可用節(jié)點(diǎn)為9臺(tái)才能正常使用。
  2. 單獨(dú)給分布式其中的某一個(gè)節(jié)點(diǎn)上傳文件,文件會(huì)被同步到其他節(jié)點(diǎn)。
  3. 分布式MinIO所需的最小磁盤(目錄)為4,所以小于4就會(huì)報(bào)錯(cuò),4是所有節(jié)點(diǎn)的磁盤(目錄)之和,不是單個(gè)節(jié)點(diǎn)需要設(shè)置4個(gè)磁盤(目錄),并且使用分布式Minio自動(dòng)引入了糾刪碼功能。
  4. 2臺(tái)分布式的時(shí)候,會(huì)分配一個(gè)主的做為網(wǎng)關(guān)(VIP),當(dāng)VIP被宕,無(wú)法在通過VIP訪問到。
  5. 分布式中密鑰必須一致。
  6. 2臺(tái)分布式的時(shí)候,其中一臺(tái)掛掉另一臺(tái)無(wú)法使用任何功能。
  7. minio 自帶控制臺(tái) http://xx.xxx.xxx.xx:9000/minio/login 老是會(huì)忘記
  8. 新建的bucket上傳文件后是沒辦法查看到的,需要修改bucket讀寫權(quán)限后重新上傳。

七、整合spring boot

依賴

        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.0.3</version>
        </dependency>

控制層

package com.giant.cloud.controller;

import com.giant.cloud.service.ImgServer;
import com.giant.security.util.ResponseData;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

/**
 * @Author big uncle
 * @Date 2020/6/15 10:41
 **/
@RestController
@RequestMapping("/img")
@RefreshScope
public class ImgController {


    @Resource(name = "MinIOServer")
    private ImgServer imgServer;

    @PostMapping("/push")
    public ResponseData push(@RequestParam("file") MultipartFile file,String path,String bucket){
        return imgServer.push(bucket,path,file);
    }

    @PostMapping("/del")
    public ResponseData<Boolean> del() {
        return imgServer.del();
    }

    @PostMapping("/get")
    public ResponseData get() {
        return imgServer.download();
    }

}

服務(wù)層

package com.giant.cloud.service.impl;

import com.giant.cloud.code.UploadFileCode;
import com.giant.cloud.config.FileEnvironmentConfig;
import com.giant.cloud.service.ImgServer;
import com.giant.security.util.ResponseData;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.UUID;

/**
 * @author big uncle
 * @date 2021/1/11 17:50
 * @module
 **/
@Service(value = "MinIOServer")
public class MinIOServerImpl implements ImgServer {

    @Resource
    private ObjectServerImpl objectServer;
    @Resource
    private FileEnvironmentConfig fileEnvironmentConfig;

    @Override
    public ResponseData<String> push(String bucket,String path,MultipartFile file) {
        try {
            Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            String id = UUID.randomUUID().toString().replaceAll("-","");
            String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            String objName = id + milliSecond + fileSuffix;
            String str = objectServer.createObject(bucket,path+objName, file.getInputStream());
            return ResponseData.successResponse(fileEnvironmentConfig.getGateway()+bucket+"/"+str);
        }catch(Exception e){
            e.printStackTrace();
            return ResponseData.failureResponse(UploadFileCode.UPLOAD_FILE_CODE_1001);
        }
    }

    @Override
    public ResponseData<String> download() {
        return null;
    }

    @Override
    public ResponseData<Boolean> del() {
        return null;
    }
}

ObjectServerImpl

package com.giant.cloud.service.impl;

import cn.hutool.core.util.StrUtil;
import com.giant.cloud.code.BucketCode;
import com.giant.cloud.service.ObjectServer;
import com.giant.security.exp.impl.BasicException;
import io.minio.MinioClient;
import io.minio.ObjectWriteArgs;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.InputStream;

/**
 * @author big uncle
 * @date 2021/1/11 18:39
 * @module
 **/
@Service
public class ObjectServerImpl implements ObjectServer {

    @Resource
    private MinioClient minioClient;
    @Resource
    private BucketServerImpl bucketServer;


    @Override
    public String putObject(String bucket, String filePath, InputStream inputStream) throws Exception{
        if(StrUtil.isBlank(bucket)){
            throw new BasicException(BucketCode.BUCKET_CODE_200);
        }
        if(!bucketServer.bucketExists(bucket)){
            throw new BasicException(BucketCode.BUCKET_CODE_201);
        }
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucket).object(filePath).stream(
                        inputStream, -1, ObjectWriteArgs.MIN_MULTIPART_SIZE)
                        .contentType("image/png")
                        .build());
        return filePath;
    }

    @Override
    public String createObject(String bucket,String path, InputStream inputStream) throws Exception {
        if(!bucketServer.bucketExists(bucket)){
            bucketServer.createBucket(bucket);
        }
        return putObject(bucket,path,inputStream);
    }

    @Override
    public void delObject(String bucket,String path,String name) throws Exception {
        minioClient.removeObject(
                RemoveObjectArgs.builder().bucket(bucket).object(path+name).build());
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,185評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,446評(píng)論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,951評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,189評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,718評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,602評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,800評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,045評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評(píng)論 1 281
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,420評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,755評(píng)論 2 371

推薦閱讀更多精彩內(nèi)容