OpenStack Object Storage(Swift)是OpenStack開源雲計算項目的子項目之一,被稱爲對象存儲,提供了強大的擴展性、冗餘和持久性。對象存儲,用於永久類型的靜態數據的長期存儲。
Swift 最初是由 Rackspace 公司開發的高可用分佈式對象存儲服務,並於 2010 年貢獻給 OpenStack 開源社區做爲其最初的核心子項目之一,爲其 Nova 子項目提供虛機鏡像存儲服務。Swift 構築在比較便宜的標準硬件存儲基礎設施之上,無需採用 RAID(磁盤冗餘陣列),經過在軟件層面引入一致性散列技術和數據冗餘性,犧牲必定程度的數據一致性來達到高可用性和可伸縮性,支持多租戶模式、容器和對象讀寫操做,適合解決互聯網的應用場景下非結構化數據存儲問題。算法
面對海量級別的對象,須要存放在成千上萬臺服務器和硬盤設備上,首先要解決尋址問題,即如何將對象分佈到這些設備地址上。Swift 是基於一致性散列技術,經過計算可將對象均勻分佈到虛擬空間的虛擬節點上,在增長或刪除節點時可大大減小需移動的數據量;虛擬空間大小一般採用 2 的 n 次冪,便於進行高效的移位操做;而後經過獨特的數據結構 Ring(環)再將虛擬節點映射到實際的物理存儲設備上,完成尋址過程。
以逆時針方向遞增的散列空間有 4 個字節長共 32 位,整數範圍是[0~232-1];將散列結果右移 m 位,可產生 232-m個虛擬節點,例如 m=29 時可產生 8 個虛擬節點。在實際部署的時候須要通過仔細計算獲得合適的虛擬節點數,以達到存儲空間和工做負載之間的平衡。數據庫
按照 Eric Brewer 的 CAP(Consistency,Availability,Partition Tolerance)理論,沒法同時知足 3 個方面,Swift 放棄嚴格一致性(知足 ACID 事務級別),而採用最終一致性模型(Eventual Consistency),來達到高可用性和無限水平擴展能力。爲了實現這一目標,Swift 採用 Quorum 仲裁協議(Quorum 有法定投票人數的含義):swift
(1)定義:N:數據的副本總數;W:寫操做被確認接受的副本數量;R:讀操做的副本數量
(2)強一致性:R+W>N,以保證對副本的讀寫操做會產生交集,從而保證能夠讀取到最新版本;若是 W=N,R=1,則須要所有更新,適合大量讀少許寫操做場景下的強一致性;若是 R=N,W=1,則只更新一個副本,經過讀取所有副原本獲得最新版本,適合大量寫少許讀場景下的強一致性。
(3)弱一致性:R+W<=N,若是讀寫操做的副本集合不產生交集,就可能會讀到髒數據;適合對一致性要求比較低的場景。api
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 個副本的元數據信息,而後比較時間戳來肯定哪一個是最新版本(強一致性模型);若是數據出現了不一致,後臺服務進程會在必定時間窗口內經過檢測和複製協議來完成數據同步,從而保證達到最終一致性。
數組
環是爲了將虛擬節點(分區)映射到一組物理存儲設備上,並提供必定的冗餘度而設計的,其數據結構由如下信息組成:
存儲設備列表、設備信息包括惟一標識號(id)、區域號(zone)、權重(weight)、IP 地址(ip)、端口(port)、設備名稱(device)、元數據(meta)。
分區到設備映射關係(replica2part2dev_id 數組)
計算分區號的位移(part_shift 整數,即圖 1 中的 m)
以查找一個對象的計算過程爲例:
使用對象的層次結構 account/container/object 做爲鍵,使用 MD5 散列算法獲得一個散列值,對該散列值的前 4 個字節進行右移操做獲得分區索引號,移動位數由上面的 part_shift 設置指定;按照分區索引號在分區到設備映射表(replica2part2dev_id)裏查找該對象所在分區的對應的全部設備編號,這些設備會被儘可能選擇部署在不一樣區域(Zone)內,區域只是個抽象概念,它能夠是某臺機器,某個機架,甚至某個建築內的機羣,以提供最高級別的冗餘性,建議至少部署 5 個區域;權重參數是個相對值,能夠來根據磁盤的大小來調節,權重越大表示可分配的空間越多,可部署更多的分區。
Swift 爲帳戶,容器和對象分別定義了的環,查找帳戶和容器的是一樣的過程。緩存
Swift 採用層次數據模型,共設三層邏輯結構:Account/Container/Object(即帳戶/容器/對象),每層節點數均沒有限制,能夠任意擴展。這裏的帳戶和我的帳戶不是一個概念,可理解爲租戶,用來作頂層的隔離機制,能夠被多個我的帳戶所共同使用;容器表明封裝一組對象,相似文件夾或目錄;葉子節點表明對象,由元數據和內容兩部分組成,如圖 4 所示:
服務器
Swift 採用徹底對稱、面向資源的分佈式系統架構設計,全部組件均可擴展,避免因單點失效而擴散並影響整個系統運轉;通訊方式採用非阻塞式 I/O 模式,提升了系統吞吐和響應能力。
代理服務(Proxy Server)
:對外提供對象服務 API,會根據環的信息來查找服務地址並轉發用戶請求至相應的帳戶、容器或者對象服務;因爲採用無狀態的 REST 請求協議,能夠進行橫向擴展來均衡負載。 認證服務(Authentication Server)
:驗證訪問用戶的身份信息,並得到一個對象訪問令牌(Token),在必定的時間內會一直有效;驗證訪問令牌的有效性並緩存下來直至過時時間。 緩存服務(Cache Server)
:緩存的內容包括對象服務令牌,帳戶和容器的存在信息,但不會緩存對象自己的數據;緩存服務可採用 Memcached 集羣,Swift 會使用一致性散列算法來分配緩存地址。 帳戶服務(Account Server)
:提供帳戶元數據和統計信息,並維護所含容器列表的服務,每一個帳戶的信息被存儲在一個 SQLite 數據庫中。 容器服務(Container Server)
:提供容器元數據和統計信息,並維護所含對象列表的服務,每一個容器的信息也存儲在一個 SQLite 數據庫中。 對象服務(Object Server)
:提供對象元數據和內容服務,每一個對象的內容會以文件的形式存儲在文件系統中,元數據會做爲文件屬性來存儲,建議採用支持擴展屬性的 XFS 文件系統。 複製服務(Replicator)
:會檢測本地分區副本和遠程副本是否一致,具體是經過對比散列文件和高級水印來完成,發現不一致時會採用推式(Push)更新遠程副本,例如對象複製服務會使用遠程文件拷貝工具 rsync 來同步;另一個任務是確保被標記刪除的對象從文件系統中移除。 更新服務(Updater)
:當對象因爲高負載的緣由而沒法當即更新時,任務將會被序列化到在本地文件系統中進行排隊,以便服務恢復後進行異步更新;例如成功建立對象後容器服務器沒有及時更新對象列表,這個時候容器的更新操做就會進入排隊中,更新服務會在系統恢復正常後掃描隊列並進行相應的更新處理。 審計服務(Auditor)
:檢查對象,容器和帳戶的完整性,若是發現比特級的錯誤,文件將被隔離,並複製其餘的副本以覆蓋本地損壞的副本;其餘類型的錯誤會被記錄到日誌中。 帳戶清理服務(Account Reaper)
:移除被標記爲刪除的帳戶,刪除其所包含的全部容器和對象。restful
數據持久性和系統可用性不一樣,指的是數據的可靠性,數據存儲到系統後,到某一天丟失的可能性。AS3的數據持久性是11個9,即若是存儲1萬個(4個0)文件到S3中,1千萬(7個0)年以後,可能會丟失1個文件。
咱們從理論上測算過,Swift在5個Zone、5×10個存儲節點的環境下,數據複製份是爲3,數據持久性的SLA能達到10個9。markdown
「對稱」意味着Swift中各節點能夠徹底對等,能極大地下降系統維護成本。數據結構
(1)數據存儲容量無限可擴展;(2)Swift性能(如QPS、吞吐量等)可線性提高
Swift是徹底對稱的架構,擴容只需簡單地新增機器,系統會自動完成數據遷移等工做,使各存儲節點從新達到平衡狀態。
元數據問題,Swift的元數據存儲是徹底均勻隨機分佈的,而且與對象文件存儲同樣,元數據也會存儲多份。
設計簡單
最典型的應用是網盤類的存儲引擎,好比Dropbox背後使用的就是AS3。在OpenStack中還能夠與鏡像服務Glance結合,爲其存儲鏡像文件。另外,因爲Swift的無限擴展能力,很是適合用於存儲日誌文件和數據備份倉庫。
Swift主要有三個組成部分:Proxy Server、Storage Server和Consistency Server。其架構如圖1所示,其中Storage和Consistency服務均容許在Storage Node上。Auth認證服務目前已從Swift中剝離出來,使用OpenStack的認證服務Keystone,目的在於實現統一OpenStack各個項目間的認證管理。
Swift 經過 Proxy Server 向外提供基於 HTTP 的 REST 服務接口,對帳戶、容器和對象進行 CRUD 等操做。在訪問 Swift 服務以前,須要先經過認證服務(keystone)獲取訪問令牌,而後在發送的請求中加入頭部信息 X-Auth-Token。下面是請求返回帳戶中的容器列表的示例:
GET /v1/<account> HTTP/1.1 Host: storage.swift.com X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb 響應頭部信息中包含狀態碼 200,容器列表包含在響應體中: HTTP/1.1 200 Ok Date: Thu, 07 Jan 2013 18:57:07 GMT Server: Apache Content-Type: text/plain; charset=UTF-8 Content-Length: 32 images movies documents backups
OpenStack Swift 做爲穩定和高可用的開源對象存儲被不少企業做爲商業化部署,如新浪的 App Engine 已經上線並提供了基於 Swift 的對象存儲服務,韓國電信的 Ucloud Storage 服務。有理由相信,由於其徹底的開放性、普遍的用戶羣和社區貢獻者,Swift 可能會成爲雲存儲的開放標準,從而打破 Amazon S3 在市場上的壟斷地位,推進雲計算在朝着更加開放和可互操做的方向前進。
看完swift,發現原來雲計算領域更爲龐大。。。一切學習都是開始啊!
Quorom 機制,是一種分佈式系統中經常使用的,用來保證數據冗餘和最終一致性的投票算法,其主要數學思想來源於鴿巢原理。
在有冗餘數據的分佈式存儲系統當中,冗餘數據對象會在不一樣的機器之間存放多份拷貝。可是同一時刻一個數據對象的多份拷貝只能用於讀或者用於寫。
該算法能夠保證同一份數據對象的多份拷貝不會被超過兩個訪問對象讀寫。
算法來源於[Gifford, 1979][3][1]。 分佈式系統中的每一份數據拷貝對象都被賦予一票。每個操做必需要得到最小的讀票數(Vr)或者最小的寫票數(Vw)才能讀或者寫。若是一個系統有V票(意味着一個數據對象有V份冗餘拷貝),那麼這最小讀寫票必須知足:
Vr + Vw > V
Vw > V/2
第一條規則保證了一個數據不會被同時讀寫。當一個寫操做請求過來的時候,它必需要得到Vw個冗餘拷貝的許可。而剩下的數量是V-Vw 不夠Vr,所以不能再有讀請求過來了。同理,當讀請求已經得到了Vr個冗餘拷貝的許可時,寫請求就沒法得到許可了。
第二條規則保證了數據的串行化修改。一份數據的冗餘拷貝不可能同時被兩個寫請求修改。
在分佈式系統中,冗餘數據是保證可靠性的手段,所以冗餘數據的一致性維護就很是重要。通常而言,一個寫操做必需要對全部的冗餘數據都更新完成了,才能稱爲成功結束。好比一份數據在5臺設備上有冗餘,由於不知道讀數據會落在哪一臺設備上,那麼一次寫操做,必須5臺設備都更新完成,寫操做才能返回。
對於寫操做比較頻繁的系統,這個操做的瓶頸很是大。Quorum算法可讓寫操做只要寫完3臺就返回。剩下的由系統內部緩慢同步完成。而讀操做,則須要也至少讀3臺,才能保證至少能夠讀到一個最新的數據。
Quorum的讀寫最小票數能夠用來作爲系統在讀、寫性能方面的一個可調節參數。寫票數Vw越大,則讀票數Vr越小,這時候系統寫的開銷就大。反之則寫的開銷就小。