極光筆記丨搭建UMS私有云文件服務器

極光高級工程師——胡冠軍

一、背景

因UMS5.1版本當中短信簽名,郵件支持上傳本地圖片/支持上傳附件的產品需求,以及後續可能存在的需要大量文件存儲的場景,所以需做一個私有云自己的文件服務器,並且該服務器也要兼容客戶文件服務器(注:客戶文件服務器一般都是兼容S3協議的)

二、調研文件服務器

經過各種調研,選型和組內討論,最終決定選擇minIO

1.minIO簡介

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

2.minIO優勢

兼容 Amazon S3

minIO使用 Amazon S3 v2 / v4 API。

數據保護

minIO使用erasure code來防止硬件故障。即使損壞一半以上的硬盤,仍然可以從中恢復數據。

高度可用

minIO服務器可以容忍分佈式系統中高達(N / 2)-1 節點故障。

Lambda 計算

minIO服務器通過其兼容 AWS SNS / SQS 的事件通知服務觸發 Lambda 功能。支持的目標是消息隊列,如Kafka,AMQP,以及 Elasticsearch,Redis,MySQL 等數據庫。

加密和防篡改

minIO爲加密數據提供了機密性,完整性和真實性保證,而且性能開銷微乎其微。使用 AES-256-GCM,ChaCha20-Poly1305 和 AES-CBC 支持服務器端和客戶端加密。

可對接後端存儲

除了minIO自己的文件系統,還支持 DAS、 JBODs、NAS、Google 雲存儲和 Azure Blob 存儲。

sdk 支持

基於minIO輕量的特點,它得到類似 Java、Python 或 Go 等語言的 sdk 支持

一致性

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

3.minIO架構圖

minIO採用去中心化的無共享架構,對象數據被打散存放在不同節點的多塊硬盤,對外提供統一命名空間訪問,並通過Web負載均衡器或DNS輪詢(DNS round-robin)在各服務器之間實現負載均衡。

4.minIO存儲機制

4.1 基本概念

硬盤(Drive):即存儲數據的磁盤,在 minIO 啓動時,以參數的方式傳入。
組( Set ):即一組 Drive 的集合,分佈式部署根據集羣規模自動劃分一個或多個 Set ,每個 Set 中的 Drive 分佈在不同位置。一個對象存儲在一個 Set 上。
桶(Bucket):文件對象存儲的邏輯位置,對於客戶端而言,就相當於一個存放文件的頂層文件夾。

4.2 糾刪碼

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

什麼是糾刪碼呢?它是一種恢復丟失和損壞數據的數學算法,minIO 採用Reed-Solomon Code實現糾刪碼,它將對象拆分成N/2 數據塊和 N/2 奇偶校驗塊。這就意味着如果是 12 塊盤,一個對象會被分成 6 個數據塊、6 個奇偶校驗塊,您可以丟失任意 6 塊盤(不管其是存放的數據塊還是奇偶校驗塊),您仍可以從剩下的盤中的數據進行恢復。

4.3 Reed-Solomon 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重新編碼,可得到丟失的編碼。

4.4 以糾刪碼模式運行minIO

minIO會自動生成12塊盤,命令如下:

4.5 存儲形式

數據對象在minIO集羣中進行存儲時,先進行糾刪分片,後打散存儲在各硬盤上。具體爲:minIO自動在集羣內生成若干糾刪組,每個糾刪組包含一組硬盤,其數量通常爲4至16塊;對數據對象進行分片,默認策略是得到相同數量的數據分片和校驗分片;而後通過哈希算法計算出該數據對象對應的糾刪組,並將數據和校驗分片存儲至糾刪組內的硬盤上。

如上圖所示,假設某minIO集羣內糾刪組包含4塊硬盤,某數據對象名爲MyObject,其隸屬存儲桶名爲MyBucket,哈希計算得到對應的糾刪組爲Disk 1~4。那麼在Disk 1~4的數據路徑下,都會生成MyBucket/MyObject子路徑,子路徑中包含2個文件,分別爲存儲元數據信息的xl.json和MyObject對象在該盤上的第一個分片part.1。其中,xl表示minIO中數據對象的默認存儲格式。

