京東智聯雲物件儲存高可用架構設計思考

京東科技開發者發表於2020-07-22

在剛剛過去的618大促中,京東影片拋棄了私有儲存, 將京東智聯雲物件儲存作為京東影片的唯一儲存。在整個618過程中,京東智聯雲物件儲存提供了穩定的服務,助力618完美落幕。


618大促作為京東集團最重要的活動,對所有服務的可用性有極高的要求,京東影片作為京東的一級系統,對儲存的故障更是零容忍,那麼如何保障系統的高可用呢?下面我們就一起來探討下京東智聯雲物件儲存在高可用架構設計上的一些思考。

作為一個有狀態的服務,影響服務可用性的因素有很多,一般來說會有以下幾大類:


  • 硬體/網路故障, 該故障會導致部分資料無法讀取或者寫入,如果是中心節點故障甚至會導致整個服務無法使用;

  • 誤操作, 人工的誤操作可能會導致服務不可用甚至資料丟失/損壞,如果是對中心類的節點誤操作可能導致整個服務無法使用;

  • 程式Bug, 儲存系統也在不斷更新迭代的過程中,每次更新迭代都可能會引入Bug,導致系統不可服務甚至資料丟失/損壞。

 

物件儲存是一個複雜的系統,在設計和實現的過程中,我們遵循了以下原則,來保證物件儲存的高可用:

 

  • 所有資料都是三副本儲存,資料跨越三個AZ,保證任何級別的硬體故障都不會導致服務不可用;

  • 資料只讀化,一個資料儲存之後就不會再被修改,這也意味著只要資料在磁碟上,就不會影響到讀,保證讀的高可用;

  • 使用多個叢集共同組成一個服務,在多個叢集上做寫的高可用,確保寫入不會中斷;

  • 藍綠部署,灰度釋出,確保任何操作都只會在一個叢集上進行,避免了Bug/誤操作等對寫入的影響;

  • 沒有中心節點。

 

下面我們以物件儲存的架構為例,詳細探討下在物件儲存中,我們是如何實踐以上原則的。


整體來說,物件儲存包括 業務層(綠色部分)、資料儲存(黃色部分)、後設資料儲存(藍色部分) 三個部分組成,下面對這三個部分分別做更詳細的介紹:


物件儲存業務層主要做了一些認證鑑許可權流等業務操作,從資料流的角度來看,他主要做了資料流的拆分和轉發的工作,下圖描述了一個基本的上傳流程:


從上圖中,我們可以看到,物件儲存業務層上傳的流程如下:


  1. 接收流式資料,拆分成一個個的Slice;

  2. 把每個Slice寫入到後端資料儲存,並且記錄下資料儲存返回的SliceId(clusterId, rgId, blobId);

  3. 把Key和所有SliceId儲存在後設資料儲存中;

  4. 返回給客戶成功。

 

從上面的描述可以看出,物件儲存業務本身是一個無狀態的服務,可以簡單的透過多個節點來實現高可用,在現實中我們也是這麼做的。





從上面的資料上傳流程中可以看到,資料儲存是一個Blob的系統,它的基本介面是使用者寫入一份資料,資料儲存返回一個Id,這意味著可以實現以下兩點:


  1. 寫入到資料儲存中的資料只會被讀取和刪除,永遠不會被修改,也意味著任意時間只要從任何一個副本讀到某個SliceId的資料,該資料一定是最新的資料;

  2. 任何一個Slice可以寫入到任意一個叢集的任意一個複製組,保證寫入永遠高可用;


首先,我們來看一下物件儲存資料儲存系統多叢集部署多邏輯結構圖:


從上面的邏輯部署圖可以看到,資料儲存系統由兩類儲存系統組成,下面分別介紹一下:



上圖展示了一個Region標準的部署圖,一般來說,一個Region由三個AZ組成,業務層會跨越三個AZ部署, 儲存叢集、WriteCache DataStore 都會部署三個叢集,做藍綠部署,其中DataStore跨越三個AZ,而WriteCache每個AZ部署一套。



物件儲存是一個Blob系統,資料寫入到後端任意一個儲存叢集都可以,Sched負責排程一次寫入寫入到具體哪個叢集。

 

流量排程會綜合叢集的容量/壓力等資訊,把請求排程到合適的叢集,確保各個叢集能最大化地被利用。





在物件儲存資料儲存中,每個區域會部署三套儲存叢集/快取叢集,這些叢集做藍綠部署,任何更新或者運維操作都只會在一個叢集上進行,確保了任何的Bug或者人工誤操作不會影響到物件儲存的寫入。

 

在部署上,物件儲存資料儲存除了部署跨越多個可用區的DataStore,還在每個AZ中部署了AZ內的WriteCache,確保了在跨AZ網路中斷某個AZ形成了孤島也不影響資料的寫入。


在資料儲存中,底層的資料儲存有WriteCache,標準儲存-DataStore,EC儲存等多個系統,它們的基本架構都是一樣的,都是基於ReplicateGroup/Raft/Log的系統,寫入成功都只依賴於複製組中大部分節點響應成功。

 

下面我們來看看底層儲存叢集的架構:

和一個常見的分散式儲存系統類似,物件儲存底層儲存叢集也是由Client,DataNode,Master三個部分組成,下面分別對三個部分做一個介紹:

底層資料儲存高可用的核心思路如下:


  1. 所有的資料/服務都是多副本的,並且跨越多個AZ,保證單磁碟/機器/交換機/機房故障都不會影響使用者;

  2. 主幹流程上不存在中心節點,常見的系統設計中,Master可能會是一箇中心節點,少數幾個Master故障可能導致整個叢集不可用,在DataStore的設計中,我們把Master分成了多個系統,和主幹流程相關的資料路由資訊被拆分到Allotter中,並且多節點部署,Master本身不影響核心流程;

  3. 資料讀取不依賴於複製組的存活,只要資料存在且能路由到就能訪問;

  4. 資料不強制要求三副本,但是保證絕大部分資料都是三副本。

 

下面我們具體從讀寫的角度看看是如何實現高可用:



寫入流程如下:


  1. Client挑選一個可用的Allotter,從中分配一個可用RG;

  2. Client訪問Cache(有本地快取),獲取到該RG對應的Leader的地址;

  3. Client向Leader傳送寫入請求;

  4. Leader透過Raft把資料複製到所有副本,提交後響應客戶端;

  5. 如果中間有任何失敗,Client會重試1-5步驟。

 

讀取的流程和寫入基本類似,就不再重複說明。


  1. 資料寫入路由依賴於Allotter和Cache,Allotter和Cache都是多節點有任意一個可用的節點就能提供服務,另外Client本身也能承擔絕大部分Allotter/Cache的功能,保證寫入路由高可用;

  2. 資料最終可以儲存在任意一個RG中,一個叢集中會有數十萬到百萬級別的RG,有任何一個可用的RG就可以成功地寫入;

  3. 一個叢集會包括數百臺儲存伺服器,RG會隨機地分散在這些伺服器上,保證了只要有部分儲存伺服器可用,就一定會有可用的RG。

  1. 資料的路由會快取在多個節點的Cache中以及Client內部,保證大量節點故障的時候仍然能找到資料的位置;

  2. 資料本身設計為不會被修改,因此資料的讀取只依賴於資料所在節點程式的儲存而不依賴於資料所在複製組的存活,只要能找到資料的位置(上一步描述了其高可用),就能讀取到資料;

  3. 寫入本身不是三副本強一致,但是Allotter在做寫入流量排程時會優先選擇主從複製delay少的複製組,保證了絕大部分資料實際上都是有三副本的;

  4. 程式快速啟動,啟動後能在數秒開始提供讀服務;

  5. 每個複製組資料較少,磁碟故障理論上在20分鐘以內能完成修復。

 

綜上所述,資料不可訪問的機率基本和資料丟失的機率一樣低。



物件儲存後設資料管理系統核心是一個全域性有序的KV系統,和資料儲存相比,它會有以下幾點不同:


  1.  資料會被覆蓋,使用者可以對一個Object做覆蓋上傳,該操作會修改後設資料儲存中該Key對應的Value;

  2. 資料量小,通常後設資料儲存大概只有資料千分之一以下。

 

對於後設資料的的高可用,我們也採取了跨AZ多副本儲存、多叢集等機制,但是這些機制和資料儲存又不完全一致,接下來我們來詳細看看後設資料的高可用方案:


上圖所示是物件儲存後設資料儲存系統的核心架構,後設資料儲存系統底層使用了Tikv作為最終的儲存系統,和資料儲存一樣,後設資料儲存在每個區域同樣會部署三套跨越三個AZ的Tikv,多個Tikv叢集之間做藍綠部署,降低人為操作/升級引入Bug等因素對整個後設資料儲存系統等影響。

 

後設資料管理系統採用了類似LSM Tree的架構,在多個叢集上透過各種不同角色的元件構建了統一的後設資料管理服務,各個元件的關係見下表描述:

和資料高可用的思路類似,後設資料高可用也是由兩個部分組成:


  1. 儲存叢集做高可用;

  2. 多叢集容災,避免單叢集故障對可用性的影響。

 

下面我們分別從讀寫兩個方面來看看具體是怎麼做的:


寫入高可用由Tikv叢集內部的高可用和多叢集兩個方面共同組成:


  1. Tikv本身跨越3個AZ做三副本儲存,單個故障域(磁碟/機器/交換機/機房) 故障不會影響叢集可用性;

  2. Writeable所在Tikv叢集故障,寫入可以快速切換到Backup,且Backup和Writeable所在物理Tikv叢集不會是一個叢集,確保寫入不會中斷。


  1. 對於已經只讀的叢集(Readonly, Stable),資料已經不會發生變化,讀任意一個副本即可,只要資料存在就可以讀到正確的資料,資料的可用性也可以簡單的透過增加副本來提升;

  2. 對於讀寫叢集中的資料,資料會準實時的透過Binlog來同步到Standby:

    a) 資料本身是三副本,保證高可用;

    b) 叢集不可用的時候,可以直接讀取Standby叢集資料,做叢集級別的容災。



一般來說,三個AZ高可用的儲存系統(例如物件儲存資料,後設資料系統),由於複製組可以跨越三個AZ,可以簡單的容忍單個AZ的徹底故障。但是如果出現了AZ之間的網路故障,導致某個AZ和其它AZ失聯,該AZ內部還能正常服務,這個時候就會形成一個孤島。

 

對於物件儲存來說,物件儲存上層的很多業務,比如說資料庫/主機等都是在一個AZ內部,也就是說如果某個AZ和其它AZ失聯,該AZ內部還是會源源不斷的產生資料,我們需要保證孤島內部生成的資料能成功的寫入物件儲存,下面我們主要介紹物件儲存在這種情況下的處理。


資料孤島本質上需要解決兩個問題:


  1. 孤島形成的時候,需要把資料寫入到孤島內部;

  2. 孤島結束後,需要把孤島內外的資料做合併。

 

物件儲存包括資料儲存和後設資料儲存兩個有狀態的服務,下面分別介紹一下我們如何利用多叢集來解決資料孤島的問題:



在資料儲存高可用的時候我們提到過,在每個AZ中,我們會部署一套可靠的寫快取服務,寫快取的資料最終會Writeback到跨AZ的儲存叢集。

 

由於資料儲存可以選擇任何一個叢集寫入,某個AZ形成資料孤島後,該孤島內部產生的資料都會寫入到本AZ的寫快取,保證了資料寫入的高可用。這部分資料最終會在AZ之間重新連線後寫入到跨AZ的叢集。

 

由於物件儲存資料儲存系統是一個不可修改的系統,這意味著孤島內外不可能會對同一個ID做操作,孤島結束後資料合併會變的很簡單。


物件儲存本身允許覆蓋上傳,這意味著後設資料是一個允許修改的系統,這也讓後設資料儲存的資料孤島解決方案變的相對比較複雜。

 

和資料儲存孤島不同,後設資料形成孤島後,如果孤島內外對同一個Object做修改,在一段時間內必然會導致孤島內外看到的資料不一致,這些不一致最終會達成一致,也就是說後設資料儲存是一個最終一致的系統。

 

在物件儲存中,我們透過 多叢集 + 多版本來解決資料孤島問題。


  1. 物件儲存支援修改,但是物件儲存實際使用中修改相對較少;

  2. 一個Key在短時間內(1s)被併發修改的機率很低,我們認為在極端異常情況下毫秒級別的併發修改最終亂序是可以接受的;

  3. 極端情況下可能讀到老的資料,甚至交替讀到新老資料,但是最終會讀到確定的一份資料。



上圖是一個多版本的後設資料管理系統的架構,和最初版本相比,多了一個IDService的服務,IDService本身是一個高可用的Id生成器,它會 根據當前機器時間生成單調遞增的ID,一個大致的Key的結構為timestampMS_自增ID_IDService叢集ID。IDService會多節點部署,保證高可用。


基於IDService,我們實現了多版本的後設資料管理系統,任何一次對後設資料的修改都會透過IDService取得唯一的ID來作為Version,並且在Tikv中儲存下所有Version的後設資料。舉個例子,兩次的PutObjectMeta(Key, meta) + 一次Delete最終會在Tikv中儲存下以下三條記錄:


  • Key_version1 -> meta

  • Key_version2 -> meta

  • Key_version3 -> DELETED


由於IDService生成的是有序的,該Meta的所有版本中版本最大的記錄就是Meta的最新記錄,比如上面的例子,最新記錄是刪除記錄,該Object已經被刪除。

下圖是一個孤島故障切換的例子,在該例子中,AZ1形成了資料孤島,AZ2和AZ3能正常互聯。

在上圖可以看到,我們會在每個AZ部署獨立的AZ內部獨立的Tikv和IDService, 在AZ1形成資料孤島後,整個Meta的服務會分成兩個獨立的部分:


  1. 全域性的Meta服務(綠色部分),會使用跨AZ的Tikv和IDService,此時服務於AZ2和AZ3;

  2. AZ1內部Meta(藍色部分),會寫入到AZ1內部的Tikv。

 

在Meta分裂成兩個叢集后,所有的寫入都可以成功。




在AZ1恢復和AZ2,3互聯後,所有的寫入會切換到多AZ多叢集,AZ1內部Tikv叢集的資料需要合併到跨AZ叢集。

 

由於Meta實現了多版本,多個IDService之間也保證能生成唯一的ID,也就是說Key_Version是唯一的,因此AZ1內部Tikv的資料可以直接合併到跨AZ叢集即可。

 

基於以下原因,合併是有效的:


  1. IDService根據機器時間生成自增ID。

  2. 多個IDService機器的時間偏移保證可控。

  3. 極端異常情況下可以接受段時間內亂序。

 

基於以上三點,可以保證直接合並的結果符合我們預期。


點選" 閱讀原文",瞭解更多京東大規模分散式物件儲存服務

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69912185/viewspace-2706101/,如需轉載,請註明出處,否則將追究法律責任。

相關文章