Minio 文件服務(1)—— Minio部署使用及存儲機制分析

Minio 文件服務(1)—— Minio部署使用及存儲機制分析
Minio 文件服務(2)—— Minio用Nginx做負載均衡

本文參考Minio官方文檔,使用細節里面說的很詳細,本文主要講解文檔中較少涉及的Minio存儲機制。以及我在使用中部署和使用Java SDK訪問的過程。

簡介

Minio 是一個基于Apache License v2.0開源協議的對象存儲服務。它兼容亞馬遜S3云存儲服務接口,非常適合于存儲大容量非結構化的數據,例如圖片、視頻、日志文件、備份數據和容器/虛擬機鏡像等,而一個對象文件可以是任意大小,從幾kb到最大5T不等。
Minio是一個非常輕量的服務,可以很簡單的和其他應用的結合,類似 NodeJS, Redis 或者 MySQL。

存儲機制

Minio使用糾刪碼erasure code和校驗和checksum來保護數據免受硬件故障和無聲數據損壞。 即便丟失一半數量(N/2)的硬盤,仍然可以恢復數據。

糾刪碼

糾刪碼是一種恢復丟失和損壞數據的數學算法,目前,糾刪碼技術在分布式存儲系統中的應用主要有三類,陣列糾刪碼(Array Code: RAID5、RAID6等)、RS(Reed-Solomon)里德-所羅門類糾刪碼和LDPC(LowDensity Parity Check Code)低密度奇偶校驗糾刪碼。Erasure Code是一種編碼技術,它可以將n份原始數據,增加m份數據,并能通過n+m份中的任意n份數據,還原為原始數據。即如果有任意小于等于m份的數據失效,仍然能通過剩下的數據還原出來。

Minio采用Reed-Solomon code將對象拆分成N/2數據和N/2 奇偶校驗塊。因此下面主要講解RS類糾刪碼。

RS code編碼數據恢復原理:

RS編碼以word為編碼和解碼單位,大的數據塊拆分到字長為w(取值一般為8或者16位)的word,然后對word進行編解碼。 數據塊的編碼原理與word編碼原理相同,后文中以word為例說明,變量Di, Ci將代表一個word。
把輸入數據視為向量D=(D1,D2,..., Dn), 編碼后數據視為向量(D1, D2,..., Dn, C1, C2,.., Cm),RS編碼可視為如下(圖1)所示矩陣運算。
圖1最左邊是編碼矩陣(或稱為生成矩陣、分布矩陣,Distribution Matrix),編碼矩陣需要滿足任意n*n子矩陣可逆。為方便數據存儲,編碼矩陣上部是單位陣(n行n列),下部是m行n列矩陣。下部矩陣可以選擇范德蒙德矩陣或柯西矩陣。

RS最多能容忍m個數據塊被刪除。 數據恢復的過程如下:
(1)假設D1、D4、C2丟失,從編碼矩陣中刪掉丟失的數據塊/編碼塊對應的行。(圖2、3)
(2)由于B' 是可逆的,記B'的逆矩陣為 (B'^-1),則B' * (B'^-1) = I 單位矩陣。兩邊左乘B' 逆矩陣。 (圖4、5)
(3)得到如下原始數據D的計算公式 。

(4)對D重新編碼,可得到丟失的編碼碼

實踐

Minio采用Reed-Solomon code將對象拆分成N/2數據和N/2 奇偶校驗塊。 這就意味著如果是12塊盤,一個對象會被分成6個數據塊、6個奇偶校驗塊,可以丟失任意6塊盤(不管其是存放的數據塊還是奇偶校驗塊),仍可以從剩下的盤中的數據進行恢復。

以下是我在4個節點上部署的集群,部署代碼如下面多節點部署所示。

1、我在minio服務中上傳了一個hello.txt文件,內容為:hello,how are you?\n 共20個字符。
2、然后在對應的bucket里會生成一個名為hello.txt的文件夾,文件夾里有2個文件,查看4個節點的part.1文件,會發現其中2個文件均分存放了原始數據hello,how are you?\n ,另外2個文件是亂碼,但是根據上述分析應該存的就是奇偶校驗塊,充當編碼矩陣的作用。因此part.1文件是存儲就刪碼的。
(數據塊和奇偶校驗塊所存儲的節點位置不是固定不變的)

3、而另一個json文件中的內容如下,對比了4個節點xl.json文件的差別,發現只有index和checksum中的hash值不同。因此這個json文件是存儲校驗和的。保護數據免受無聲數據損壞。

模擬數據丟失的情況

新建一個happy.txt文件,上傳至文件服務,在服務器的4個節點上可以看見該文件生成了一個part.1和xl.json文件。
第一步刪除005號服務器上的數據塊,下載該文件,可讀;
第二步刪除004號服務器上的數據塊,下載該文件,可讀;
第二步刪除003號服務器上的數據塊,下載該文件,不可讀,得到空白文件;因為丟失的硬盤數量大于N/2,不可恢復健康數據。

模擬checksum丟失的情況

新建一個sing.txt文件,上傳至文件服務,在服務器的4個節點上可以看見該文件生成了一個part.1和xl.json文件。
第一步刪除005號服務器上的校驗塊,下載該文件,可讀;
第二步刪除004號服務器上的校驗塊,下載該文件,可讀;
第二步刪除003號服務器上的校驗塊,下載該文件,不可讀,頁面報異常,返回頁面后該文件已不存在。
再看服務器中但存儲,文件名變為.CORRUPTED后綴。文件被損壞。

單機Minio服務存在單點故障,相反,如果是一個N節點的分布式Minio,只要有N/2節點在線,你的數據就是安全的。不過你需要至少有N/2+1個節點 Quorum 來創建新的對象。
例如,一個8節點的Minio集群,每個節點一塊盤,就算4個節點宕機,這個集群仍然是可讀的,不過你需要5個節點才能寫數據。

部署

單節點

(容器部署)

docker pull minio/minio
 
#在Docker中運行Minio單點模式
docker run -p 9000:9000 -e MINIO_ACCESS_KEY=sunseaiot -e MINIO_SECRET_KEY=sunseaiot minio/minio server /data
 
#要創建具有永久存儲的Minio容器,您需要將本地持久目錄從主機操作系統映射到虛擬配置~/.minio 并導出/data目錄
#建立外掛文件夾 /Users/hbl/dockersp/volume/minio/
docker run -p 9000:9000 -e MINIO_ACCESS_KEY=sunseaiot -e MINIO_SECRET_KEY=sunseaiot -v /Users/hbl/dockersp/volume/minio/data:/data -v /Users/hbl/dockersp/volume/minio/config:/root/.minio minio/minio server /data

多節點

分布式搭建的流程和單節點基本一樣,Minio服務基于命令行傳入的參數自動切換成單機模式還是分布式模式。

分布式Minio單租戶存在最少4個盤最多16個盤的限制(受限于糾刪碼)。這種限制確保了Minio的簡潔,同時仍擁有伸縮性。如果你需要搭建一個多租戶環境,你可以輕松的使用編排工具(Kubernetes)來管理多個Minio實例。

糾刪碼 (多塊硬盤 / 服務)

項目 參數
最大驅動器數量 16
最小驅動器數量 4
讀仲裁 N / 2
寫仲裁 N / 2+1

(多節點部署如果要使用容器需要用docker swarm 和K8s,文檔中有介紹,本文重點不在此因此我直接在4個服務器上安裝了Minio,直接運行即可。Minio服務基于命令行傳入的參數自動切換成單機模式還是分布式模式,啟動一個分布式Minio實例,你只需要把硬盤位置做為參數傳給minio server命令即可,然后,你需要在所有其它節點運行同樣的命令。)

部署4主機,每機單塊磁盤(drive)

export MINIO_ACCESS_KEY=123456
export MINIO_SECRET_KEY=123456
./minio server http://192.168.8.110/export1 \
               http://192.168.8.111/export2 \
               http://192.168.8.112/export3 \
               http://192.168.8.113/export4

部署4主機,每機2塊磁盤(drives)

export MINIO_ACCESS_KEY=123456
export MINIO_SECRET_KEY=123456
./minio server http://192.168.8.110/export1 http://192.168.1.110/export2 \
               http://192.168.8.111/export1 http://192.168.1.111/export2 \          
               http://192.168.8.112/export1 http://192.168.1.112/export2 \
               http://192.168.8.113/export1 http://192.168.1.113/export2

后臺運行

由于不是用docker部署的,所以需要將進程加入后臺運行。使用nohup指令。

export MINIO_ACCESS_KEY=SunseaIoT2018!
export MINIO_SECRET_KEY=SunseaIoT2018!
nohup ./minio server http://192.168.8.110/minio1 \
               http://192.168.8.111/minio2 \
               http://192.168.8.112/minio3 \
               http://192.168.8.113/minio4 >  out.file  2>&1  & 

使用

部署好Minio服務后可以通過瀏覽器訪問。輸入設置好的用戶名和密碼即可進行操作。

Java SDK訪問Minio服務

package com.minio.client;

import io.minio.MinioClient;
import io.minio.errors.MinioException;
import lombok.extern.slf4j.Slf4j;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

@Slf4j
public class FileUploader {
    public static void main(String[] args) throws NoSuchAlgorithmException, IOException, InvalidKeyException, XmlPullParserException {
        try {
            MinioClient minioClient = new MinioClient("https://minio.sunseaiot.com", "sunseaiot", "sunseaiot",true);

            // 檢查存儲桶是否已經存在
            if(minioClient.bucketExists("ota")) {
                log.info("Bucket already exists.");
            } else {
                // 創建一個名為ota的存儲桶
                minioClient.makeBucket("ota");
                log.info("create a new bucket.");
            }

            //獲取下載文件的url,直接點擊該url即可在瀏覽器中下載文件
            String url = minioClient.presignedGetObject("ota","hello.txt");
            log.info(url);

            //獲取上傳文件的url,這個url可以用Postman工具測試,在body里放入需要上傳的文件即可
            String url2 = minioClient.presignedPutObject("ota","ubuntu.tar");
            log.info(url2);

            // 下載文件到本地
            minioClient.getObject("ota","hello.txt", "/Users/hbl/hello2.txt");
            log.info("get");

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

推薦閱讀更多精彩內容