天天看點

Storage-Minio的原理和K8S部署一、OSS簡介二、Minio簡介三、Minio部署四、SDK

Storage-Minio的原理和K8S部署一、OSS簡介二、Minio簡介三、Minio部署四、SDK

Storage-Minio的原理和K8S部署

  • 一、OSS簡介
    • 1.1、Object Storage Service
    • 1.2、OSS相關概念
  • 二、Minio簡介
    • 2.1、Minio
    • 2.2、Minio應用場景
    • 2.3、Minio特點
    • 2.4、存儲機制(資料編碼)
    • 2.5、分布式
  • 三、Minio部署
    • 3.1、docker部署
    • 3.2、helm部署minio
      • 3.2.1、建立持久化存儲
      • 3.2.2、helm部署
      • 3.3.3、配置Ingress外部通路
  • 四、SDK

一、OSS簡介

1.1、Object Storage Service

  • 何為對象存儲?我們來看下阿裡雲 OSS (Object Storage Service)的介紹:https://link.zhihu.com/?target=https%3A//helpcdn.aliyun.com/product/31815.html
對象存儲服務(Object Storage Service,OSS)是一種海量、安全、低成本、高可靠的雲存儲服務,适合存放任意類型的檔案。容量和處理能力彈性擴充,多種存儲類型供選擇,全面優化存儲成本。
  • 對于中小型企業,如果不選擇存儲上雲,那麼 Minio 是個不錯的選擇,麻雀雖小,五髒俱全。當然 Minio 除了直接作為對象存儲使用,還可以作為雲上對象存儲服務的網關層,無縫對接到 Amazon S3、MicroSoft Azure。

1.2、OSS相關概念

  • 存儲類型(Storage Class)
    • OSS提供标準、低頻通路、歸檔、冷歸檔四種存儲類型,全面覆寫從熱到冷的各種資料存儲場景。其中标準存儲類型提供高持久、高可用、高性能的對象存儲服務,能夠支援頻繁的資料通路;低頻通路存儲類型适合長期儲存不經常通路的資料(平均每月通路頻率1到2次),存儲單價低于标準類型;歸檔存儲類型适合需要長期儲存(建議半年以上)的歸檔資料;冷歸檔存儲适合需要超長時間存放的極冷資料。更多資訊,請參見存儲類型介紹。
  • 存儲空間(Bucket)
    • 存儲空間是您用于存儲對象(Object)的容器,所有的對象都必須隸屬于某個存儲空間。存儲空間具有各種配置屬性,包括地域、通路權限、存儲類型等。您可以根據實際需求,建立不同類型的存儲空間來存儲不同的資料。
  • 對象(Object)
    • 對象是OSS存儲資料的基本單元,也被稱為OSS的檔案。對象由元資訊(Object Meta)、使用者資料(Data)和檔案名(Key)組成。對象由存儲空間内部唯一的Key來辨別。對象元資訊是一組鍵值對,表示了對象的一些屬性,例如最後修改時間、大小等資訊,同時您也可以在元資訊中存儲一些自定義的資訊。
  • 地域(Region)
    • 地域表示OSS的資料中心所在實體位置。您可以根據費用、請求來源等選擇合适的地域建立Bucket。更多資訊,請參見OSS已開通的地域。
  • 通路域名(Endpoint)
    • Endpoint表示OSS對外服務的通路域名。OSS以HTTP RESTful API的形式對外提供服務,當通路不同地域的時候,需要不同的域名。通過内網和外網通路同一個地域所需要的域名也是不同的。更多資訊,請參見各個Region對應的Endpoint。
  • 通路密鑰(AccessKey)
    • AccessKey簡稱AK,指的是通路身份驗證中用到的AccessKey ID和AccessKey Secret。OSS通過使用AccessKey ID和AccessKey Secret對稱加密的方法來驗證某個請求的發送者身份。AccessKey ID用于辨別使用者;AccessKey Secret是使用者用于加密簽名字元串和OSS用來驗證簽名字元串的密鑰,必須保密。關于擷取AccessKey的方法,請參見建立AccessKey。

二、Minio簡介

2.1、Minio

  • Minio 是一個基于Apache License v2.0開源協定的對象存儲服務。它相容亞馬遜S3雲存儲服務接口,非常适合于存儲大容量非結構化的資料,例如圖檔、視訊、日志檔案、備份資料和容器/虛拟機鏡像等,而一個對象檔案可以是任意大小,從幾kb到最大5T不等。
  • Minio是一個非常輕量的服務,可以很簡單的和其他應用的結合;
  • Minio 是個基于 Golang 編寫的開源對象存儲套件,雖然輕量,卻擁有着不錯的性能。
  • 官網位址:MinIO | High Performance, Kubernetes Native Object Storage

