精品国产一级在线观看,国产成人综合久久精品亚洲,免费一级欧美大片在线观看

當前位置:存儲企業動態 → 正文

LinkedIn 開源其分布式對象存儲系統 Ambry

責任編輯:jackye 作者:張衛濱 |來源:企業網D1Net  2016-06-02 09:34:30 本文摘自:INFOQ

日前,LinkedIn在Github上基于Apache 2許可證協議開源了其分布式對象存儲系統Ambry。Ambry是一個是不可變對象的存儲系統,非常易于擴展,它能夠存儲KB到GB大小的不可變對象,并且能夠實現高吞吐和低延遲,該系統支持跨數據中心的雙活部署,并且存儲成本低廉。它特別適于存儲各種媒體內容。

據Linkedin的前工程主管Sriram Subramanian介紹,媒體內容在Web中已經無處不在,Linkedin中的每項新特性基本上都會與某種類型的媒體內容進行交互。這些媒體內容會存儲在后端,并且主要會由內容分發網絡(Content Delivery Networks,CDN)來提供服務,后臺存儲系統會作為CDN的原始服務器(origin server)。

隨著Linkedin流量的不斷增長,原來所使用的媒體內容存儲方案在可擴展性、可用性以及運維方面所遇到的問題越來越多。兩年前,他們著手解決這些問題,而Ambry正是該項工作的結果。

2013年時的媒體存儲是什么樣的?

LinkedIn之前的系統被稱為媒體服務器(因為沒有一個像樣的名字),這個系統由兩部分組成,分別是用于媒體文件存儲的Filer以及存儲元數據的大型Oracle數據庫。這些系統的前端是一些運行在SOLARIS上的無狀態機器,它們會將請求路由到對應的Filer或數據庫上。Filer是通過NFS的方式mount到無狀態機器上的,并使用Java的File API進行遠程訪問。前端會與數據中心(DC)里面的一組緩存進行交互,從而保證如果下游系統(Filer/Oracle)出現性能問題或不可用時,前端不會受其影響。

頻繁出現的可用性問題:每次對文件的元數據操作出現峰值時,原有的系統都會出現延遲。當訪問大量的小文件時,對元數據的操作就會增多。每次文件操作都要經過多級的轉換(Java、NFS以及Filer),使其很難進行調試;難以擴展:用來存儲數據和元數據的底層系統都是單體的。水平擴展元數據的存儲是不可能實現的,為數據存儲增加硬件也需要很多的手動過程;對小對象和大對象的支持效率低下:媒體數據集中包含了數萬億的小對象(50KB-1MB)也包括數億的大對象(1MB-1GB)。對于小對象的存儲來說,元數據操作的代價是很高昂的,而對于大數據,原有的系統缺乏端到端的流支持,難以支持新產品的使用場景;平均修復時間(MTTR,Mean Time To Repair)指標很差:老系統中的大多數組成部分在很大程度上都是黑盒,這需要獲得支持許可證,并且要通過電話的方式來描述和解決問題,這會影響到MTTR;成本高昂:舊的媒體存儲成本很高,再繼續擴展的話,成本上已經吃不消了。如果想管理媒體的擴展性,就不能延續該方案了。

在這個過程中,Linkedin探索過多種替代方案,最終還是決定自行實現更匹配其需求的解決方案。

Ambry是如何運行呢?

設計目標

在了解Ambry的設計和內部運行原理之前,明確其設計目標是很有幫助的,這決定了它的實現方式。

高可用性和水平可擴展:該系統要處理實時流量,會直接影響到站點的可用性,因此它必須具有很高的可用性。另外,還希望新系統能夠盡可能地實現無縫的集群擴展;降低運維的負擔:分布式系統一般都會難以管理,對于頻繁的集群操作,能夠實現自動化是非常重要的,這能避免系統成為運維的一種負擔。復雜的系統通常很難實現自動化并可靠的運行,因此新系統的設計要簡單、優雅并自動化;更低的MTTR:分布式系統出現故障是難以避免的,但是很重要的一點在于快速修復故障,讓各個子組件啟動并運行。這就需要系統的設計簡單,并且不會出現單點故障;跨DC雙活:Linkedin有多個數據中心,因此所有的系統都要支持雙活配置,這樣的話,系統能夠更新不同數據中心中的同一個對象;提升小對象和大對象的效率:請求是由小對象和大對象所組成的,小對象通常是1K到100K,超出這個范圍的對象會位于大對象桶中(bucket)。要同時處理好各種大小的對象,通常來講是很困難的。大量的小對象會給元數據帶來很高的負載,造成硬盤碎片,需要很多的隨機IO,而大對象則需要很好的內存管理、端到端的流處理和有限的資源使用;廉價:媒體內容很快就會占據很大的存儲空間,它的另外一個特點是舊數據會變成“冷”數據,并不會頻繁訪問。針對這種情況有很多優化技術,包括使用密集的硬件(denser hardware)、分層存儲、擦除編碼以及數據去重等。在設計時,Ambry希望媒體內容能夠高效存儲在密集型的機器上,并且能夠非常容易地使用其他優化成本的方案。