5.minIO golang SDK簡單使用

以下上傳文件的例子可以直接運行,文件會上傳到minIO官方服務器


三、minIO在UMS系統中的實際應用

1.應用系統架構

整個架構中,模塊之間使用http協議通信,並且每個模塊的作用如下:

(1)Web/API服務器的作用是提供UMS系統的認證和鑑權,即驗證Web客戶端或者開發者API請求接口的合法性;

(2)文件管理服務器的作用是提供對外操作minIO服務器的接口,根據目前UMS系統的業務需求,只提供了獲取上傳文件presignedURL,設置過期時間, 設置對外訪問

策略,創建存儲桶,生成下載文件URL的功能;那麼什麼是presignedURL呢?它是對象所有者使用自己的安全憑證來創建預簽名的 URL,以授予有限時間內的上傳或下

載對象權限,從而與其他用戶共享對象,注:即使是私有對象使用presignedURL也可以共享給他人,並且presignedURL最大有效期爲7天。

其中文件管理服務器獲取上傳文件presignedURL的方法直接使用了minIO官方API,當然你也可以自己實現presignedURL方法,此外,由於下載presignedURL最大保留時間爲7天,不符合UMS系統業務需求,所以,文件管理服務器自己實現了一個生成下載URL的方法,此鏈接的過期時間可任意設置,但前提要把存儲桶的對外訪問策略設置爲public。由此,客戶端就可以直接使用上傳presignedURL上文件到minIO服務器,使用下載鏈接直接下載文件即可。

(3)minIO集羣作用是存儲實體文件,該集羣採用去中心化無共享架構,各節點間爲對等關係,連接至任一節點均可實現對集羣的訪問,minIO集羣前端增加了Nginx實現反向代理;minIO節點之間的通信使用的都是rpc。此外,管理minIO服務器除了上面提到的SDK以外,官方還提供了命令行和web頁面的形式,內容分別如下:

把Nginx代理ip和端口號或者minIO集羣中任意節點的ip和端口號輸入瀏覽器,輸入minIO的賬戶名和密碼即可登錄,界面如下:

2.具體交互邏輯

首先,客戶端要請求業務服務器(WebServer/APIServer)獲取上傳文件的憑證(presignedURL),然後,業務服務器響應一個上傳文件URL和下載文件的URL,客戶端使用上傳URL上傳文件到文件服務器,使用下載URL作爲請求後端的文件參數,如發送郵件消息支持上傳本地圖片,上傳到後端的圖片即可使用文件下載URL作爲參數。

該方案的優點如下:

客戶端直接上傳文件到minIO服務器,不經過業務服務器,減輕業務服務器的壓力,提高可用性
數據庫服務器只存儲文件的下載URL,減少數據庫的存儲量
支持上傳超大文件,比如3G以上等,硬件性能足夠的情況下,minIO服務器單個文件最大可達5T
上傳文件的數量沒有限制
可以解決同名文件覆蓋問題
可以適配任何兼容S3協議的文件服務器,滿足不同客戶的要求

四、minIO分佈式部署

minIO分佈式部署架構
1.1 架構概述

minIO集羣採用去中心化無共享架構,各節點間爲對等關係,連接至任一節點均可實現對集羣的訪問,這種節點間保持對等關係的設計並非最常見的分佈式集羣架構。當前大多數的分佈式存儲集羣,其節點往往可劃分爲多類角色,例如負責連接並處理外部應用請求的訪問節點、負責存儲元數據的管理節點、實際的數據存儲節點等。minIO與之不同,minIO集羣中的所有節點都同時承擔了多種角色,集元數據存儲、數據存儲、應用訪問等功能於一體,真正實現了去中心化和所有節點的完全對等。其優勢在於有效地減少了集羣內的複雜調度過程以及因中心節點帶來的故障風險和性能瓶頸。

下圖minIO集羣增加了Nginx代理:

部署minIO集羣只需一條命令,但集羣中每個節點都要執行相同的命令

其中,官方推薦節點ip要連續。

1.2 minIO擴容方案