2.2、Minio應用場景

  • 單主機單硬碟模式
    Storage-Minio的原理和K8S部署一、OSS簡介二、Minio簡介三、Minio部署四、SDK
  • 單主機多硬碟模式
    Storage-Minio的原理和K8S部署一、OSS簡介二、Minio簡介三、Minio部署四、SDK
  • 多主機多硬碟分布式
    Storage-Minio的原理和K8S部署一、OSS簡介二、Minio簡介三、Minio部署四、SDK

2.3、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的磁盤也能恢複資料

2.4、存儲機制(資料編碼)

  • 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份的資料失效,仍然能通過剩下的資料還原出來。
  • Reed-Solomon算法
    • Minio采用Reed-Solomon code将對象拆分成N/2資料和N/2 奇偶校驗塊。 這就意味着如果是12塊盤,一個對象會被分成6個資料塊、6個奇偶校驗塊,可以丢失任意6塊盤(不管其是存放的資料塊還是奇偶校驗塊),仍可以從剩下的盤中的資料進行恢複。
    • 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列矩陣。下部矩陣可以選擇範德蒙德矩陣或柯西矩陣。
Storage-Minio的原理和K8S部署一、OSS簡介二、Minio簡介三、Minio部署四、SDK
  • RS最多能容忍m個資料塊被删除。 資料恢複的過程如下:
    • 1、假設D1、D4、C2丢失,從編碼矩陣中删掉丢失的資料塊/編碼塊對應的行。(圖2、3)
    • 2、由于B’ 是可逆的,記B’的逆矩陣為 (B’^-1),則B’ * (B’^-1) = I 機關矩陣。兩邊左乘B’ 逆矩陣。 (圖4、5)
    • 3、得到如下原始資料D的計算公式 。
      Storage-Minio的原理和K8S部署一、OSS簡介二、Minio簡介三、Minio部署四、SDK
    • 4、對D重新編碼,可得到丢失的編碼
  • 存儲形式
    Storage-Minio的原理和K8S部署一、OSS簡介二、Minio簡介三、Minio部署四、SDK
  • 上圖直覺地展示了每個節點上的資料存放形式。所有對象的編碼塊和meta資訊,最終是以目錄和檔案的形式,存儲在檔案系統上的。
  • 比如My Bucket就是在所有節點的頂級目錄建立了對應的目錄叫My Bucket。然後當我們上傳一個對象的時候,就會在這個對象所對應的Set上面建立一個目錄叫My Object,之後把所有編碼塊的資料跟meta資訊都儲存在此目錄下面,這就是MinIO的真實存儲資料的方式。
  • meta資料是json檔案,編碼塊是part.1檔案。黑色的右圖是meta資訊示例圖,裡面除了包含正常的meta資訊外,還包括了怎樣做ec編碼,以便之後可以解碼出來。

2.5、分布式

分布式好處

  • 分布式Minio可以讓你将多塊硬碟(甚至在不同的機器上)組成一個對象存儲服務。由于硬碟分布在不同的節點上,分布式Minio避免了單點故障

資料保護

  • 分布式Minio采用 糾删碼來防範多個節點當機和位衰減bit rot。
  • 分布式Minio至少需要4個硬碟,使用分布式Minio自動引入了糾删碼功能。

高可用

  • 單機Minio服務存在單點故障,相反,如果是一個有N塊硬碟的分布式Minio,隻要有N/2硬碟線上,你的資料就是安全的。不過你需要至少有N/2+1個硬碟來建立新的對象。
  • 例如,一個16節點的Minio叢集,每個節點16塊硬碟,就算8台服務器當機,這個叢集仍然是可讀的,不過你需要9台服務器才能寫資料。
  • 注意,隻要遵守分布式Minio的限制,你可以組合不同的節點和每個節點幾塊硬碟。比如,你可以使用2個節點,每個節點4塊硬碟,也可以使用4個節點,每個節點兩塊硬碟,諸如此類。

一緻性

  • Minio在分布式和單機模式下,所有讀寫操作都嚴格遵守read-after-write一緻性模型。

糾删碼

  • Minio使用糾删碼erasure code和校驗和checksum來保護資料免受硬體故障和無聲資料損壞。 即便您丢失一半數量(N/2)的硬碟,您仍然可以恢複資料。