概覽

總體上來講,Ambry由三部分組成,分別是用來存儲和檢索數據的一組數據節點,路由請求的前端機器(請求會在一些預處理之后路由到數據節點上)以及協調和維護集群的集群管理器。數據節點會在不同節點之間復制數據,同時支持數據中心內部和數據中間之間的復制。前端提供了支持對象PUT、GET和DELETE操作的HTTP API。另外,前端所使用的路由庫也可以直接用在客戶端中,從而實現更好的性能。在LinkedIn,這些前端節點會作為CDN的原始服務器。

  API

Ambry提供了REST API,它們適用于大多數的場景。在有些場景下,需要更好的性能,如果是這樣的話,Ambry也支持在客戶端使用路由庫,直接針對數據節點的流字節進行讀取和寫入。目前,路由庫是阻塞的(同步),不過Ambry目前正在致力于實現非阻塞(異步)版本,同時也會提供對路由庫的多語言支持。

Clustermap

Clustermap控制拓撲結構、維護狀態并幫助協調集群的操作。Clustermap有兩部分組成:

硬件布局:包含了機器的列表、每臺機器上的磁盤以及每個磁盤的容量。布局還維護資源的狀態(機器和磁盤)并指定主機名和端口,通過主機名和端口就能連接到數據節點;分區布局:包含了分區的列表、它們的位置信息以及狀態。在Ambry中,分區有一個數字表示的ID,副本的列表可以跨數據中心。分區是固定大小的資源,集群間的數據重平衡都是在分區級別進行的。

數據節點和前端服務器都能夠訪問clustermap,并且會始終使用它們當前的視圖來做出決策,這些決策涉及到選擇可用的機器、過濾副本以及識別對象的位置等。

存儲

存儲節點會用來存放不同分區的副本。每個存儲節點會有N塊磁盤,副本會跨磁盤分布存儲。這些副本的結構和管理都是相同的。

  在存儲方面,Ambry涵蓋的功能包括如下幾個方面:

持久化:磁盤上的每個副本均被建模為預先分配的log(preallocated log)。所有新的消息都會按照順序附加到log上,消息是由實際的對象塊(chunk)和相關的元數據(系統和用戶)所組成的。這能夠使寫入操作實現很高的吞吐量,并且避免出現磁盤碎片。Ambry會使用索引將對象id與log中的消息映射起來,索引本身是一組排序的文件片段,條目按照最新使用在前,最舊的條目在后的順序,從而便于高效查找。索引中的每個條目都維護了log中消息的偏移量、消息的屬性以及一些內部使用的域。索引中的每個片段會維護一個bloom filter,從而優化實際磁盤操作所耗費的時間;零拷貝:通過使用sendfile API,在進行讀取時,字節從log轉移到網絡的過程中實現了零拷貝。通過避免額外的系統調用,實現了更好的性能,在這個過程中,會確保字節不會讀入到用戶內存中,不必進行緩存池的管理;恢復:因為系統和機器會出現宕機,磁盤上的數據也有可能會損壞,所以有必要實現恢復(recovery)的功能。在啟動的時候,存儲層會從最后一個已知的檢查點讀取log,并重建索引。恢復也有助于重建內存中的狀態。Log是恢復的來源,并且會永久保存;復制:存儲節點還需要維護分區中各副本的同步。每個節點上都會有一個復制服務(replication service),它會負責保證本地存儲中的副本與所有的遠程副本是同步的。在這里,進行了很多的優化,以保證復制過程的高效可靠。

路由/前端

前端服務器提供了HTTP接口,供客戶端與之通信。除此之外,它們還會負責為CDN設置正確的頭信息、進行安全校驗,并將對象以流的形式返回給路由庫和客戶端。

路由所負責的功能如下所示:

