轉載請注明 : [過把火] http://www.reibang.com/p/29d17aa23116
序
一直都沒有很系統(tǒng)地閱讀過RDD的原始論文,最近翻出來研讀一遍,并作此記錄僧著。
《Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster Computing》
總
閱讀完之后,唯一的感覺就是---RDD(彈性分布式數據集)完全是伯克利的博士起的一個很抽象的名字罷了芹壕,換句話說就是為了發(fā)論文而起的一個高大上的名字燃辖。但是這并不妨礙RDD的思想依然是diaodiao的。
動機
當前很多分布式計算框架無法實現高效的迭代式計算以及交互式數據挖掘踏烙,包括Hadoop师骗!,首先為了解決高效這個問題讨惩,RDD提出基于內存的迭代思想辟癌,直接鄙視了Hadoop要不斷進行磁盤Spill的弊端;其次荐捻,為了保證大數據場景下迭代計算的正常運轉黍少,RDD自身具有高容錯快恢復的特點。
背景及意義
1靴患、Hadoop仍侥?
Hadoop為分布式大規(guī)模數據的計算而生,但別忘了鸳君,Hadoop依托于HDFS农渊,在沒有與Spark進行對比之前,可能并不會刻意去思考為何需要HDFS,可能這個問題很容易回答砸紊,不就是一個存儲倉庫嘛传于,ok,就先這樣認為醉顽。
2沼溜、RDD與Spark的關系?
Spark就是RDD的具體實現游添。
3系草、Spark VS Hadoop
相同數據集的重復利用的這種特性在很多領域或算法中常見,例如機器學習唆涝,就是對同一數據集不斷進行收斂或是梯度下降找都,不管什么方式,對象都是同一數據分片廊酣。那么這種業(yè)務丟給Hadoop-MR來做的話能耻,無非就是每計算完一次,Spill到HDFS進行多副本存儲亡驰,單就這個多副本存儲來講晓猛,數據量一大,IO及磁盤的負擔將會成為整個業(yè)務流程的瓶頸凡辱,換句話說戒职,做一次PageRank,加入設定10次收斂透乾,那么MR整體會寫9次帕涌,這還不算,寫完后還得讀出來繼續(xù)迭代续徽,我的天蚓曼,互聯(lián)網發(fā)展到如今地步,數不清的網頁钦扭,數不清的圖節(jié)點纫版,照這樣進行rank,可想而知背后需要多好的磁盤性能來做保障客情,當然其弊,運維人員有飯吃那是肯定的。
OK膀斋,RDD概念一出梭伐,使得這些業(yè)務邏輯無需每次都得先保存后計算,而是將數據顯式地存儲在內存中進行迭代仰担,同時允許用戶控制數據分區(qū)糊识。這些還都不是最大的特點,RDD最大的特點是能夠通過記錄數據集的一些列轉換方式來執(zhí)行這些task,這樣一來赂苗,某一分片若是丟失愉耙,則可以從該RDD的記錄中去就近恢復該分片,而不是從頭執(zhí)行拌滋!最后一點朴沿,RDD中所記錄的這些所謂的轉換方式其實就是該RDD的誕生方式,也稱作是“血緣”败砂。因此赌渣,這種方式在不用大規(guī)模保存副本的同時也能夠有很好地容錯表現。
RDD---Resilient Distributed Datasets
1 RDD概念
1昌犹、RDD是一個只讀的锡垄、有分區(qū)的分布式數據集。其分類主要有兩種:transformations和action祭隔。這兩種RDD負責不同的業(yè)務。transformations負責數據分片的轉換路操,而action負責激活整個計算鏈條的實際計算疾渴。
2、RDD運轉方式
RDD只需知道自己是怎么誕生的就可以了屯仗,這就是RDD的實際工作方式搞坝。
2 RDD與傳統(tǒng)DSM對比
RDD作為對內存的抽象,與其相類似的就是分布式共享內存年系統(tǒng)(DSM)魁袜。
RDDs 只能通過粗粒度的轉換被創(chuàng)建(或者被寫) , 然而 DSM 允許對每一個內存位置進行讀寫, 這個是 RDDs 和 DSM 最主要的區(qū)別. 這樣使都 RDDs在 應用中大量寫數據受到了限制, 但是可以使的容錯變的更加高效. 特別是, RDDs 不需要發(fā)生非常耗時的 checkpoint 操作, 因為它可以根據 lineage 進行恢復數據 . 而且, 只有丟掉了數據的分區(qū)才會需要重新計算, 并不需要回滾整個程序, 并且這些重新計算的任務是在多臺機器上并行運算的.
RDDs 的第二個好處是:它不變的特性使的它可以和 MapReduce 一樣來運行執(zhí)行很慢任務的備份任務來達到緩解計算很慢的節(jié)點的問題. 在 DSM 中, 備份任務是很難實現的, 因為原始任務和備份任務或同時更新訪問同一個內存地址和接口.
最后, RDDs 比 DSM 多提供了兩個好處. 第一, 在對 RDDs 進行大量寫操作的過程中, 我們可以根據數據的本地性來調度 task 以提高性能. 第二, 如果在 scan-base 的操作中, 且這個時候內存不足以存儲這個 RDDs, 那么 RDDs 可以慢慢的從內存中清理掉. 在內存中存儲不下的分區(qū)數據會被寫到磁盤中, 且提供了和現有并行數據處理系統(tǒng)相同的性能保證.
3 RDD的表達
RDD的內容究竟該包括哪些內容才能達到輕松跟蹤RDD迭代狀態(tài)以及應對各種業(yè)務邏輯的目的呢桩撮?理論上講,RDD的transformation類型算子越多峰弹,則代表RDD能夠應對的場景就越多店量,而不同的transformation算子能夠由用于任意結合則會將極大提升其應用場景的范圍。
Spark中RDD的設計其客觀表達是基于DAG圖的形式鞠呈,圖中的每個節(jié)點表達相互獨立的每個RDD融师,而RDD中的編程實現主要包含的就是5種信息,或叫做5種接口蚁吝。以下五個信息可以表達 RDDs: 一個分區(qū)列表, 每一個分區(qū)就是數據集的原子塊. 一個父親 RDDs 的依賴列表. 一個計算父親的數據集的函數. 分區(qū)模式的元數據信息以及數據存儲信息. 比如, 基于一個 HDFS 文件創(chuàng)建出來的的 RDD 中文件的每一個數據塊就是一個分區(qū), 并且這個 RDD 知道每一個數據塊存儲在哪些機器上, 同時, 在這個 RDD 上進行 map 操作后的結果有相同的分區(qū)數, 當計算元素的時候, 將 map 函數應用到父親 RDD 數據中的.
那么旱爆,我們定義了每個RDD需要實現的接口后,需要考慮的就是如何定義不同RDD之間的依賴關系窘茁!當然怀伦,對于一個完整通用的系統(tǒng)而言,需要找到具有普適性的定義方式山林。RDD的圖表達中引入兩種依賴關系:1)寬依賴 房待。2)窄依賴。
寬依賴:表示父親 RDDs 的一個分區(qū)可以被子 RDDs 的多個子分區(qū)所依賴
窄依賴:表示父親 RDDs 的一個分區(qū)最多被子 RDDs 一個分區(qū)所依賴
舉例:map 操作是一個窄依賴, join 操作是一個寬依賴操作。
下圖是論文中的一個圖例吴攒,其中藍色實心矩形表示分區(qū)张抄,一個大的空心矩形代表一個RDD。
為何要分為這兩種依賴關系洼怔?
第一,:
窄依賴允許所有的父節(jié)點分區(qū)能夠在一臺節(jié)點中完成計算署惯。例如可以將每一個元素進行 map 操作后緊接著執(zhí)行filter 操作, 與此相反, 寬依賴需要父親 RDDs 的所有分區(qū)數據在不同的節(jié)點之間進行重新洗牌和網絡傳輸類似于MR。
第二:
窄依賴從一個失敗節(jié)點中恢復是非常高效的, 因為只需要重新計算相對應的父親的分區(qū)數據就可以, 而且這個重新計算是在不同的節(jié)點進行并行重計算的, 與此相反, 在一個含有寬依賴的血緣關系 RDDs 圖中, 一個節(jié)點的失敗可能導致一些分區(qū)數據的丟失, 但是只用重新計算父 RDD 的所有分區(qū)的數據镣隶。
4 Job調度
RDD的延遲性執(zhí)行使得其能夠實現交互式執(zhí)行极谊,舉個例子,你可以在shell窗口中寫一堆transformation的代碼安岂,但是此時代碼不會執(zhí)行轻猖,你還可以繼續(xù)寫下去,直到你滿意為止域那,而且中間你可以通過重寫相同變量名的不同方法來覆蓋更新一些變量(RDD)咙边,直到最后你使用了一個action算子后,整個代碼塊才會執(zhí)行次员。這就是交互式操作败许。
那么整個代碼塊被激活后JOB是如何調度的呢?
當一個用戶對某個 RDD 調用了 action 操作(比如 count 或者 save )的時候調度器會檢查這個 RDD 的血緣關系圖, 然后根據這個血緣關系圖構建一個含有 stages 的有向無環(huán)圖( DAG ), 最后按照步驟執(zhí)行這個 DAG 中的 stages , 如下圖所示淑蔚。每一個 stage 包含了盡可能多的帶有窄依賴的 transformations 操作. 這個 stage 的劃分是根據需要 shuffle 操作的寬依賴或者任何可以不依賴父節(jié)點的RDD市殷, 然后調度器可以調度啟動 tasks 來執(zhí)行父Stage未被執(zhí)行的Stage,一直計算到最終的RDD刹衫。
上圖中空心矩形表示 RDDs ,藍色的實心方形表示分區(qū), 黑色的是表示這個分區(qū)的數據存儲在內存中, 最后對 RDD-G 調用 action 操作,醋寝。根據寬依賴生成很多 stages , 且將窄依賴的 transformations 操作放在 stage 中。
調度器在分配 tasks 的時候是采用延遲調度來達到數據本地性的目的(說白了, 就是數據在哪里, 計算就在哪里). 如果某個分區(qū)的數據在某個節(jié)點上的內存中, 那么將這個分區(qū)的計算發(fā)送到這個機器節(jié)點中. 如果某個 RDD 為它的某個分區(qū)提供了這個數據存儲的位置節(jié)點, 則將這個分區(qū)的計算發(fā)送到這個節(jié)點上.
對于寬依賴(比如 shuffle 依賴), 中間數據會寫入到節(jié)點的磁盤中以利于從錯誤中恢復, 這個和 MapReduce 將 map 后的結果寫入到磁盤中是很相似的.
5 RDD的內存管理
既然RDD基于內存迭代带迟,那么內存資源需要一定的管理方式使其更高效地被利用音羞。
目前Spark支持三種RDD存儲介質:1)完全內存中的非序列化jvm對象。2)內存中的序列化數據仓犬。3)持久化在磁盤黄选。當然,第一種方式是最好的婶肩,因為計算速度最快办陷,但是大多時候內存容不下這么多RDD,則會使用第三種律歼。
內存中的RDD怎樣被回收來釋放資源呢民镜?Spark中采用LRU的回收方式,即:如果新的RDD無法被內存容納险毁,則內存中會啟動LRU策略來將最近很少使用的RDD進行清除制圈。
6 容錯的更高保證:checkpointing
如果迭代鏈條十分長们童,那么有必要適當進行checkpoint來緩存一些中間結果來保證計算鏈條的可靠性。
PageRank是一種需要重復很多次迭代的算法鲸鹦,且真實場景下該算法適配的數據集很大慧库,因此很有必要進行checkpoint。checkpoint對于一些有較高存儲保障的RDD來講并沒有用馋嗜,例如textfile齐板,大多都是從HDFS讀取的原始數據。