什麼是糾删碼erasure code?

  • 糾删碼是一種恢複丢失和損壞資料的數學算法, Minio采用Reed-Solomon code将對象拆分成N/2資料和N/2 奇偶校驗塊。 這就意味着如果是12塊盤,一個對象會被分成6個資料塊、6個奇偶校驗塊,你可以丢失任意6塊盤(不管其是存放的資料塊還是奇偶校驗塊),你仍可以從剩下的盤中的資料進行恢複,是不是很NB,感興趣的同學請自行google。

為什麼糾删碼有用?

  • 糾删碼的工作原理和RAID或者複制不同,像RAID6可以在損失兩塊盤的情況下不丢資料,而Minio糾删碼可以在丢失一半的盤的情況下,仍可以保證資料安全。 而且Minio糾删碼是作用在對象級别,可以一次恢複一個對象,而RAID是作用在卷級别,資料恢複時間很長。 Minio對每個對象單獨編碼,存儲服務一經部署,通常情況下是不需要更換硬碟或者修複。Minio糾删碼的設計目标是為了性能和盡可能的使用硬體加速。

什麼是位衰減bit rot保護?

  • 位衰減又被稱為資料腐化Data Rot、無聲資料損壞Silent Data Corruption,是目前硬碟資料的一種嚴重資料丢失問題。硬碟上的資料可能會神不知鬼不覺就損壞了,也沒有什麼錯誤日志。正所謂明槍易躲,暗箭難防,這種背地裡犯的錯比硬碟直接咔咔宕了還危險。 不過不用怕,Minio糾删碼采用了高速 HighwayHash 基于哈希的校驗和來防範位衰減。

三、Minio部署

3.1、docker部署

docker pull minio/minio     
docker run -p 9000:9000 minio/minio server /data     
           

3.2、helm部署minio

3.2.1、建立持久化存儲

1、給node打标簽
	# kubectl label node aliyun_beijing_node01 minio_role=standalone

2、建立storage、PV
# pv 、torageclass是叢集資源,不區分名稱空間,這裡使用了節點親和性
# cat storage-minio.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage-minio
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv-minio
spec:
  capacity:
    storage: 500Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-storage-minio
  local:
    path: /storage/data/minio
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: minio_role
          operator: In
          values:
          - standalone
          - distributed
           

3.2.2、helm部署

  • 更多配置請閱讀官網配置示例 :https://artifacthub.io/packages/helm/minio/minio
helm upgrade --install minio \
--set persistence.storageClass=local-storage-minio,mode=standalone,accessKey=ACCESSKEY,secretKey=SECRETKEY \
./minio --namespace test-ns

# 更多配置示例
helm install \
--set persistence.enabled=true \
--set service.externalIPs[0]=192.168.1.7 \
--set accessKey=xxxxxxx \
--set secretKey=yyyyyyy \
--set persistence.size=1Gi \
--set resources.requests.memory=1Gi \
--set persistence.storageClass=managed-nfs-storage \
--set mode=distributed,replicas=4 \
minio/minio --generate-name
# 設定persistence.enabled=false 表示不使用持久卷存儲資料
	--set persistence.existingClaim=minio-pvc --set persistence.enabled=false
# 分布式建立mode=distributed表示分布式建立, 節點數為4個
# externalIPs外部通路IP
	--set service.externalIPs[0]=192.168.1.7
           

3.3.3、配置Ingress外部通路

  • http
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: minio
  annotations:
    kubernetes.io/ingress.class: "nginx-alpha"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: 2048m
  namespace: test-ns
spec:
  rules:
  - host: "minio.toptops.top"
    http:
      paths:
      - backend:
          serviceName: minio
          servicePort: 9000
        path: /
           
  • 如果使用cert-manager自動生成的證書,https域名通路,需要調整values.yaml
[[email protected] minio]# cat <<EOF> values.yaml
ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
  path: /
  hosts:
    - minio.xxxxxx.xxx
  tls:
    - secretName: minio-tls
      hosts:
        - minio.xxxxxx.xxx
accessKey: "xxxxxx"
secretKey: "yyyyyy"
resources:
  requests:
    memory: 1Gi
persistence:
  storageClass: minio-data
  size: 3Gi
EOF
           

四、SDK

  • python

    : https://github.com/minio/minio-py
  • go

    : https://github.com/minio/minio-go
  • java

    : https://github.com/minio/minio-java

繼續閱讀