請求管理:請求的端到端生命周期是由路由來進行管理的。路由會處理PUT、GET以及DELETE請求。對于其中的每個請求類型,路由都會跟蹤副本成功和失敗的數量從而確定Quorum的值、維護分塊的狀態、生成對象id并在成功或失敗的時候觸發對應的回調;分塊:大對象會分解為塊(chunk),每個塊都能夠跨分區獨立地進行路由。每個塊都會有一個id來進行唯一標識。路由會生成一個元數據對象,其中包含了塊的列表以及它們所需的獲取順序。元數據對象存儲為獨立的blob,它的id也會作為blob的id。在讀取的時候,會得到元數據對象,然后檢索各個塊并返回給客戶端;故障檢測:故障檢測的邏輯要負責主動識別宕機或狀態出問題的資源。資源可以是機器、磁盤或分區。路由會將出現問題的資源標記為不可用,這樣后續的請求就不會使用它們了;Quorum:Ambry為寫入和讀取實現了一種多主人(multi-master)的策略。這能夠實現更高的可用性并減少端到端的延遲,這是通過減少一個額外的hop來實現的,在基于主從結構(master slave)的系統中,往往會有這個額外的hop。請求通常會發往M個副本,然后等待至少N個成功的響應(這里N<=M)。路由會優先使用本地數據中心的副本,向其發送請求,如果本地存儲無法實現所需的Quorum的話,它會代理遠程數據中心的訪問;變更捕獲:在每次成功的PUT或DELETE操作之后,路由會生成一個變更捕獲(change capture)。變更捕獲中所包含的信息是blob id以及blob相關的元數據,這個信息可以被下游的應用所使用。

在路由中,典型的PUT和GET操作的流程分別如下所示,系統的實際運行過程會比下述的描述會更復雜一些:

PUT操作:客戶端會將對象以及一些元數據信息以流的形式發送到前端,當流到達時,前端會將對象進行分塊、選擇可用的分區、為blob或分塊生成blob id,并將請求分發給W個副本。然后,前端就開始等待至少Q個成功的響應(Q<=W),等到之后,會將blob id返回給客戶端。如果無法達到足夠的Quorum,那么前端會報告一個錯誤。當然,Ambry也實現了當Quorum失敗的時候,選擇另外一個分區的功能,從而提升可用性。

GET操作:客戶端通過將id發送給前端來請求某一個blob。前端會根據id來確定分區,并在數據節點中檢索blob相關的塊。對于每個塊,前端會并行發送R個請求,在將blob或分塊發送給客戶端之前,前端會等待Q個成功響應(Q<=R)。

  解決運維的難題

分布式系統最困難的在于它的運維,在這個過程中,需要工具、度量并且要進行廣泛地測試,從而保證所有的事情都能符合預期。在這個過程中,Ambry積累了很多的工具和實踐。

Simoorg:為了模擬各種故障,他們孵化并開源了Simoorg。這是一個分布式的故障引入系統,能夠在集群中引入各種故障,如GC暫停、磁盤錯誤、節點宕機以及網絡故障,從而校驗在各種情況下,系統的正確性,有助于預先發現并修正嚴重的缺陷;生產環境的正確性測試:當新版本部署到集群中的部分機器進行驗證時,可以進行正確性測試,從而保證生產環境的健康狀態。通過加壓訪問所有可用的API(組合使用各種可能出現的輸入參數),確保結果的正確性;審計:當新的blob寫入到磁盤時,都會產生復制事件,這個事件包含了blob的信息以及事件的來源。所有存儲節點的事件都會聚集到Hadoop中,這樣就能審計是否所有的副本都進行了寫入。目前該系統并不是實時的,不過,Ambry規劃會構建一個實時的審計系統。

除此之外,Ambry還實現了指標和告警工具,用來幫助識別系統中的異常行為以及維護集群的管理工具。

遷移工作是如何進行的?

團隊需要將所有的媒體內容從遺留系統遷移至Ambry,在這個過程中還要服務于所有的流量,不能出現任何的宕機時間。除此之外,團隊還面臨著多項deadline,了解Ambry是如何組織研發和部署的,對我們會有一定的指導意義:

當時,公司正在將所有的服務從Spring RPC方案中剝離出來。從構建Ambry開始計算,團隊有四個月的時間支持新的API并移除Spring RPC;一個新的數據中心正好需要搭建,Ambry團隊并不想再去部署遺留系統了,因為這會帶來很高的成本。這同時也就意味著為了避免部署遺留系統,需要在八個月內完成Ambry;最后,團隊希望在數據中心里面移除掉Solaris的方案,遺留系統是運行在Solaris上的,它的deadline是一年。

