理解Spark的核心RDD
http://www.infoq.com/cn/articles/spark-core-rdd/
//摘要
【RDD將操作分為兩類:transformation與action。無論執(zhí)行了多少次transformation操作,RDD都不會真正執(zhí)行運算,只有當action操作被執(zhí)行時,運算才會觸發(fā)】。而在RDD的內(nèi)部實現(xiàn)機制中,【底層接口則是基于迭代器的,從而使得數(shù)據(jù)訪問變得更高效,也避免了大量中間結(jié)果對內(nèi)存的消耗】。
總結(jié)
RDD是Spark的核心,也是整個Spark的架構(gòu)基礎(chǔ)。它的特性可以總結(jié)如下:
它是不變的數(shù)據(jù)結(jié)構(gòu)存儲
它是支持跨集群的分布式數(shù)據(jù)結(jié)構(gòu)
可以根據(jù)數(shù)據(jù)記錄的key對結(jié)構(gòu)進行分區(qū)
提供了粗粒度的操作,且這些操作都支持分區(qū)
它將數(shù)據(jù)存儲在內(nèi)存中,從而提供了低延遲性
//

與許多專有的大數(shù)據(jù)處理平臺不同,Spark建立在【統(tǒng)一抽象的RDD之上,使得它可以以基本一致的方式應對不同的大數(shù)據(jù)處理場景,包括MapReduce,Streaming,SQL,Machine Learning以及Graph等】。這即Matei Zaharia所謂的“設(shè)計一個【通用的編程抽象(Unified Programming Abstraction)】。這正是Spark這朵小火花讓人著迷的地方。
要理解Spark,就需得理解RDD。
RDD是什么?
RDD,全稱為Resilient Distributed Datasets,是一個容錯的、并行的數(shù)據(jù)結(jié)構(gòu),可以讓用戶顯式地將數(shù)據(jù)存儲到磁盤和內(nèi)存中,并能控制【數(shù)據(jù)的分區(qū)】。同時,RDD還提供了一組豐富的操作來【操作這些數(shù)據(jù)】。在這些操作中,諸如【map、flatMap、filter等轉(zhuǎn)換操作】實現(xiàn)了monad模式,很好地契合了Scala的【集合操作】。除此之外,RDD還提供了諸如join、groupBy、reduceByKey等更為方便的操作(注意,reduceByKey是action,而非transformation),以支持常見的數(shù)據(jù)運算。
通常來講,針對數(shù)據(jù)處理有幾種常見模型,包括:Iterative Algorithms,Relational Queries,MapReduce,Stream Processing。例如Hadoop MapReduce采用了MapReduces模型,Storm則采用了Stream Processing模型?!綬DD混合了這四種模型,使得Spark可以應用于各種大數(shù)據(jù)處理場景】。
【RDD作為數(shù)據(jù)結(jié)構(gòu),本質(zhì)上是一個只讀的分區(qū)記錄集合】。一個RDD可以包含多個分區(qū),每個分區(qū)就是一個dataset片段。RDD可以相互依賴。如果RDD的每個分區(qū)最多只能被一個Child RDD的一個分區(qū)使用,則稱之為narrow dependency;若多個Child RDD分區(qū)都可以依賴,則稱之為wide dependency。不同的操作依據(jù)其特性,可能會產(chǎn)生不同的依賴。例如map操作會產(chǎn)生narrow dependency,而join操作則產(chǎn)生wide dependency。
Spark之所以將依賴分為narrow與wide,基于兩點原因。
首先,【narrow dependencies可以支持在同一個cluster node上以管道形式執(zhí)行多條命令,例如在執(zhí)行了map后,緊接著執(zhí)行filter】。相反,【wide dependencies需要所有的父分區(qū)都是可用的,可能還需要調(diào)用類似MapReduce之類的操作進行跨節(jié)點傳遞】。
其次,則是從失敗恢復的角度考慮。narrow dependencies的失敗恢復更有效,因為它只需要重新計算丟失的parent partition即可,而且可以并行地在不同節(jié)點進行重計算。而wide dependencies牽涉到RDD各級的多個Parent Partitions。下圖說明了narrow dependencies與wide dependencies之間的區(qū)別:
【RDD將操作分為兩類:transformation與action。無論執(zhí)行了多少次transformation操作,RDD都不會真正執(zhí)行運算,只有當action操作被執(zhí)行時,運算才會觸發(fā)】。而在RDD的內(nèi)部實現(xiàn)機制中,【底層接口則是基于迭代器的,從而使得數(shù)據(jù)訪問變得更高效,也避免了大量中間結(jié)果對內(nèi)存的消耗】。
Spark快速入門指南 - 夢里花落的博客 - 博客頻道 - CSDN.NET
http://blog.csdn.net/qq_19244267/article/details/46456873
【RDDs提供actions操作,通過它可以返回值;同時還提供 transformations操作,通過它可以返回一個新的RDD的引用】。如下:
1 scala> textFile.count() // Number of items in this RDD
2 res1: Long = 108
我們再試試transformations操作,下面的例子中我們通過使用filter transformation來一個新的RDD:
1 scala> val linesWithSpark = textFile.filter(line => line.contains("Spark"))
2 linesWithSpark: org.apache.spark.rdd.RDD[String] = FilteredRDD[4] at
3 filter at <console>:14
我們將transformations操作和actions操作連起來操作:
1 scala> textFile.filter(line => line.contains("Spark")).count()
2 res3: Long = 15
更多關(guān)于RDD上面的操作
RDD的transformations操作和actions操作可以用于更復雜的計算。下面的例子是找出README.md文件中單詞數(shù)最多的行有多少個單詞
1 scala> var size = textFile.map(line=>line.split(" ").size)
2 scala> size.reduce((a, b)=>if (a > b) a else b)
3 res4: Long = 15
map函數(shù)負責將line按照空格分割,并得到這行單詞的數(shù)量,而reduce函數(shù)將獲取文件中單詞數(shù)最多的行有多少個單詞。map和reduce函數(shù)的參數(shù)是Scala的函數(shù)式編程風格。我們可以直接用Java里面的Math.max()函數(shù),這樣會使得這段代碼更好理解