一:簡介
一、背景
1. Swift 最初是由 Rackspace 公司開發的高可用分散式物件儲存服務(Object Storage Service),並於 2010 年貢獻給 OpenStack 開源社群作為其最初的核心子專案之一,為其 Nova 子專案提供虛機映象儲存服務。Swift 構築在比較便宜的標準硬體儲存基礎設施之上,無需採用 RAID(磁碟冗餘陣列),通過在軟體層面引入一致性雜湊技術和資料冗餘性,犧牲一定程度的資料一致性來達到高可用性和可伸縮性,支援多租戶模式、容器和物件讀寫操作,適合解決網際網路的應用場景下非結構化資料儲存問題。
2. Swift 包括2個組成部分,一個是代理服務(proxy),一個是儲存服務(storage)。
1. 代理服務是Swift內部儲存的拓撲邏輯,即一個具體檔案位於哪個儲存節點的哪個區上。它同時是一個web伺服器,通過http或https對外提供REST API服務。
2. 儲存服務是負責檔案儲存的服務,由3個元件組成:account-server、container-server、object-server。其中object-server負責具體的檔案儲存,container-server包含到每個object的索引,account-server包含到每個container 的索引。
二、原理
1. 一致性雜湊(Consistent Hashing):Swift 是基於一致性雜湊技術,通過計算可將物件均勻分佈到虛擬空間的虛擬節點上,在增加或刪除節點時可大大減少需移動的資料量;虛擬空間大小通常採用 2 的 n 次冪,便於進行高效的移位操作;然後通過獨特的資料結構 Ring(環)再將虛擬節點對映到實際的物理儲存裝置上,完成定址過程。
1. 平衡性:平衡性是指雜湊的結果能夠儘可能的分佈到所有的緩衝中去,這樣可以使得所有緩衝空間能夠都得到利用。為了更好的滿足平衡性,引入了虛擬節點概念,虛擬節點是實際節點在hash空間的複製品,一個實際節點對應若干個虛擬節點,這個對應的個數也稱為複製個數,虛擬節點在hash空間以hash值排列。
2. 單調性:單調性是指如果已經有些內容通過Hash分派到相應的緩衝中,又有新的緩衝加入到系統中,雜湊的結果應能夠保證原有已分配的內容可以被對映到原有或者新的緩衝中區,而不會被對映到舊的或者其他緩衝區。
3. 分散性:在分散式環境中,客戶端可能看不到所有的緩衝,而只能看到其中一部分。當終端希望通過雜湊過程將內容對映到緩衝上時,由於不同的客戶端所看到的緩衝範圍可能不同,從而導致得到的Hash結果不一致,導致結果相同的內容被對映到不用的緩衝區中。這種情況應該被避免,因為這將會導致相同的內容將會被對映到不同緩衝區中,降低了系統的儲存效率。
4. 負載:負載時對分散性要求的另一個維度。既然相同的內容可能被對映到不同的緩衝中去,那麼對於同一個緩衝而言,就有可能被不同的使用者對映不同的內容。與分散性一樣,這種情況應該被避免。
5. 如圖所示,以逆時針方向遞增的雜湊空間有 4 個位元組長共 32 位,整數範圍是[0~232-1];將雜湊結果右移 m 位,可產生 232-m個虛擬節點,例如 m=29 時可產生 8 個虛擬節點。在實際部署的時候需要經過仔細計算得到合適的虛擬節點數,以達到儲存空間和工作負載之間的平衡。
2. 資料一致性模型(Consistency Model)
1. 按照 Eric Brewer 的 CAP(Consistency,Availability,Partition Tolerance)理論,無法同時滿足 3 個方面,Swift 放棄嚴格一致性(滿足 ACID 事務級別),而採用最終一致性模型(Eventual Consistency),來達到高可用性和無限水平擴充套件能力。為了實現這一目標,Swift 採用 Quorum 仲裁協議(Quorum 有法定投票人數的含義):
1. 定義:N:資料的副本總數;W:寫操作被確認接受的副本數量;R:讀操作的副本數量
2. 強一致性:R+W>N,以保證對副本的讀寫操作會產生交集,從而保證可以讀取到最新版本;如果 W=N,R=1,則需要全部更新,適合大量讀少量寫操作場景下的強一致性;如果 R=N,W=1,則只更新一個副本,通過讀取全部副本來得到最新版本,適合大量寫少量讀場景下的強一致性。
3. 弱一致性:R+W<=N,如果讀寫操作的副本集合不產生交集,就可能會讀到髒資料;適合對一致性要求比較低的場景。
2. Swift 針對的是讀寫都比較頻繁的場景,所以採用了比較折中的策略,即寫操作需要滿足至少一半以上成功 W >N/2,再保證讀操作與寫操作的副本集合至少產生一個交集,即 R+W>N。Swift 預設配置是 N=3,W=2>N/2,R=1 或 2,即每個物件會存在 3 個副本,這些副本會盡量被儲存在不同區域的節點上;W=2 表示至少需要更新 2 個副本才算寫成功;當 R=1 時意味著某一個讀操作成功便立刻返回,此種情況下可能會讀取到舊版本(弱一致性模型);當 R=2 時,需要通過在讀操作請求頭中增加 x-newest=true 引數來同時讀取 2 個副本的後設資料資訊,然後比較時間戳來確定哪個是最新版本(強一致性模型);如果資料出現了不一致,後臺服務程式會在一定時間視窗內通過檢測和複製協議來完成資料同步,從而保證達到最終一致性。如圖 2 所示:
3. 環的資料結構
1. 環是為了將虛擬節點(分割槽)對映到一組物理儲存裝置上,並提供一定的冗餘度而設計的,其資料結構由以下資訊組成:
1. 儲存裝置列表、裝置資訊包括唯一標識號(id)、區域號(zone)、權重(weight)、IP 地址(ip)、埠(port)、裝置名稱(device)、後設資料(meta)。
2. 分割槽到裝置對映關係(replica2part2dev_id 陣列)。
3. 計算分割槽號的位移(part_shift 整數,即圖 1 中的 m)。
2. 使用物件的層次結構 account/container/object 作為鍵,使用 MD5 雜湊演算法得到一個雜湊值,對該雜湊值的前 4 個位元組進行右移操作得到分割槽索引號,移動位數由上面的 part_shift 設定指定;按照分割槽索引號在分割槽到裝置對映表(replica2part2dev_id)裡查詢該物件所在分割槽的對應的所有裝置編號,這些裝置會被儘量選擇部署在不同區域(Zone)內,區域只是個抽象概念,它可以是某臺機器,某個機架,甚至某個建築內的機群,以提供最高階別的冗餘性,建議至少部署 5 個區域;權重引數是個相對值,可以來根據磁碟的大小來調節,權重越大表示可分配的空間越多,可部署更多的分割槽。
4. 資料模型
1. Swift 採用層次資料模型,共設三層邏輯結構:Account/Container/Object(即賬戶/容器/物件),每層節點數均沒有限制,可以任意擴充套件。
2. 賬戶和個人賬戶不是一個概念,可理解為租戶,用來做頂層的隔離機制,可以被多個個人賬戶所共同使用;
3. 容器代表封裝一組物件,類似資料夾或目錄;葉子節點代表物件,由後設資料和內容兩部分組成,如圖所示:
三、特性
1. 大量物件的儲存(Storage of large number of objects)。
2. 大物件的儲存(Storage of large sized objects)。
3. 資料冗餘(Data Redundancy)。
4. 檔案能力——儲存大資料集(Archival capabilities - Work with large datasets)。
5. 虛擬機器和雲應用的資料容器(Data container for virtual machines and cloud apps)。
6. 流媒體的能力(Media Streaming capabilities)。
7. 物件儲存安全(Secure storage of objects)。
8. 備份和檔案(Backup and archival)。
9. 極高的擴充套件性(Extreme scalability)
二:架構
一、核心架構
二、元件詳解
1. 代理服務(Proxy Server):對外提供物件服務 API,會根據環的資訊來查詢服務地址並轉發使用者請求至相應的賬戶、容器或者物件服務;由於採用無狀態的 REST 請求協議,可以進行橫向擴充套件來均衡負載。
2. 認證服務(Authentication Server):驗證訪問使用者的身份資訊,並獲得一個物件訪問令牌(Token),在一定的時間內會一直有效;驗證訪問令牌的有效性並快取下來直至過期時間。
3. 快取服務(Cache Server):快取的內容包括物件服務令牌,賬戶和容器的存在資訊,但不會快取物件本身的資料;快取服務可採用 Memcached 叢集,Swift 會使用一致性雜湊演算法來分配快取地址。
4. 賬戶服務(Account Server):提供賬戶後設資料和統計資訊,並維護所含容器列表的服務,每個賬戶的資訊被儲存在一個 SQLite 資料庫中。
5. 容器服務(Container Server):提供容器後設資料和統計資訊,並維護所含物件列表的服務,每個容器的資訊也儲存在一個 SQLite 資料庫中。
6. 物件服務(Object Server):提供物件後設資料和內容服務,每個物件的內容會以檔案的形式儲存在檔案系統中,後設資料會作為檔案屬性來儲存,建議採用支援擴充套件屬性的 XFS 檔案系統。
7. 複製服務(Replicator):會檢測本地分割槽副本和遠端副本是否一致,具體是通過對比雜湊檔案和高階水印來完成,發現不一致時會採用推式(Push)更新遠端副本,例如物件複製服務會使用遠端檔案拷貝工具 rsync 來同步;另外一個任務是確保被標記刪除的物件從檔案系統中移除。
8. 更新服務(Updater):當物件由於高負載的原因而無法立即更新時,任務將會被序列化到在本地檔案系統中進行排隊,以便服務恢復後進行非同步更新;例如成功建立物件後容器伺服器沒有及時更新物件列表,這個時候容器的更新操作就會進入排隊中,更新服務會在系統恢復正常後掃描佇列並進行相應的更新處理。
9. 審計服務(Auditor):檢查物件,容器和賬戶的完整性,如果發現位元級的錯誤,檔案將被隔離,並複製其他的副本以覆蓋本地損壞的副本;其他型別的錯誤會被記錄到日誌中。
10. 賬戶清理服務(Account Reaper):移除被標記為刪除的賬戶,刪除其所包含的所有容器和物件。
三、Swift對CAP的支援程度
1. CAP概述:美國著名科學家,Berkerly大學Brewer教授提出的一個分散式系統不能同時滿足一致性,可用性和分割槽容錯性這三個需求,最多隻能同時滿足兩個。重要屬性:
1. 一致性(Consistency):任何一個讀操作總是能讀取到之前完成的寫操作結果,也就是在分散式環境中,多點的資料是一致的。
2. 可用性(Availability):每一個操作總是能夠在確定的時間內返回,也就是系統隨時都是可用的。
3. 分割槽可容忍性(Tolerance of network Partition):在出現網路分割槽(比如斷網)的情況下,分離的系統也能正常執行。
2. Swift對CAP的支援
1. Consistency:Swift的一致性歸為弱一致性模型。Swift 由 updater 保證最終一致性,auditor 保證儲存物件的完整性。Swift 只能保證資料的最終一致性,即,如果upload(update也是一種upload)一個object,從其他客戶端GET這個object,不一定是最新的。
2. Availability:基於python對hash的 原生支援,swift中廣泛使用了hash演算法。比如均衡ring中partition的分佈,object update備份策略。sqlite控制account/container/object的相關資訊,簡化了維護成本。
三:常用操作