Ambry團隊采用了一種特殊的方式來達到這些里程碑節點。首先,構建前端并使用它來代理所有對舊系統的請求,然后再將所有的客戶端遷移到新的前端上。這雖然費了很大的功夫,但是確保了第一個deadline目標的達成。

第二步是讓Ambry能夠以端到端的方式運行,并且只將其部署到新的數據中心上,然后將所有的數據從舊系統遷移至Ambry。在代碼中,添加了一定的邏輯,確保如果新數據中心發生故障的話,將會使用舊的系統。這可能會產生更多的延遲,但是團隊決定承擔這個風險。

在新數據中心搭建完成之后,在接下來的幾個月里,團隊不斷運行并穩定Ambry。基于測試和審計結果,當對新系統完全自信的時候,團隊決定停掉遺留的系統。這樣就在一年的deadline之內完成了目標。

在接下來的一年中,Ambry成為了Linkedin中媒體內容的唯一來源。它的成功要歸因于周密的規劃以及漸進式的基礎設施研發。

Ambry是如何適應Linkedin的生態系統的?

媒體基礎設施是針對媒體內容的端到端管道,涉及到上傳、存儲、處理、元數據管理以及內容下載。在基礎設施中,Ambry是很重要的一個環節,基礎的穩固是非常重要的。在Ambry就緒之后,就可以圍繞著它進行擴展并關注生態系統中的其他組成部分。

  下一步的研發計劃

目前,Ambry主要進行中的任務包括在前端和路由層實現非阻塞、存儲節點實現機架感知等功能。團隊希望不斷地為Ambry添加新的特性,并且構建活躍的開源社區。完整的未來工作計劃列表可以參見Github上的相關頁面,如下列出了當前正在進行的或者可能會開展的項目:

非阻塞:阻塞類型的請求通常會占用一個進程,直到請求結束并且不支持管道。為了達到更高的吞吐量,并且避免大對象所造成的資源枯竭現象,需要將路由和前端變成完全非阻塞的。這樣的話,就能支持更大吞吐量,在操作執行時,不再受限于線程資源,從而能夠實現更好的可用性。目前,前端實現已經完成,正在進行測試。路由庫的代碼預計也將會很快完成,可以參考其repository來了解最近的更新情況;機架感知:現代的數據中心為了降低成本都將機架切換視為很重要的因素。這意味著軟件要足夠智能來應對切換故障。Ambry正在構建的一項功能就是確保新分區的副本在跨數據中心存放時,能夠遵循機架感知的方式。目前,該項工作正在進行之中;Bucket/Container:Ambry尚不支持命名空間的概念。如果要在群組的級別上強化控制的話,那命名空間是非常有用的。在Ambry中,可能將會引入Bucket或Container的理念。這有助于在bucket級別上定義用戶群組、訪問控制和配額,這種方式會比在對象級別進行維護容易得多;安全:Ambry目前支持數據節點之間的加密,在前端和數據節點之前的通信也可以啟用加密功能。不過,在安全方面,Ambry會有更多的進展,包括REST級別的認證、授權以及對加密的支持。該項功能預計會在Bucket/Container實現完成之后開展。

對于社區來講,這個系統會有很大的用處,有助于支持媒體內容的實時上傳和媒體服務的構建,詳細的文檔可以參見Github上的相關頁面。如果讀者有反饋意見或有志于為該項目做出貢獻的話,可以參考其開發指南。Ambry團隊希望該項目的開發能夠保持開放的狀態,并幫助社區使用它來構建應用程序。另外值得一提的是,2016年度的SIGMOD(Special Interest Group on Management Of Data)已經接受了一篇關于Ambry的論文,該會議將會在六月份舉行,可以瀏覽其網站了解更多信息。

關鍵字:Ambry存儲層LinkedIn

本文摘自:INFOQ

x LinkedIn 開源其分布式對象存儲系統 Ambry 掃一掃
分享本文到朋友圈
當前位置:存儲企業動態 → 正文

LinkedIn 開源其分布式對象存儲系統 Ambry

責任編輯:jackye 作者:張衛濱 |來源:企業網D1Net  2016-06-02 09:34:30 本文摘自:INFOQ

日前,LinkedIn在Github上基于Apache 2許可證協議開源了其分布式對象存儲系統Ambry。Ambry是一個是不可變對象的存儲系統,非常易于擴展,它能夠存儲KB到GB大小的不可變對象,并且能夠實現高吞吐和低延遲,該系統支持跨數據中心的雙活部署,并且存儲成本低廉。它特別適于存儲各種媒體內容。

據Linkedin的前工程主管Sriram Subramanian介紹,媒體內容在Web中已經無處不在,Linkedin中的每項新特性基本上都會與某種類型的媒體內容進行交互。這些媒體內容會存儲在后端,并且主要會由內容分發網絡(Content Delivery Networks,CDN)來提供服務,后臺存儲系統會作為CDN的原始服務器(origin server)。

隨著Linkedin流量的不斷增長,原來所使用的媒體內容存儲方案在可擴展性、可用性以及運維方面所遇到的問題越來越多。兩年前,他們著手解決這些問題,而Ambry正是該項工作的結果。

2013年時的媒體存儲是什么樣的?

LinkedIn之前的系統被稱為媒體服務器(因為沒有一個像樣的名字),這個系統由兩部分組成,分別是用于媒體文件存儲的Filer以及存儲元數據的大型Oracle數據庫。這些系統的前端是一些運行在SOLARIS上的無狀態機器,它們會將請求路由到對應的Filer或數據庫上。Filer是通過NFS的方式mount到無狀態機器上的,并使用Java的File API進行遠程訪問。前端會與數據中心(DC)里面的一組緩存進行交互,從而保證如果下游系統(Filer/Oracle)出現性能問題或不可用時,前端不會受其影響。

頻繁出現的可用性問題:每次對文件的元數據操作出現峰值時,原有的系統都會出現延遲。當訪問大量的小文件時,對元數據的操作就會增多。每次文件操作都要經過多級的轉換(Java、NFS以及Filer),使其很難進行調試;難以擴展:用來存儲數據和元數據的底層系統都是單體的。水平擴展元數據的存儲是不可能實現的,為數據存儲增加硬件也需要很多的手動過程;對小對象和大對象的支持效率低下:媒體數據集中包含了數萬億的小對象(50KB-1MB)也包括數億的大對象(1MB-1GB)。對于小對象的存儲來說,元數據操作的代價是很高昂的,而對于大數據,原有的系統缺乏端到端的流支持,難以支持新產品的使用場景;平均修復時間(MTTR,Mean Time To Repair)指標很差:老系統中的大多數組成部分在很大程度上都是黑盒,這需要獲得支持許可證,并且要通過電話的方式來描述和解決問題,這會影響到MTTR;成本高昂:舊的媒體存儲成本很高,再繼續擴展的話,成本上已經吃不消了。如果想管理媒體的擴展性,就不能延續該方案了。

在這個過程中,Linkedin探索過多種替代方案,最終還是決定自行實現更匹配其需求的解決方案。

Ambry是如何運行呢?

設計目標

在了解Ambry的設計和內部運行原理之前,明確其設計目標是很有幫助的,這決定了它的實現方式。

高可用性和水平可擴展:該系統要處理實時流量,會直接影響到站點的可用性,因此它必須具有很高的可用性。另外,還希望新系統能夠盡可能地實現無縫的集群擴展;降低運維的負擔:分布式系統一般都會難以管理,對于頻繁的集群操作,能夠實現自動化是非常重要的,這能避免系統成為運維的一種負擔。復雜的系統通常很難實現自動化并可靠的運行,因此新系統的設計要簡單、優雅并自動化;更低的MTTR:分布式系統出現故障是難以避免的,但是很重要的一點在于快速修復故障,讓各個子組件啟動并運行。這就需要系統的設計簡單,并且不會出現單點故障;跨DC雙活:Linkedin有多個數據中心,因此所有的系統都要支持雙活配置,這樣的話,系統能夠更新不同數據中心中的同一個對象;提升小對象和大對象的效率:請求是由小對象和大對象所組成的,小對象通常是1K到100K,超出這個范圍的對象會位于大對象桶中(bucket)。要同時處理好各種大小的對象,通常來講是很困難的。大量的小對象會給元數據帶來很高的負載,造成硬盤碎片,需要很多的隨機IO,而大對象則需要很好的內存管理、端到端的流處理和有限的資源使用;廉價:媒體內容很快就會占據很大的存儲空間,它的另外一個特點是舊數據會變成“冷”數據,并不會頻繁訪問。針對這種情況有很多優化技術,包括使用密集的硬件(denser hardware)、分層存儲、擦除編碼以及數據去重等。在設計時,Ambry希望媒體內容能夠高效存儲在密集型的機器上,并且能夠非常容易地使用其他優化成本的方案。

概覽

總體上來講,Ambry由三部分組成,分別是用來存儲和檢索數據的一組數據節點,路由請求的前端機器(請求會在一些預處理之后路由到數據節點上)以及協調和維護集群的集群管理器。數據節點會在不同節點之間復制數據,同時支持數據中心內部和數據中間之間的復制。前端提供了支持對象PUT、GET和DELETE操作的HTTP API。另外,前端所使用的路由庫也可以直接用在客戶端中,從而實現更好的性能。在LinkedIn,這些前端節點會作為CDN的原始服務器。

  API

Ambry提供了REST API,它們適用于大多數的場景。在有些場景下,需要更好的性能,如果是這樣的話,Ambry也支持在客戶端使用路由庫,直接針對數據節點的流字節進行讀取和寫入。目前,路由庫是阻塞的(同步),不過Ambry目前正在致力于實現非阻塞(異步)版本,同時也會提供對路由庫的多語言支持。

Clustermap

Clustermap控制拓撲結構、維護狀態并幫助協調集群的操作。Clustermap有兩部分組成:

硬件布局:包含了機器的列表、每臺機器上的磁盤以及每個磁盤的容量。布局還維護資源的狀態(機器和磁盤)并指定主機名和端口,通過主機名和端口就能連接到數據節點;分區布局:包含了分區的列表、它們的位置信息以及狀態。在Ambry中,分區有一個數字表示的ID,副本的列表可以跨數據中心。分區是固定大小的資源,集群間的數據重平衡都是在分區級別進行的。

數據節點和前端服務器都能夠訪問clustermap,并且會始終使用它們當前的視圖來做出決策,這些決策涉及到選擇可用的機器、過濾副本以及識別對象的位置等。

存儲

存儲節點會用來存放不同分區的副本。每個存儲節點會有N塊磁盤,副本會跨磁盤分布存儲。這些副本的結構和管理都是相同的。

  在存儲方面,Ambry涵蓋的功能包括如下幾個方面:

持久化:磁盤上的每個副本均被建模為預先分配的log(preallocated log)。所有新的消息都會按照順序附加到log上,消息是由實際的對象塊(chunk)和相關的元數據(系統和用戶)所組成的。這能夠使寫入操作實現很高的吞吐量,并且避免出現磁盤碎片。Ambry會使用索引將對象id與log中的消息映射起來,索引本身是一組排序的文件片段,條目按照最新使用在前,最舊的條目在后的順序,從而便于高效查找。索引中的每個條目都維護了log中消息的偏移量、消息的屬性以及一些內部使用的域。索引中的每個片段會維護一個bloom filter,從而優化實際磁盤操作所耗費的時間;零拷貝:通過使用sendfile API,在進行讀取時,字節從log轉移到網絡的過程中實現了零拷貝。通過避免額外的系統調用,實現了更好的性能,在這個過程中,會確保字節不會讀入到用戶內存中,不必進行緩存池的管理;恢復:因為系統和機器會出現宕機,磁盤上的數據也有可能會損壞,所以有必要實現恢復(recovery)的功能。在啟動的時候,存儲層會從最后一個已知的檢查點讀取log,并重建索引。恢復也有助于重建內存中的狀態。Log是恢復的來源,并且會永久保存;復制:存儲節點還需要維護分區中各副本的同步。每個節點上都會有一個復制服務(replication service),它會負責保證本地存儲中的副本與所有的遠程副本是同步的。在這里,進行了很多的優化,以保證復制過程的高效可靠。

路由/前端

前端服務器提供了HTTP接口,供客戶端與之通信。除此之外,它們還會負責為CDN設置正確的頭信息、進行安全校驗,并將對象以流的形式返回給路由庫和客戶端。

路由所負責的功能如下所示:

