中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Uber如何為大規(guī)模Apache Hadoop表實(shí)現(xiàn)一致性數(shù)據(jù)分區(qū)?

2019-06-04    來源:raincent

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬Linux鏡像隨意使用

導(dǎo)讀:為了可靠且一致地找到數(shù)據(jù)的位置,本文作者及其同事開發(fā)了一個(gè)名為全局索引(Global Index)的組件。這個(gè)組件負(fù)責(zé)在 Hadoop 表中簿記(bookkeeping)并查找數(shù)據(jù)位置。它提供了高吞吐量、強(qiáng)一致性和水平可擴(kuò)展能力,并幫助用戶更好地更新 Hadoop 表中數(shù)以 PB 計(jì)的數(shù)據(jù)。

本文作為對(duì)之前大數(shù)據(jù)博客系列文章(https://eng.uber.com/tag/big-data/)的擴(kuò)展,將會(huì)闡述解決如此大規(guī)模問題所涉及的挑戰(zhàn),并分享如何利用開源軟件解決這些問題的經(jīng)驗(yàn)。

 

 

找不到的數(shù)據(jù)是沒有價(jià)值的。優(yōu)步積累的數(shù)據(jù)量超過 100PB,從這些數(shù)據(jù)中挖掘到的信息能夠幫助我們不斷進(jìn)步,獲得有價(jià)值的見解以改善我們的服務(wù)——例如為騎手提供更精確的到達(dá)時(shí)間預(yù)測(cè),或向食客展示他們最愛的食品類別等等。查詢?nèi)绱舜笠?guī)模的數(shù)據(jù)庫(kù)并及時(shí)提供結(jié)果并非易事,但只有達(dá)成這一目標(biāo),才能讓優(yōu)步的團(tuán)隊(duì)獲得足夠的洞察力,從而為客戶提供出色的無縫體驗(yàn)。

為了實(shí)現(xiàn)上述目標(biāo),我們通過分離存儲(chǔ)和查詢層來構(gòu)建優(yōu)步的大數(shù)據(jù)平臺(tái)(https://eng.uber.com/uber-big-data-platform/),以使存儲(chǔ)和查詢層都可以獨(dú)立擴(kuò)展。我們?cè)?HDFS 上存儲(chǔ)分析數(shù)據(jù)集,將它們注冊(cè)為外部數(shù)據(jù)表,并使用 Apache Hive、Presto 和 Apache Spark 等查詢引擎為它們服務(wù)。這個(gè)大數(shù)據(jù)平臺(tái)為團(tuán)隊(duì)提供了可靠且可擴(kuò)展的分析能力,以保證我們的服務(wù)準(zhǔn)確無誤,并得到持續(xù)的改進(jìn)。

在優(yōu)步出行服務(wù)的整個(gè)生命周期中,在諸如行程創(chuàng)建、出行時(shí)間更新和車手審查更新等事件期間就會(huì)有新的信息更新到行程數(shù)據(jù)中。為實(shí)現(xiàn)這類更新,需要在修改和保存數(shù)據(jù)之前查找數(shù)據(jù)的位置。當(dāng)這類查找行為增加到每秒數(shù)百萬次操作的規(guī)模時(shí),我們發(fā)現(xiàn)開源鍵值存儲(chǔ)已經(jīng)無法滿足我們的可擴(kuò)展需求了——它們要么無法滿足吞吐量要求,要么會(huì)損失精確度。

為了可靠且一致地找到數(shù)據(jù)的位置,我們開發(fā)了一個(gè)名為全局索引(Global Index)的組件。這個(gè)組件負(fù)責(zé)在 Hadoop 表中簿記(bookkeeping)并查找數(shù)據(jù)位置。它提供了高吞吐量、強(qiáng)一致性和水平可擴(kuò)展能力,并幫助我們更好地更新 Hadoop 表中數(shù)以 PB 計(jì)的數(shù)據(jù)。本文作為對(duì)之前大數(shù)據(jù)博客系列文章(https://eng.uber.com/tag/big-data/)的擴(kuò)展,將會(huì)闡述解決如此大規(guī)模問題所涉及的挑戰(zhàn),并分享我們利用開源軟件解決這些問題的經(jīng)驗(yàn)。

數(shù)據(jù)引入的負(fù)載類型

優(yōu)步的 Hadoop 數(shù)據(jù)大致可分為兩種類型:僅附加(append-only)和附加并更新(append-plus-update)。僅附加數(shù)據(jù)代表不可變事件。在優(yōu)步術(shù)語(yǔ)中,不可變事件可能包含行程的付款歷史記錄。附加并更新數(shù)據(jù)顯示任意給定時(shí)間點(diǎn)的實(shí)體最新狀態(tài)。例如,在行程結(jié)束時(shí)間的實(shí)例中,其中行程是實(shí)體,結(jié)束時(shí)間是對(duì)實(shí)體的更新;結(jié)束時(shí)間是估測(cè)的,直到行程結(jié)束之前都可以變動(dòng)。

由于每個(gè)事件是獨(dú)立的,因此引入僅附加數(shù)據(jù)不需要任何前值的上下文。但將附加并更新數(shù)據(jù)引入到數(shù)據(jù)集就不一樣了。雖然我們收到的數(shù)據(jù)更新只涉及數(shù)據(jù)的部分內(nèi)容,但我們?nèi)孕枰峁┳钚虑彝暾男谐炭煺铡?/p>

附加并更新數(shù)據(jù)的負(fù)載

數(shù)據(jù)集構(gòu)建通常有兩個(gè)階段:bootstrap(引導(dǎo))和 incremental(增量)。在引導(dǎo)階段,來自上游的大量歷史數(shù)據(jù)會(huì)在短時(shí)間內(nèi)引入完畢。一般來說這一階段出現(xiàn)在數(shù)據(jù)集首次上線或重啟維護(hù)期間。增量階段會(huì)接收來自上游的最新增量改動(dòng)并將其應(yīng)用于數(shù)據(jù)集。數(shù)據(jù)集生命周期的大部分時(shí)間都處于這一階段,以確保數(shù)據(jù)同上游來源同步更新。

數(shù)據(jù)引入的本質(zhì)就是對(duì)數(shù)據(jù)做組織優(yōu)化,從而取得讀取性能和新數(shù)據(jù)寫入性能的平衡。為了提升讀取性能,一種優(yōu)化措施是對(duì)數(shù)據(jù)分區(qū)后再做查詢,從而盡量減少每次查詢需要讀取的數(shù)據(jù)量。由于分析數(shù)據(jù)集往往會(huì)讀取很多次,所以分區(qū)后就不需要掃描整個(gè)數(shù)據(jù)集了。為了提升寫入性能,數(shù)據(jù)布局會(huì)分布在不同分區(qū)內(nèi)的多個(gè)文件中,以實(shí)現(xiàn)并行寫入操作;而且將來更新數(shù)據(jù)時(shí),只需要向包含更新內(nèi)容的文件寫入新數(shù)據(jù)就行了。

提升數(shù)據(jù)更新時(shí)寫入性能的另一個(gè)辦法是開發(fā)一個(gè)組件,用來快速查找我們的大數(shù)據(jù)生態(tài)系統(tǒng)中現(xiàn)有數(shù)據(jù)的位置。這個(gè)引入組件名為全局索引,負(fù)責(zé)維護(hù)數(shù)據(jù)布局的簿記信息。該組件需要強(qiáng)一致性才能正確判斷接收的數(shù)據(jù)屬于插入還是更新類型。在分類時(shí),插入數(shù)據(jù)(例如我們的新行程)會(huì)被分組并寫入新文件,而更新數(shù)據(jù)(例如行程的結(jié)束時(shí)間)將寫入由全局索引標(biāo)識(shí)的對(duì)應(yīng)預(yù)設(shè)文件,如下圖 1 所示:

 

 

圖 1:在我們的引入流程中,全局索引對(duì)數(shù)據(jù)集的插入和更新數(shù)據(jù)做分類,還要查找需要寫入的對(duì)應(yīng)文件以實(shí)現(xiàn)更新。

下圖是全局索引在數(shù)據(jù)引入體系中的功能示意。

 

 

圖 2:優(yōu)步的數(shù)據(jù)架構(gòu)示意圖,展示全局索引如何集成到數(shù)據(jù)引入平臺(tái)。

要實(shí)現(xiàn)全局索引,常見的解決方案是使用主流的鍵值存儲(chǔ)技術(shù),諸如 HBase(https://hbase.apache.org/)或 Cassandra(http://cassandra.apache.org/)等。這類鍵值存儲(chǔ)可以支持每秒數(shù)十萬,具備強(qiáng)一致性的讀 / 寫請(qǐng)求(https://academy.datastax.com/planet-cassandra/nosql-performance-benchmarks)。

對(duì)于大型數(shù)據(jù)集而言,引導(dǎo)階段的吞吐量需求(每個(gè)數(shù)據(jù)集每秒數(shù)百萬個(gè)請(qǐng)求的數(shù)量級(jí))非常高,因?yàn)樾枰谙鄬?duì)較短的時(shí)間內(nèi)引入大量數(shù)據(jù)。在優(yōu)步的大型數(shù)據(jù)集的引導(dǎo)階段,吞吐量需求約為每秒數(shù)百萬個(gè)請(qǐng)求。但在增量階段,吞吐量需求要低得多(每個(gè)數(shù)據(jù)集每秒數(shù)千個(gè)請(qǐng)求),偶爾出現(xiàn)的高峰期也可以通過請(qǐng)求速率限制來控制。

全局索引的其它需求包括大規(guī)模索引讀 / 寫、強(qiáng)一致性和合理的索引讀 / 寫放大等。如果我們將面臨的挑戰(zhàn)劃分為引導(dǎo)階段索引和增量階段索引,就可以使用一個(gè)擴(kuò)展的鍵值存儲(chǔ)解決增量階段的索引問題,但引導(dǎo)階段的索引可能會(huì)另尋出路。要深入理解這種策略的背景,我們要先搞明白兩個(gè)階段面臨的負(fù)載差異。

引導(dǎo)階段數(shù)據(jù)引入的索引

在引導(dǎo)階段,如果源數(shù)據(jù)是處理優(yōu)化過的,保證所有的輸入數(shù)據(jù)都是插入類型(如圖 1 所示),那就不需要全局索引了。但在增量階段,我們無法確保輸入的數(shù)據(jù)都是插入類型的,因?yàn)槲覀儽仨毝ㄆ谝霐?shù)據(jù),隨時(shí)都可能引入對(duì)某行數(shù)據(jù)的更新。因此在增量階段開始之前需要使用索引來更新鍵值存儲(chǔ)。

我們用這個(gè)屬性來設(shè)計(jì)引導(dǎo)階段的數(shù)據(jù)引入架構(gòu)。由于鍵值存儲(chǔ)的請(qǐng)求吞吐量有限,我們從數(shù)據(jù)集生成索引,并將它們批量上載到鍵值存儲(chǔ),避免碎片化的寫入請(qǐng)求,這樣就消除了典型的寫入性能瓶頸。

 

 

圖 3:在引導(dǎo)數(shù)據(jù)引入期間對(duì)源數(shù)據(jù)分組以使其不包含更新內(nèi)容,此時(shí)可以跳過全局索引步驟。引導(dǎo)數(shù)據(jù)引入完成后,對(duì)應(yīng)的索引會(huì)批量上傳到 HBase,使數(shù)據(jù)集做好準(zhǔn)備進(jìn)入下一階段,即增量數(shù)據(jù)引入。

選擇合適的鍵值存儲(chǔ)方案

基于上述優(yōu)化策略,在增量階段用于索引的鍵值存儲(chǔ)需要強(qiáng)一致性的讀 / 寫能力,且能夠擴(kuò)展到每個(gè)數(shù)據(jù)集每秒數(shù)千個(gè)請(qǐng)求的規(guī)模,還要有可靠的索引批量上傳策略(例如設(shè)法避免寫入性能瓶頸)。

HBase 和 Cassandra 是優(yōu)步常用的兩個(gè)鍵值存儲(chǔ)方案。我們選擇使用 HBase 來做全局索引,原因如下:

與 Cassandra 不同,HBase 只允許一致的讀寫,因此不需要調(diào)整一致性參數(shù)。

HBase 提供群集中 HBase 表的自動(dòng)重平衡能力。其主從架構(gòu)允許獲取跨集群傳播的數(shù)據(jù)集的全局視圖,這個(gè)視圖能幫助我們定制每個(gè) HBase 集群的數(shù)據(jù)集吞吐量。

使用 HFiles 生成和上傳索引

我們以 HBase 的內(nèi)部存儲(chǔ)文件格式 HFile(https://blog.cloudera.com/blog/2012/06/hbase-io-hfile-input-output/)生成索引,并將它們上傳到我們的 HBase 集群。HBase 基于區(qū)域服務(wù)器(https://mapr.com/blog/in-depth-look-hbase-architecture/)上的有序、非重疊鍵范圍,使用 HFile 文件格式分區(qū)數(shù)據(jù)。數(shù)據(jù)在每個(gè) HFile 中根據(jù)鍵值和列名排序。為了以 HBase 期望的格式生成 HFile,我們使用 Apache Spark 在一組機(jī)器上執(zhí)行大規(guī)模分布式操作。

首先從引導(dǎo)數(shù)據(jù)集中將索引信息提取為彈性分布式數(shù)據(jù)集(RDD),如下面的圖 4 所示,然后基于鍵值使用 RDD.sort() 做全局排序。

 

 

圖 4:我們的大數(shù)據(jù)生態(tài)系統(tǒng)中,存儲(chǔ)在 HBase 中的索引模型包含的實(shí)體是綠色部分,這些實(shí)體有助于識(shí)別需要更新的文件,這些文件對(duì)應(yīng)附加并更新數(shù)據(jù)集中的指定記錄。

我們布局 RDD 的方式是讓每個(gè) Apache Spark 分區(qū)負(fù)責(zé)獨(dú)立寫出一個(gè) HFile。在每個(gè) HFile 中,HBase 期望內(nèi)容按照下面的圖 5 所示布置,以便根據(jù)鍵值和列名對(duì)它們進(jìn)行排序。

 

 

圖 5:HFile 中索引條目的布局允許我們根據(jù)鍵值和列進(jìn)行排序。

然后對(duì) RDD 應(yīng)用 RDD.flatMapToPair() 轉(zhuǎn)換,以組織圖 5 所示布局中的數(shù)據(jù)。但此轉(zhuǎn)換不保留 RDD 中條目的順序,因此我們使用 RDD.repartitionAndSortWithinPartitions() 執(zhí)行分區(qū)隔離排序,但不對(duì)分區(qū)做任何更改。不更改分區(qū)是很重要的,因?yàn)槊總(gè)分區(qū)都已經(jīng)被選定來表示 HFile 中的內(nèi)容了。然后使用 HFileOutputFormat2 保存生成的 RDD。使用這種方法后,我們的一些索引高達(dá)數(shù)十 TB 的超大規(guī)模數(shù)據(jù)集只需不到兩個(gè)小時(shí)就能生成 HFile。

 

 

圖 6:Apache Spark 中的 FlatMapToMair 轉(zhuǎn)換不保留條目的順序,因此要執(zhí)行分區(qū)隔離排序。分區(qū)不做更改以確保每個(gè)分區(qū)仍然對(duì)應(yīng)于非重疊的鍵范圍。

現(xiàn)在使用名為 LoadIncrementalHFiles 的功能將 HFile 上載到 HBase。如果沒有完全包含 HFile 中鍵范圍的預(yù)設(shè)區(qū)域,或者 HFile 尺寸大于設(shè)定閾值,則在 HBase 上傳期間會(huì)觸發(fā)稱為 HFile-splitting(HFile 分裂)的過程。

分裂會(huì)嚴(yán)重影響 HFile 的上傳速度,因?yàn)榇诉^程需要重寫整個(gè) HFile。我們通過讀取 HFile 鍵范圍并將 HBase 表預(yù)分割成與 HFile 一樣多的區(qū)域來避免 HFile 分裂,這樣每個(gè) HFile 都能適配一個(gè)區(qū)域。只讀取 HFile 鍵范圍比重寫整個(gè)文件消耗的資源少幾個(gè)數(shù)量級(jí),因?yàn)?HFile 鍵范圍是存儲(chǔ)在標(biāo)頭塊中的。對(duì)于我們的一些索引高達(dá)數(shù)十 TB 的大規(guī)模數(shù)據(jù)而言集,上傳 HFile 只需不到一個(gè)小時(shí)。

 

 

圖 7:HFile 被寫入托管 HBase 的集群,以確保 HBase 區(qū)域服務(wù)器在上傳過程中可以訪問它們。

增量引入期間的索引

生成索引后,每個(gè)行鍵和文件 ID 之間的映射就不會(huì)更改了。我們不會(huì)索引批量引入的所有記錄,而是僅索引插入數(shù)據(jù)。這樣我們就能把 HBase 的寫入請(qǐng)求控制在性能限制范圍內(nèi),并滿足我們的吞吐量需求。

