吳維偉:京東大數(shù)據(jù)的強一致、高可用跨域存儲實踐,及冷熱數(shù)據(jù)分層存儲實踐
今天的介紹會從下面三點展開:
- 京東數(shù)據(jù)平臺架構簡介
- 跨域存儲
- 分層存儲
01京東數(shù)據(jù)平臺架構簡介?
京東數(shù)據(jù)平臺的整體架構主要由六部分組成,其中數(shù)據(jù)存儲作為計算存儲層的底層組件支撐著上游的計算引擎調(diào)度,以及更高層的工具層、服務層和應用層。在整個數(shù)據(jù)平臺架構中,底層數(shù)據(jù)存儲起到了基建的作用,是整個大數(shù)據(jù)平臺的基礎。
該數(shù)據(jù)存儲系統(tǒng)的體量是數(shù)EB(1EB=1024PB),有數(shù)萬個節(jié)點,三地多中心,每天的吞吐量是百PB級別。面對如此大的數(shù)據(jù)量,京東大數(shù)據(jù)平臺采用了可視化管理,通過監(jiān)控系統(tǒng)可快速方便地定位到集群問題,保證了集群的穩(wěn)定性和服務的高可用。
02 跨域存儲
1. 跨域存儲——問題
在跨域存儲架構應用之前,跨機房數(shù)據(jù)的同步主要通過業(yè)務方在不同機房之間進行Distcp實現(xiàn),這種方式便會存在一些隱患問題:
- 第一個問題:元數(shù)據(jù)一致性由業(yè)務方保證,數(shù)據(jù)遷移需要業(yè)務介入,成本高時間長。
- 第二個問題:跨機房的流量不受控,影響同步任務,需要借助外部調(diào)度系統(tǒng)和存儲。
- 第三個問題:產(chǎn)生多份冗余數(shù)據(jù),數(shù)據(jù)共享和同步成本高,比如在不同機房不同數(shù)據(jù)節(jié)點間載入了多份相同數(shù)據(jù),導致冗余。
- 第四個問題:不具備多機房集群的容災系統(tǒng),未充分利用多機房優(yōu)勢。
2. 跨域存儲——架構
基于以上,京東大數(shù)據(jù)平臺在底層存儲模塊設計了一個跨域數(shù)據(jù)同步功能來解決歷史數(shù)據(jù)存儲同步帶來的問題。選擇在底層解決該問題不僅可以把控跨域數(shù)據(jù)的一致性,還提供了業(yè)務無感知的跨域數(shù)據(jù)同步與分享功能,以減少業(yè)務方重復工作,使存儲系統(tǒng)具備跨域遷移和跨域容災的能力。
該京東跨域存儲架構的主要思路是通過“全量存儲+全網(wǎng)拓撲”,實現(xiàn)跨機房故障域,最終實現(xiàn)大數(shù)據(jù)關鍵數(shù)據(jù)異地容災及跨機房存儲能力。
這個項目的主要挑戰(zhàn)有:
- 單集群規(guī)模龐大,達到數(shù)萬個。
- 跨域補塊與流動,存在性能瓶頸。
- 跨域心跳與塊匯報,遇到限制。
該方案的主要優(yōu)勢有:
- 強一致性:全局文件一致性,數(shù)據(jù)自動同步避免數(shù)據(jù)參差和冗余。
- 復用原理:自主跨機房補塊,跨域數(shù)據(jù)補塊由后臺自動進行。
- 易遷移:數(shù)據(jù)異動成本低,將數(shù)據(jù)與業(yè)務分開,降低成本,提高效率。
- 高可用:支持跨機房切換,提高機房容災率,增加數(shù)據(jù)安全性。
3. 跨域存儲——跨域數(shù)據(jù)流
在實現(xiàn)跨域存儲過程中,采用了兩種數(shù)據(jù)流方式:
- 異步數(shù)據(jù)流?
?將數(shù)據(jù)先寫到本地機房,再通過namenode(NN)自動進行跨域同步。該數(shù)據(jù)傳輸方式寫入性能與現(xiàn)有未跨域場景一致,同步時延優(yōu)于 distcp 方案。
- 同步數(shù)據(jù)流
建立pipeline數(shù)據(jù)管道,串聯(lián)機房全部datanode(DN),一次將數(shù)據(jù)同步。該種傳輸方式針對數(shù)據(jù)一致性和可靠性要求高的業(yè)務。
4. 跨域存儲——拓撲與機房感知
拓撲與機房感知是解決“節(jié)點定位”這一跨域存儲核心問題的關鍵模塊?;谠撃K可控制數(shù)據(jù)塊分布和控制客戶端流量。該模塊主要從兩個方面解決問題:
- 拓撲管理
通過改造節(jié)點的拓撲方式,在拓撲管理中增加一個機房維度,同時選塊邏輯要基于全網(wǎng)拓撲模塊進行適配,以兼容多機房。
- 機房感知
針對跨域版本的客戶端,可通過在RPC頭部攜帶機房信息,以便識別和檢索;針對不支持跨域版本的客戶端,可通過京東網(wǎng)絡服務團隊提供的ip映射到機房的服務, 實現(xiàn)客戶端對應機房的檢索和查詢。
5. 跨域存儲——跨域標識
跨域標識模塊是解決“數(shù)據(jù)跨機房存放”問題的關鍵設計,我們采用一個支持副本和EC的屬性標簽來描述數(shù)據(jù)的跨域?qū)傩浴@鏏:3,B:2,C:2,A,status,[period],[start,end],即表示在A機房有3個副本;B機房有2個副本;C機房有2個副本;A機房是跨域傳輸?shù)闹鳈C房;[status]為標識存量數(shù)據(jù)內(nèi)部流轉(zhuǎn)的狀態(tài),包括“init、processing、done、invalid”四個狀態(tài);[period]用于跨域機房配置的時間戳,描述跨域數(shù)據(jù)的生命周期策略;[start,end]是另外一種數(shù)據(jù)共享生命周期配置方式,數(shù)據(jù)共享起止時間可通過絕對時間指定。
EC包含數(shù)據(jù)塊和校驗塊兩種類型, 相對于副本模式其跨域同步的支持更加復雜,需要支持在同機房內(nèi)的數(shù)據(jù)重構和重構條件不具備時的跨域數(shù)據(jù)拷貝,以減少 EC 數(shù)據(jù)在跨域場景下的跨域同步流量。
加快整體跨域數(shù)據(jù)處理的速度,采用了三種方法:
- 將元數(shù)據(jù)固化在XATTR上
- 在內(nèi)存上構建了Inode Proto
- 在每個數(shù)據(jù)塊上,創(chuàng)建塊屬性標識
6. 跨域存儲——跨域補塊及流控
針對跨域補塊和流控,采用了三種方法保證了性能:
- 在處理跨域補塊時遵從的原理是跨域處理與原有流程隔離,保證新增的跨域處理流程不影響原先同機房的補塊處理,在遇到機房網(wǎng)絡中斷等極端情況可以保障單機房元數(shù)據(jù)服務可用。
- 新增異步跨域更新器,結合跨域標簽屬性,實現(xiàn)HA切換接續(xù)補塊,解決存量數(shù)據(jù)問題。
- 采用CR-Checker程序替代原有的DistCopy任務,可以將原先的跨集群同步任務平滑升級成跨域同步任務,最大限度減少跨域架構升級對原有存量任務的沖擊。
跨域補塊的邏輯如右圖所示。對于增量的數(shù)據(jù),分為兩個模塊,同機房塊的增量數(shù)據(jù)通過原有的RedundancyMonitor進行補塊,對于跨域塊會放置到CrossRegionRedundancyMonitor模塊進行補塊。新增的更新器主要處理跨域配置和目錄變更等跨域標簽變更場景,經(jīng)過跨域要求判斷后加入到CrossRegionRedundancyMonitor模塊進行補塊處理。
跨域流控分為四個部分:
- 跨域補塊流控,通過配置帶寬嚴格控制跨域帶寬。
- 讀寫優(yōu)先客戶端同機房DN,基于前面介紹的機房感知功能,去匹配客戶端和DN所屬機房,確保只讀取同機房的DN數(shù)據(jù),避免產(chǎn)生跨域流量。
- 跨域讀寫流控,針對沒有攜帶跨域標識的數(shù)據(jù)有跨域客戶端訪問時,對新版本用戶端和老版本用戶端有兩種處理方法。對新版本客戶端,會在NN做流量的統(tǒng)計和背壓處理,保證讀寫不會影響核心專線的流量帶寬;對于老版本客戶端,會在DN處對流量進行統(tǒng)計和上報,如果超過限額后,會進行背壓處理。
- Balancer機房內(nèi)部均衡,在同機房節(jié)點上進行數(shù)據(jù)均衡。
03分層存儲?
1. 分層存儲——問題
數(shù)據(jù)分層存儲是為了解決原有框架所存在的問題:
- 冷熱數(shù)據(jù)未區(qū)分對待。例如實時核心數(shù)據(jù)與舊數(shù)據(jù)未區(qū)分,導致無法做核心數(shù)據(jù)的加速處理。
- 不同硬件類型未區(qū)分對待。存儲系統(tǒng)長期演進,集群內(nèi)存在多種不同類型的存儲機型,之前版本對不同存儲機型未加區(qū)分處理,無法充分利用硬件特性。
- 數(shù)據(jù)治理需要協(xié)同用戶處理,存在較大工作量,推進困難。
2. 分層存儲
針對以上問題,我們需要在分層存儲上完成以下功能要求:實現(xiàn)數(shù)據(jù)自動整理,將冷熱數(shù)據(jù)通過打標簽進行分級處理——分為Hot、Warm、Cold。將不同硬件機型也進行分級處理——分為SSD、HDD、高密存儲。將實時熱數(shù)據(jù)與性能較好的DN相匹配,存儲在SSD的硬件上,而冷數(shù)據(jù)則存儲在高密存儲硬件上,實現(xiàn)資源合理搭配。
3. 分層存儲——使用場景
針對上述數(shù)據(jù)分層存儲的實現(xiàn)方案,主要有以下三個應用場景:
- 存儲加速?
對熱數(shù)據(jù)和核心數(shù)據(jù)提供加速手段,分時分層。例如在夜晚核心時間段,將其分為三個時間段,在對應時段將該時段的熱數(shù)據(jù)搬移到高性能的存儲機器上,這種處理方法可以在核心時段賦能更多的業(yè)務數(shù)據(jù)。
- 冷存歸檔?
僵冷數(shù)據(jù)存儲到高密存儲機器上,優(yōu)化單位存儲成本。業(yè)務方通過配置集群維度的動態(tài)規(guī)則,完成冷熱數(shù)據(jù)的自動分配,將冷數(shù)據(jù)存儲到高密數(shù)據(jù)上,對于過度僵冷的數(shù)據(jù)會直接轉(zhuǎn)化為EC(Erasure Coding),進一步降低存儲成本。
- 邏輯子集群?
支持按業(yè)務/目錄維度劃分邏輯子集群,實現(xiàn)數(shù)據(jù)隔離。針對新上線的機型,可采用該邏輯去摸索其性能;針對服務器擴容,可對新服務器增加寫權重,提高存入數(shù)量。對于應急情況,可快速分離出故障機器,不影響整體的存量數(shù)據(jù)可靠性。
4. 分層存儲——架構
上面介紹了分層存儲的邏輯和應用場景,下面將介紹分層存儲的架構,整個框架主要是在NN內(nèi)部實現(xiàn)的:
- 分層策略配置:提供外部API下發(fā)及內(nèi)部配置。
- 分層配置API:提供分層策略下發(fā)接口,外部可通過離線數(shù)據(jù)分析及業(yè)務側(cè)下發(fā)分層邏輯。
- 內(nèi)置分層策略:可配置和動態(tài)刷新的分層策略,默認通過訪問監(jiān)控器統(tǒng)計數(shù)據(jù)進行LRU分層策略配置。
- 標簽管理器:實現(xiàn)目錄標簽和節(jié)點標簽管理,指導選塊模塊及分布校驗器等模塊進行數(shù)據(jù)遷移。
- 數(shù)據(jù)分布校驗器:實現(xiàn)對新增數(shù)據(jù)的分布校驗,指導數(shù)據(jù)按照標簽進行分布。
- 存量數(shù)據(jù)滿足器:對存量數(shù)據(jù)進行掃描驗證,指導存量數(shù)據(jù)塊遷移;實現(xiàn)數(shù)據(jù)生命周期管理功能。
5. 分層存儲——核心設計
分層存儲的核心設計,可以分為兩個模塊,一個是元數(shù)據(jù)上根據(jù)目錄樹進行標簽管理,對數(shù)據(jù)進行冷熱數(shù)據(jù)分配;另一塊是節(jié)點拓撲樹,采用虛擬多拓撲樹在邏輯上將不同標簽的節(jié)點進行區(qū)分,不同標簽類型會有自己獨立的拓撲樹,實現(xiàn)更高效的選節(jié)點性能。虛擬拓撲樹有兩種更新方式,分別為根據(jù)節(jié)點權重進行異步更新和上下線數(shù)據(jù)進行同步更新。
增量數(shù)據(jù)和存量數(shù)據(jù)在處理流程上有以下差異:
- 增量數(shù)據(jù):對于寫入請求,先判斷標簽,然后根據(jù)匹配對應節(jié)點,寫入數(shù)據(jù)。
- 存量數(shù)據(jù):后臺數(shù)據(jù)分布校驗會掃描數(shù)據(jù)的標簽,基于虛擬拓撲樹匹配對應的節(jié)點,然后完成數(shù)據(jù)遷移或轉(zhuǎn)換。
04 問答?
Q1:數(shù)據(jù)遷移到高密集群是通過什么方法,基于什么策略?
A1:我們是基于分層功能來實現(xiàn)數(shù)據(jù)遷移,整體的處理邏輯是基于動態(tài)規(guī)則的設定,將數(shù)據(jù)分為冷、溫、熱三種類型。針對溫數(shù)據(jù)采用類 Balancer 的實現(xiàn)方式,將數(shù)據(jù)搬移到高密存儲上;針對冷數(shù)據(jù)我們是在 HDFS 內(nèi)部實現(xiàn)一套簡單的調(diào)度系統(tǒng),將掃描發(fā)現(xiàn)的冷數(shù)據(jù)發(fā)送給DN,由 DN實現(xiàn)數(shù)據(jù)的搬移和原地轉(zhuǎn)EC。
Q2:京東有做HDFS計費的考慮嗎,有哪些維度?
A2:計費功能也是我們下一步要重點投入的方向,整體的思路是通過計費功能指導業(yè)務方更合理高效的使用存儲集群。目前我們將寫操作和讀操作進行分級,因為寫操作對NN的壓力比較大,因此寫操作的計費權重會超過讀操作計費權重,比例大概是 10 倍左右。在NN側(cè)會將計費信息匯總到HDFS Router,做一個統(tǒng)一全集群的計費匯總統(tǒng)計。HDFS Router會定期將統(tǒng)計信息下發(fā)給NN,NN基于統(tǒng)計信息對用戶訪問進行分級處理,超過預設額度的業(yè)務方訪問會被降級處理。
Q3:NN的壓力會不會很大,對NN有何優(yōu)化處理?
A3:在NameNode 內(nèi)部新增模塊時,會實時統(tǒng)計各模塊對 NameNode 內(nèi)部核心鎖的占用時間,當新增模塊的占鎖時間超過設定閾值,程序會動態(tài)縮減模塊的占鎖時間,保證不影響NameNode對外的吞吐量。
今天的分享就到這里,謝謝大家。