請求管理:請求的端到端生命周期是由路由來進行管理的。路由會處理PUT、GET以及DELETE請求。對于其中的每個請求類型,路由都會跟蹤副本成功和失敗的數量從而確定Quorum的值、維護分塊的狀態、生成對象id并在成功或失敗的時候觸發對應的回調;分塊:大對象會分解為塊(chunk),每個塊都能夠跨分區獨立地進行路由。每個塊都會有一個id來進行唯一標識。路由會生成一個元數據對象,其中包含了塊的列表以及它們所需的獲取順序。元數據對象存儲為獨立的blob,它的id也會作為blob的id。在讀取的時候,會得到元數據對象,然后檢索各個塊并返回給客戶端;故障檢測:故障檢測的邏輯要負責主動識別宕機或狀態出問題的資源。資源可以是機器、磁盤或分區。路由會將出現問題的資源標記為不可用,這樣后續的請求就不會使用它們了;Quorum:Ambry為寫入和讀取實現了一種多主人(multi-master)的策略。這能夠實現更高的可用性并減少端到端的延遲,這是通過減少一個額外的hop來實現的,在基于主從結構(master slave)的系統中,往往會有這個額外的hop。請求通常會發往M個副本,然后等待至少N個成功的響應(這里N<=M)。路由會優先使用本地數據中心的副本,向其發送請求,如果本地存儲無法實現所需的Quorum的話,它會代理遠程數據中心的訪問;變更捕獲:在每次成功的PUT或DELETE操作之后,路由會生成一個變更捕獲(change capture)。變更捕獲中所包含的信息是blob id以及blob相關的元數據,這個信息可以被下游的應用所使用。

在路由中,典型的PUT和GET操作的流程分別如下所示,系統的實際運行過程會比下述的描述會更復雜一些:

PUT操作:客戶端會將對象以及一些元數據信息以流的形式發送到前端,當流到達時,前端會將對象進行分塊、選擇可用的分區、為blob或分塊生成blob id,并將請求分發給W個副本。然后,前端就開始等待至少Q個成功的響應(Q<=W),等到之后,會將blob id返回給客戶端。如果無法達到足夠的Quorum,那么前端會報告一個錯誤。當然,Ambry也實現了當Quorum失敗的時候,選擇另外一個分區的功能,從而提升可用性。

GET操作:客戶端通過將id發送給前端來請求某一個blob。前端會根據id來確定分區,并在數據節點中檢索blob相關的塊。對于每個塊,前端會并行發送R個請求,在將blob或分塊發送給客戶端之前,前端會等待Q個成功響應(Q<=R)。

  解決運維的難題

分布式系統最困難的在于它的運維,在這個過程中,需要工具、度量并且要進行廣泛地測試,從而保證所有的事情都能符合預期。在這個過程中,Ambry積累了很多的工具和實踐。

Simoorg:為了模擬各種故障,他們孵化并開源了Simoorg。這是一個分布式的故障引入系統,能夠在集群中引入各種故障,如GC暫停、磁盤錯誤、節點宕機以及網絡故障,從而校驗在各種情況下,系統的正確性,有助于預先發現并修正嚴重的缺陷;生產環境的正確性測試:當新版本部署到集群中的部分機器進行驗證時,可以進行正確性測試,從而保證生產環境的健康狀態。通過加壓訪問所有可用的API(組合使用各種可能出現的輸入參數),確保結果的正確性;審計:當新的blob寫入到磁盤時,都會產生復制事件,這個事件包含了blob的信息以及事件的來源。所有存儲節點的事件都會聚集到Hadoop中,這樣就能審計是否所有的副本都進行了寫入。目前該系統并不是實時的,不過,Ambry規劃會構建一個實時的審計系統。

除此之外,Ambry還實現了指標和告警工具,用來幫助識別系統中的異常行為以及維護集群的管理工具。

遷移工作是如何進行的?

團隊需要將所有的媒體內容從遺留系統遷移至Ambry,在這個過程中還要服務于所有的流量,不能出現任何的宕機時間。除此之外,團隊還面臨著多項deadline,了解Ambry是如何組織研發和部署的,對我們會有一定的指導意義:

當時,公司正在將所有的服務從Spring RPC方案中剝離出來。從構建Ambry開始計算,團隊有四個月的時間支持新的API并移除Spring RPC;一個新的數據中心正好需要搭建,Ambry團隊并不想再去部署遺留系統了,因為這會帶來很高的成本。這同時也就意味著為了避免部署遺留系統,需要在八個月內完成Ambry;最后,團隊希望在數據中心里面移除掉Solaris的方案,遺留系統是運行在Solaris上的,它的deadline是一年。

Ambry團隊采用了一種特殊的方式來達到這些里程碑節點。首先,構建前端并使用它來代理所有對舊系統的請求,然后再將所有的客戶端遷移到新的前端上。這雖然費了很大的功夫,但是確保了第一個deadline目標的達成。

第二步是讓Ambry能夠以端到端的方式運行,并且只將其部署到新的數據中心上,然后將所有的數據從舊系統遷移至Ambry。在代碼中,添加了一定的邏輯,確保如果新數據中心發生故障的話,將會使用舊的系統。這可能會產生更多的延遲,但是團隊決定承擔這個風險。

在新數據中心搭建完成之后,在接下來的幾個月里,團隊不斷運行并穩定Ambry。基于測試和審計結果,當對新系統完全自信的時候,團隊決定停掉遺留的系統。這樣就在一年的deadline之內完成了目標。

在接下來的一年中,Ambry成為了Linkedin中媒體內容的唯一來源。它的成功要歸因于周密的規劃以及漸進式的基礎設施研發。

Ambry是如何適應Linkedin的生態系統的?

媒體基礎設施是針對媒體內容的端到端管道,涉及到上傳、存儲、處理、元數據管理以及內容下載。在基礎設施中,Ambry是很重要的一個環節,基礎的穩固是非常重要的。在Ambry就緒之后,就可以圍繞著它進行擴展并關注生態系統中的其他組成部分。

  下一步的研發計劃

目前,Ambry主要進行中的任務包括在前端和路由層實現非阻塞、存儲節點實現機架感知等功能。團隊希望不斷地為Ambry添加新的特性,并且構建活躍的開源社區。完整的未來工作計劃列表可以參見Github上的相關頁面,如下列出了當前正在進行的或者可能會開展的項目:

非阻塞:阻塞類型的請求通常會占用一個進程,直到請求結束并且不支持管道。為了達到更高的吞吐量,并且避免大對象所造成的資源枯竭現象,需要將路由和前端變成完全非阻塞的。這樣的話,就能支持更大吞吐量,在操作執行時,不再受限于線程資源,從而能夠實現更好的可用性。目前,前端實現已經完成,正在進行測試。路由庫的代碼預計也將會很快完成,可以參考其repository來了解最近的更新情況;機架感知:現代的數據中心為了降低成本都將機架切換視為很重要的因素。這意味著軟件要足夠智能來應對切換故障。Ambry正在構建的一項功能就是確保新分區的副本在跨數據中心存放時,能夠遵循機架感知的方式。目前,該項工作正在進行之中;Bucket/Container:Ambry尚不支持命名空間的概念。如果要在群組的級別上強化控制的話,那命名空間是非常有用的。在Ambry中,可能將會引入Bucket或Container的理念。這有助于在bucket級別上定義用戶群組、訪問控制和配額,這種方式會比在對象級別進行維護容易得多;安全:Ambry目前支持數據節點之間的加密,在前端和數據節點之前的通信也可以啟用加密功能。不過,在安全方面,Ambry會有更多的進展,包括REST級別的認證、授權以及對加密的支持。該項功能預計會在Bucket/Container實現完成之后開展。

對于社區來講,這個系統會有很大的用處,有助于支持媒體內容的實時上傳和媒體服務的構建,詳細的文檔可以參見Github上的相關頁面。如果讀者有反饋意見或有志于為該項目做出貢獻的話,可以參考其開發指南。Ambry團隊希望該項目的開發能夠保持開放的狀態,并幫助社區使用它來構建應用程序。另外值得一提的是,2016年度的SIGMOD(Special Interest Group on Management Of Data)已經接受了一篇關于Ambry的論文,該會議將會在六月份舉行,可以瀏覽其網站了解更多信息。

關鍵字:Ambry存儲層LinkedIn

本文摘自:INFOQ

電子周刊
回到頂部

關于我們聯系我們版權聲明隱私條款廣告服務友情鏈接投稿中心招賢納士

企業網版權所有 ©2010-2024 京ICP備09108050號-6 京公網安備 11010502049343號

^
  • <menuitem id="jw4sk"></menuitem>

    1. <form id="jw4sk"><tbody id="jw4sk"><dfn id="jw4sk"></dfn></tbody></form>
      主站蜘蛛池模板: 宁阳县| 彭州市| 遵义县| 商丘市| 左贡县| 昌黎县| 抚顺市| 崇阳县| 宁明县| 铜鼓县| 莎车县| 陵川县| 济源市| 道真| 泰顺县| 绥阳县| 塔城市| 阿城市| 宣恩县| 临沧市| 盐池县| 红桥区| 龙江县| 丰宁| 潜山县| 怀宁县| 邢台市| 昌都县| 沙坪坝区| 龙州县| 休宁县| 江华| 田东县| 滦平县| 贡觉县| 竹北市| 墨玉县| 贡嘎县| 电白县| 惠安县| 牡丹江市|