限制 HBase 訪問

如前所述,HBase 的擴(kuò)展能力是有極限的。在增量階段偶爾會(huì)出現(xiàn)峰值負(fù)載,因此我們需要限制對(duì) HBase 的訪問。下面的圖 8 顯示了多個(gè)獨(dú)立的引入作業(yè)如何同時(shí)訪問 HBase:

 

 

圖 8:對(duì)應(yīng)于三個(gè)不同數(shù)據(jù)集的三個(gè) Apache Spark 作業(yè)訪問其各自的 HBase 索引表,在托管這些表的 HBase 區(qū)域服務(wù)器上創(chuàng)建負(fù)載。

我們根據(jù)影響 Hbase 請(qǐng)求數(shù)量的幾個(gè)因素,控制獨(dú)立 Apache Spark 作業(yè)對(duì)區(qū)域服務(wù)器的每秒累積寫入速度:

1、作業(yè)并行度:作業(yè)中 HBase 的并行請(qǐng)求數(shù)。

2、區(qū)域服務(wù)器數(shù)量:托管特定 HBase 索引表的服務(wù)器數(shù)量。

3、輸入 QPS 積分:跨數(shù)據(jù)集的累積 QPS 的積分。一般來說,這個(gè)積分是數(shù)據(jù)集中行數(shù)的加權(quán)平均值,以確?鐢(shù)據(jù)集的 QPS 的公平份額。

4、內(nèi)部測(cè)得的 QPS:區(qū)域服務(wù)器可以處理的 QPS。

下面的圖 9 顯示了當(dāng) HBase 區(qū)域服務(wù)器添加到 HBase 集群時(shí),調(diào)整限制算法以處理更多查詢的一次實(shí)驗(yàn)。

 

 

圖 9:盡管數(shù)據(jù)集的 QPS 積分保持不變,但隨著一個(gè) HBase 集群中的服務(wù)器數(shù)量增加,使用全局索引的單個(gè)數(shù)據(jù)集也能獲得線性的 QPS 增長(zhǎng)。

系統(tǒng)限制

雖然我們的全局索引系統(tǒng)有助于提高數(shù)據(jù)的可靠性和一致性,但它也存在一些局限性,如下所述:

根據(jù) CAP 定理(https://en.wikipedia.org/wiki/CAP_theorem),HBase 提供了一致性和分區(qū)容錯(cuò)能力,但無法提供 100%的可用性。由于引入作業(yè)對(duì)時(shí)間不是非常敏感,因此我們可以在少見的 HBase 停機(jī)期間以較寬松的條件處理作業(yè)。

限制流程假定索引表均勻分布在所有區(qū)域服務(wù)器上。但對(duì)于只包含少量索引的數(shù)據(jù)集,情況可能并非如此。這種情況下它們得到的 QPS 份額就不夠,所以我們要提高其 QPS 積分來做補(bǔ)償。

如果 HBase 中的索引已損壞或表因?yàn)?zāi)難事件而變得不可用,則需要災(zāi)難恢復(fù)機(jī)制。我們當(dāng)前的策略是重用前述過程,從數(shù)據(jù)集生成索引并上傳到新的 HBase 集群。

未來展望

我們的全局索引方案使數(shù)以 PB 計(jì)的數(shù)據(jù)能夠運(yùn)行在優(yōu)步的大數(shù)據(jù)平臺(tái)上,滿足我們的 SLA 和需求。但我們也在考慮一些改進(jìn)措施:

例如,我們通過確保引入僅附加類型的數(shù)據(jù)簡(jiǎn)化了引導(dǎo)引入階段的全局索引問題,但這可能不適用于所有的數(shù)據(jù)集。因此,我們需要一個(gè)解決此問題的可擴(kuò)展解決方案。

我們希望探索出一種索引解決方案,可以不再需要 HBase 等鍵值存儲(chǔ)一類的外部依賴。

作者:Nishith Agarwal,Kaushik Devarajaiah

譯者:王強(qiáng)編輯 Vincent

查看英文原文:https://eng.uber.com/data-partitioning-global-indexing/

標(biāo)簽: [db:TAGG]

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:大數(shù)據(jù)“獨(dú)角獸”折戟:MapR 或?qū)⒉脝T百余人,并關(guān)閉硅谷總部

下一篇:2019 到目前為止的深度學(xué)習(xí)研究進(jìn)展匯總