Storage-Minio的原理和K8S部署


image

一、OSS簡介

1.1、Object Storage Service

對象存儲服務(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應用場景

  • 單主機單硬盤模式
    image
  • 單主機多硬盤模式
    image
  • 多主機多硬盤分布式
    image

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列矩陣。下部矩陣可以選擇范德蒙德矩陣或柯西矩陣。

image

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

  • 存儲形式
    image

  • 上圖直觀地展示了每個節點上的數據存放形式。所有對象的編碼塊和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部署

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
[root@master 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM