京東統一存儲實踐
一、概況簡介
京東大數據平臺構建了一個健全的基礎架構,它起著至關重要的作用,為多樣化的數據處理任務和高級分析工作提供了支持。該平臺的核心組成部分之一是 Hadoop Distributed File System(HDFS),這是一個高度可擴展的分布式文件存儲系統。HDFS 在京東大數據平臺中承擔了重要的角色,它不僅是數據存儲的基石,同時也是數據處理流程的一個重要環節。它為上層的數據分析工具和應用提供了數據支撐,并為下游的數據產品和服務提供了強有力的數據輸入。
為了強化數據管理和運維效率,京東大數據平臺實施了可視化管理工具,這使得運維團隊能夠通過監控系統輕松快捷地定位集群問題。實時監控和可視化數據展現,極大地簡化了日常管理任務,提高了運維響應速度。京東大數據平臺的離線存儲能力已經達到了較大規模,擁有數萬臺服務器,總存儲量達到 EB 級別。日常數據增長量達到數十 PB。這種規模的存儲系統為平臺上每天百萬次的作業提供了穩定且高效的讀寫性能,保障了大數據平臺的平穩運行。
二、跨域存儲
1. 存在的問題
隨著京東業務的持續發展,對底層數據存儲的要求也日益增高,單機房獨立部署的架構已無法滿足日常的需求,也不符合未來多機房的發展需求,面臨著一系列跨域存儲問題:
容災能力:在當前的多機房分布架構中,雖然存在多個數據中心,但尚未實現真正的多機房容災能力。
數據同步:當業務層需要跨機房訪問數據時,目前采用的方案主要是數據同步。這種同步通過 distcp 進行,實現元數據和存儲數據的復制。在這種模式下,元數據會在每個數據中心各自存儲一份,這種做法無法保證元數據的一致性,數據一致性的確保必須依賴于業務層的邏輯。
數據存儲:由于數據在多個機房存儲,導致了數據的大量冗余,這種冗余不僅占據了大量的存儲空間,也導致了單位數據存儲成本的顯著提高。
跨機房專線不受控:跨機房復制數據時,通過跨機房的專線進行數據表的讀取,這些操作可能導致機房間專線出現一些不可控的問題。
2. 存儲架構
針對上述問題,我們決定采用全量存儲加上全網拓撲的策略來實現異地容災和跨域存儲的能力。通過這種方法,可以提高數據的可用性和一致性,同時優化存儲效率,降低成本。
在這一架構中,多個數據節點(DN)同時向同一機房的元數據節點(NameNode)匯報信息,實現了全網拓撲結構和全量存儲的功能。這種設計允許單個元數據節點統一管理源數據,有效解決了數據一致性問題,并控制了數據遷移成本,達到無感知遷移的用戶體驗。
在跨域存儲功能實施之前,機房間的數據同步主要通過 distcp 完成。然而,在實際工作中,如在一個大規模機房遷移過程中,若采用 distcp 進行遷移,涉及的數據量高達數十 PB,這將要求遷移所有相關業務表和任務,帶來巨大的成本。
采用了跨域存儲架構后,遷移效率得到顯著提升,提高了 350%。此架構支持跨機房數據同步,業務無需分析上下游鏈路,極大簡化了遷移過程。在一個實際案例中,遷移了上萬張表,涉及數十個產品和上千個業務。
除了實現跨機房存儲節點的匯報功能外,架構還在其他機房部署了只讀節點,并支持跨機房切換能力,允許元數據節點實現跨機房容災能力。只讀節點的引入,使得可以啟用讀寫分離,將讀流量全部轉移到只讀節點,從而提高了整個集群的讀性能,性能提升超過了 70%。同時,隨著讀流量從活躍節點遷移走,活躍節點可以專注于優化寫性能。此外,開啟聚合寫功能進一步提升了集群寫數據的能力。
盡管跨機房存儲架構帶來了多種優勢,但它也伴隨著一些挑戰需要克服。
首先,隨著跨機房存儲功能的實施,集群規模可能會迅速擴大,導致單一集群規模激增至數萬的規模。這種快速擴張帶來了管理和維護的難度,對集群管理能力提出了更高的要求。
其次,跨機房心跳(心跳機制用于監測節點間的活躍狀態)同樣面臨挑戰。由于物理距離和網絡延遲的存在,確保跨機房心跳的穩定和可靠性變得更加困難,需要采用高效的同步機制來減少心跳丟失和誤判的情況。
最后,多機房存儲節點的加入復雜化了元數據節點的拓撲結構,同時對跨機房流量的控制也提出了新的要求。流量控制機制必須能夠應對來自不同機房的數據流,確保數據同步的效率和準確性,同時避免網絡擁堵和數據丟失。
總結而言,為了充分發揮跨機房存儲架構的優勢,必須解決伴隨其帶來的規模擴張、心跳同步和流量控制等一系列問題。
3. 拓撲與數據存儲
針對跨機房數據分布問題,采取了通過修改目錄上的 XTTR 屬性來解決的方案。該方案實現了跨域標簽功能,該標簽攜帶了關鍵信息,包括數據分布、標簽狀態、標簽的生命周期以及提交信息等。這些標簽隨著 Editlog 生成,并持久化保存在對應的文件系統鏡像(fsimage)中。
在新增文件時,系統會檢查文件的父目錄來確定對應的跨域標簽。如果父目錄包含多層,并且有多個目錄都配置了跨域標簽,系統將遵循“就近原則”,即選擇與文件最接近的跨域標簽來進行操作。這樣的處理原則確保了數據分布的合理性,并提高了存儲系統的效率和一致性。
4. 跨域數據流
跨域流量控制是跨域存儲特性的核心組成部分,它主要通過跨域標簽來管理機房間的數據流動。根據客戶端的訪問請求及其所屬機房信息,系統可以確定數據應當寫入的目標機房。
在數據寫入過程中,系統首先依據塊標簽(跨域標簽)決定同機房需要寫入的數據塊數量。完成數據塊的寫入后,這一操作將觸發元數據節點內部的一個模塊——CR check 模塊。CR check 模塊負責下發補塊任務,以實現異步的跨機房數據同步。
例如,當客戶端訪問屬于 A 機房時,數據首先會被寫入 A 機房。隨后,元數據節點將下發補塊任務,并通過異步操作在其他機房間進行數據塊的相互拷貝。這個過程確保了數據在各個機房間能夠得到一致性的維護,同時也滿足了數據冗余和可靠性的需求。通過這種方式,跨域存儲不僅優化了數據的寫入流程,還提高了整個存儲系統的穩定性和可擴展性。
5. 跨域補塊
最初階段,跨域讀取和數據同步是通過 distcp 來實現的。隨著架構的演進,現有跨域存儲架構在元數據節點內部新增了一個名為 CR check 的模塊,該模塊負責創建數據拷貝任務,以便執行跨機房間的數據復制。
就性能而言,元數據節點內部通過 CR check 模塊下發的異步補塊任務效率明顯高于 distcp 同步效率。這是因為 CR check 模塊下發的補塊任務可以分發至多個數據節點(DN)上執行,其并發性顯著提升。此外,在節點選擇方面,CR check 模塊的性能也優于 distcp。
在實際應用中,除了處理新數據的跨機房復制過程,還需要處理現有的存量數據。這涉及到批量變更目錄下跨域標簽的操作,主要源于三種操作:新增跨域標簽、刪除跨域標簽以及修改跨域標簽。特別地,修改跨域標簽通常涉及目錄的重命名操作,例如將目錄從跨域目錄轉移至非跨域目錄,或從一個跨域目錄移動到另一個跨域目錄。
這些目錄相關的操作通過內部的異步更新器模塊進行處理。該模塊調用 CR check 模塊掃描目錄下的所有文件,以判斷哪些文件需要進行跨域補充處理。這樣的設計確保了在文件層面上,跨域存儲能夠靈活地響應目錄變化,維護數據的一致性和完整性。
6. 異步更新器
異步更新器是一個關鍵組件,用于處理存量數據的異步更新任務。為了優先保障電商等優先級較高的表盡快完成跨機房數據流動,異步更新器采用了帶有優先級的隊列設計。
在處理隊列中的任務時,異步更新器會啟動一個線程,該線程會按照任務的優先級進行排序處理。在處理過程中,線程不會一次性完成一個目錄下的所有任務,而是采取輪詢方式,分步處理不同目錄下的任務。這樣的設計保證了在處理過程中,一旦有新的高優先級目錄任務加入,系統可以及時調整處理順序,優先處理這些高優先級任務。同時避免了單個大表(如 PB 級別的表)占用過多時間而導致其他任務阻塞的問題。異步更新器不會等待一個目錄下的所有任務全部完成后才開始處理下一個目錄。這種設計確保了系統處理的高效性和響應性,不僅符合了初期的設計理念,同時也避免了大表在數據遷移中對系統造成的影響。
7. 跨域流控
跨域流控是跨域存儲架構中的一個重要機制,用于管理和控制不同機房間的數據傳輸速度。在初始版本的跨域架構設計中,存在單一的跨域模塊隊列。然而,在大規模使用場景下,由于不同機房間數據存儲節點的數量和專線帶寬的差異,出現了數據補塊速度不一致的問題。這導致了在某些小機房中數據補塊速度緩慢,進而造成了跨域模塊隊列和異步更新器隊列的大量積壓。
這種積壓不僅影響了其他機房補塊的速度,還可能出現跨區域讀取數據,專線不可控的現象。為解決此問題,我們根據機房分布和數據流動方向,進行了補塊隊列的拆分,從而避免了不同機房間數據流控制的相互影響。
處理補塊任務的是 CrossRegionRedundancyMonitor 線程,它負責處理補塊隊列中的所有數據塊,并將這些塊轉化為異步補塊任務,下發到數據節點(DN)端執行。該線程復用了社區版本 ReduceMonitor 線程中處理補塊的部分邏輯,這樣既保證了非跨域補塊的時效性,同時也提升了跨域補塊的處理速度。
由于跨機房拷貝涉及專線的使用,為了減輕對專線的沖擊,我們引入了限速器。隨著模塊隊列積壓問題的出現,我們意識到統一限速存在不合理性。因此,在二次優化時,我們對限速器也進行了拆分,每個補塊隊列對應一個限速器,并且限速值可以根據專線的實時使用量動態調整。這樣的優化不僅保障了專線的穩定性,還加快了數據傳輸的速度,提高了整個跨域存儲架構的效率。
跨機房流量的管理不僅涉及數據的跨機房流動,還包括跨機房的數據讀寫操作。如前所述,所有的 RPC 請求均攜帶機房信息,系統依據該信息返回指定的存儲節點。例如,如果請求來自機房 A,則會優先寫入或讀取機房 A 的數據;若來自機房 B,則相應地操作機房 B 的數據。這種機制有效避免了大部分的跨域流量。
然而,存在一些異常情況,比如使用非標準客戶端訪問或機房信息缺失的情況,這時候存儲系統中可能沒有可用的節點信息。為了兼容這類情況,系統會根據IP 信息推斷機房位置。在獲取到機房信息后,系統按照訪問流程選擇對應的節點。如果無法選擇到合適的節點,系統可能會進行降級處理,例如允許訪問跨域標簽所指定的其他機房節點。
針對異常訪問情況,系統設有專門的任務進行監控和統計,該任務會針對異常情況進行匯總。系統需要根據關鍵信息追蹤任務來源。一旦確定了任務來源,可以通知相關的數據治理團隊進行處理,以確保數據的正確管理和優化跨機房流量的使用。通過這種方式,系統旨在減少非必要的跨機房流量,提高數據讀寫的效率。
三、分層存儲
隨著集群存儲規模的擴大,數據量的增長以及存儲節點機器類型的多樣化,一系列的挑戰和問題隨之浮現。
其中一個顯著問題是冷熱數據的管理。未對冷熱數據進行區分對待可能導致存儲資源的浪費,因為冷數據(很少訪問的數據)占用了與熱數據(頻繁訪問的數據)同等的存儲資源,對效率和成本都造成了影響。
另外,不同硬件間的差異也是一個需要關注的問題。不同硬件的存儲節點性能差異可能導致數據存取效率不一,這要求存儲系統能夠識別和優化使用不同硬件特性,以提高整體存儲性能。
數據治理的推進也是隨著存儲規模的增長而變得更加復雜和重要。有效的數據治理能夠確保數據的安全、合規以及有效使用,同時降低數據冗余和管理成本。
為了應對這些挑戰,存儲系統需要一系列的優化措施,如智能數據分層、自適應數據遷移、不同硬件性能的優化利用,以及持續的數據治理和質量控制。這些措施旨在保證存儲系統的高效運作,同時確保數據的安全性和可訪問性。
1. 存儲對比
微服務架構中,常見的存儲方案包括本地緩存、Redis 和 MySQL。這三種存儲方式各自適用于不同的數據訪問頻率和數據熱度。具體來說:
(1)本地緩存
- 存儲最頻繁訪問的數據,性能最高。
- 數據讀取速度最快,因為避免了網絡傳輸的開銷。
(2)Redis
- 存儲在內存中,但訪問數據需要通過網絡。
- 相比本地緩存,性能略有下降,但仍遠高于磁盤存儲。
(3)MySQL
- 通常用于持久化存儲,涉及到磁盤 I/O,因此性能較低。
- 適用于不頻繁訪問的數據或需要持久化保證的數據。
這種數據存儲的分層策略與 HDFS 社區提出的異構存儲策略相呼應。HDFS 的異構存儲允許將不同類型的數據存儲在不同性能的本地磁盤上。我們可以根據數據的熱度將其存儲在相應的磁盤類型上。HDFS 異構存儲的優勢在于能夠更細粒度地管理存儲,支持到磁盤級別的類型定義。然而,這種優勢在某些情況下也可能轉變為劣勢:
- 由于磁盤類型有限,不支持過多層次的定義。
- 存儲節點類型的變更可能需要重啟服務才能生效。
- 若涉及到磁盤類型新增,可能需要修改存儲節點代碼,并進行滾動升級,這對大型集群是一個復雜的過程。
- 冷熱數據之間的狀態轉換不夠靈活。
為了更高效地管理冷熱數據,我們需要一種支持冷熱數據自動轉換的分層存儲方案。這種方案能夠動態根據數據的訪問模式和熱度進行數據遷移,優化存儲資源使用,提高系統性能。
2. 京東分層存儲
京東存儲機器主要分為三種類型:SSD 盤機器、HDD 盤機器和多 HDD 盤的高密存儲機器。這三種機型的主要區別在于磁盤的性能和磁盤數量。由于 SSD 的性能優于 HDD,HDD 的小盤機器的性能又優于多磁盤 HDD 機器的性能?;趯〇|存儲機器分布現狀的分析,決定采用以下分層存儲策略:
- 熱數據:存儲在性能較高的 SSD 盤上,以提供快速的數據訪問速度。
- 溫數據:存儲在性能適中的 HDD 盤上。
- 冷數據:存儲在高密度 HDD 盤上。
這種策略不僅充分利用了不同機器類型的硬件特性,還解決了冷熱數據分層的問題,優化了存儲資源的使用。為了實現這種分層存儲,京東對網絡拓撲進行了調整,以標識不同的機器類型,并確定它們應當存儲哪些類型的數據。此外,通過修改目錄的XATTR(擴展屬性)來標識目錄中數據的冷熱需求。通過這種策略和調整,我們能夠有效地將數據定位到適合其訪問的存儲介質上,從而提高了存儲系統的整體性能。
為了實現數據的自動轉換,即熱數據與溫數據的互轉以及溫數據與冷數據的互轉,我們在元數據節點(NameNode)內部引入了一個自動轉換模塊。該模塊基于元數據節點內部的多個組件協同工作,實現了數據的動態遷移和存儲類型轉換。
數據自動轉換的實現細節如下:
- 熱數據轉換為溫數據:通過內部的數據搬移機制實現節點替換。
- 溫數據轉換為熱數據:同樣依靠數據搬移機制進行節點替換。
- 冷數據處理:利用時間生存期(TTL)功能,當數據存儲到冷數據節點時,會進行副本轉換為糾刪碼(Erasure Coding, EC)的過程,以優化存儲效率和耐久性。
為了根據不同的機器類型區分數據存儲位置,數據節點(DataNode,DN)上新增了多個屬性,包括但不限于:
- 讀寫權重:決定節點在讀寫操作中的優先級。
- 存儲使用量:反映節點的存儲空間占用情況。
- 節點健康度:指示節點的健康狀況。
在進行數據塊的選擇和寫入時,不僅可以根據存儲類型進行劃分,還可以根據 DN 節點上的這些屬性值來做出決策。這些屬性值會向上匯總到機架和更高層次的元數據中。因此,在選定機架之后,可以基于節點的健康度或讀寫權重等因素,選擇健康性更高的節點來進行數據的讀寫操作。通過這種方式,我們實現了一種動態的數據存儲策略,既優化了存儲資源的使用,又提高了數據訪問的性能和可靠性。
在實施的分層存儲方案中,涉及到多個內部模塊的修改,特別是三個核心模塊的設計與實現對于數據冷熱狀態的轉換至關重要:
- 數據訪問監視器:
該監視器默認采用最近最少使用(LRU)算法統計文件目錄的訪問情況,篩選出熱點數據。
提供 API 支持,允許變更已實現的其他策略。 - 分層管理模塊:
主要功能是掃描已標記分層標簽的目錄,結合訪問監視器提供的熱點數據信息。
對這些目錄處理,創建數據轉換任務,并提交到任務管理模塊。 - 任務管理模塊:
京東在元數據節點內部實現了一個分布式調度平臺,包含多種功能,如數據節點變更、數據類型轉換和數據生命周期管理等。
該模塊復用社區原有的任務下發機制,例如在數據節點(DN)心跳時,從元數據節點獲取數據塊刪除、復制或恢復任務。
模塊擴展了任務類型,具體任務的處理則在存儲節點上實現。
通過這些模塊的協同工作,京東的分層存儲方案有效提高了核心鏈路的整體性能。數據訪問監視器的策略改進,使得高頻訪問數據得到加速,提升了 L0 和 L1 任務的時效性,整體性能提高了 10%。同時,分層存儲方案也降低了平均存儲成本,通過高密存儲和 EC(糾刪碼)轉換,提升了 EC 數據的覆蓋率,達到 30%,并且使得冷數據存儲成本降低了90%。
京東的分層存儲方案不僅提升了數據處理的效率和速度,也顯著降低了存儲資源的成本,實現了存儲系統性能與成本的雙重優化。
3. 實踐結合
京東結合跨域存儲和分層存儲實現了兩個具體的應用場景,分別是跨域生命周期管理和數據調度功能。
(1)跨域生命周期管理
- 社區版本中的跨地方存儲可能會造成數據的過度冗余,提高存儲成本。京東的跨域存儲方案也面臨類似問題,但冗余度有所降低。
- 某些數據在平臺上寫入后很久不會被讀取,可以根據文件創建時間和跨域標簽對數據進行流動處理。從多機房數據轉換為單機房數據,并引入分層存儲功能,將單機房數據通過EC 轉換為高密存儲,從而將數據冗余度降低。這種策略大幅度降低了數據的冗余度,并將數據從性能較好的機器轉移到了適合冷存儲的機器上。
(2)數據調度功能
- 可以理解為反生命周期過程,即通過訪問監視器統計結果進行數據反向加熱。數據加熱后,結合跨域標簽進行多機房分布,提升數據讀取效率。
- 任務漂移的支持。根據計算資源的動態分配,將任務分配到資源較多的集群執行,優化線上任務的時效性。多機房之間的計算資源可能在不同時間段不一樣,任務漂移功能能夠智能地分配任務,確保數據就近處理,進一步提升任務處理的效率。
這兩個場景展示了京東如何通過智能化的存儲和數據管理策略,實現了存儲成本的優化和數據處理性能的提升??缬蛏芷诠芾硗ㄟ^動態調整數據存儲位置和方式,大幅度降低了存儲成本;而數據調度功能則確保了數據和計算資源的有效配合,提高了任務執行的時效性和效率。這些創新的存儲管理方法對于大規模分布式存儲系統來說至關重要,幫助我們實現了資源的最優化利用。