首先,minIO的極簡設計理念使得minIO分佈式集羣並不支持向集羣中添加單個節點並進行自動調節的擴容方式,這是因爲加入單個節點後所引發的數據均衡以及糾刪組劃分等問題會爲整個集羣帶來複雜的調度和處理過程,並不利於維護。因此,minIO提供了一種對等擴容的方式,即要求增加的節點數和磁盤數均需與原集羣保持對等。

例如原集羣包含4個節點4塊磁盤,則在擴容時必須同樣增加4個節點4塊磁盤(或爲其倍數),以便系統維持相同的數據冗餘SLA,從而極大地降低擴容的複雜性。如上例,在擴容後,minIO集羣並不會對全部的8個節點進行完全的數據均衡,而是將原本的4個節點視作一個區域,新加入的4節點視作另一區域,當有新對象上傳時,集羣將依據各區域的可用空間比例確定存放區域,在各區域內仍舊通過哈希算法確定對應的糾刪組進行最終的存放。此外,集羣進行一次對等擴容後,還可依據擴容規則繼續進行對等擴容,但出於安全性考慮,集羣的最大節點數一般不得超過32個。

minIO支持通過命令,指定新的集羣來擴展現有集羣(糾刪碼模式),命令行如下:

現在整個集羣就擴展了1024個磁盤,總磁盤變爲2048個,新的對象上傳請求會自動分配到最少使用的集羣上。通過以上擴展策略,您就可以按需擴展您的集羣。重新配置後重啓集羣,會立即在集羣中生效,並對現有集羣無影響。如上命令中,我們可以把原來的集羣看做一個區,新增集羣看做另一個區,新對象按每個區域中的可用空間比例放置在區域中。在每個區域內,基於確定性哈希算法確定位置。

注:您添加的每個區域必須具有與原始區域相同的磁盤數量(糾刪碼集)大小,以便維持相同的數據冗餘SLA。 例如,第一個區有8個磁盤,您可以將集羣擴展爲16個、32個或1024個磁盤的區域,您只需確保部署的SLA是原始區域的倍數即可。

對等擴容的優點和缺點如下:

優點:在於配置操作簡單易行,通過一條命令即可完成擴容。

缺點:①擴容需重啓;②擴容存在限制,集羣節點數一般不超過32個,這是由於MinIO集羣通過分佈式鎖保證強一致性,若集羣節點數過大,維護強一致性將帶來性能問題。

但對於初期存儲量不是很大,並且集羣短暫停機重啓對業務影響不大的情況下,使用對等擴容即可。

注意事項
分佈式minIO裏所有的節點需要有同樣的access祕鑰和secret祕鑰,即:用戶名和密碼
分佈式minIO存放數據的磁盤目錄必須是空目錄
分佈式minIO官方建議生產環境最少4個節點,因爲有N個節點,得至少保證有N/2的節點才能可讀,保證至少N/2+1的節點才能可寫
分佈式minIO節點時間要相同,機器配置也要都相同
分佈式minIO會在每個磁盤都存一份數據文件保證數據的可靠性與安全性

3.具體實施步驟

網上很多人部署minIO集羣都是使用單個腳本,這在實際生產環境中很不友好,因爲minIO要求集羣中每個節點都要執行相同的命令才能啓動成功,所以最好的方式是使用ansible部署minIO集羣。

3.1 安裝ansible

3.2 使用ansible部署minIO集羣

Ansible編寫的核心代碼如下,具體細節讀者可自行百度

3.3 配置Nginx代理集羣

Nginx配置文件內容如下:

3.4 驗證minIO集羣是否部署成功

在瀏覽器上,輸入Nginx所在服務器的地址外加Nginx配置裏的監聽端口即可訪問文件服務器web頁面,部署成功的效果如下:

五、結語

以上就是UMS私有云文件服務開發以及部署的主要內容,該方案已經得到實施驗證,如果您想搭建兼容S3協議的文件服務器,那麼該篇文章有參考價值,當然由於時間倉促並且初期文件存儲量不是很大,該方案也有需要優化的地方,比如想實現動態擴容機制可以採用官方聯邦擴容方式,不過這需要引入etcd,也需要更多的機器。總之,您還是需要根據具體業務場景來定,就像買鞋子不是越大越好,合腳的纔是最好的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章