學(xué)習(xí)和使用一段時(shí)間的spark虹统, 對(duì)spark的總結(jié)一下弓坞,希望對(duì)大家有用,不介紹怎么使用车荔, 只從設(shè)計(jì)上談?wù)劇?/p>
spark解決了什么問題渡冻?
說spark前一定要說一下, 就不得不提Google的三駕馬車:Google FS忧便、MapReduce族吻、BigTable。其中對(duì)應(yīng)開源實(shí)現(xiàn)如下:
Google FS -> hdfs珠增、
MapReduce -> hadoop mapreduce
BigTable -> hbase
spark就是處理 mapreduce慢的問題超歌。
在spark沒出現(xiàn)前, hadoop是 v1 版本 有兩個(gè)問題蒂教,
- 一個(gè)就是 hadoop的namenode單點(diǎn)以及內(nèi)存問題(數(shù)據(jù)的node是放在內(nèi)存中)巍举, v2也都解決了。
- hadoop的機(jī)器資源管理和計(jì)算管理都是 mapreduce進(jìn)程管理凝垛,就是執(zhí)行任務(wù)和資源都是mapduce一個(gè)在管理懊悯, v2獨(dú)立出 yarn才解決這個(gè)問題的
- mapreduce慢的問題, 還是不能解決梦皮。 一開始定位就是在廉價(jià)的機(jī)器上運(yùn)行定枷。 定位不同。
說下mapreduce核心
:
-
移動(dòng)數(shù)據(jù)不如移動(dòng)計(jì)算
届氢。 比如數(shù)據(jù)在一個(gè)節(jié)點(diǎn)上欠窒, 那就把計(jì)算放在這個(gè)節(jié)點(diǎn)上, 這樣就沒有網(wǎng)絡(luò)磁盤IO了退子, 當(dāng)然需要考慮機(jī)器的負(fù)載繁忙等岖妄。 -
合久必分,分久必合
寂祥。 數(shù)據(jù)量很大鸥诽, 處理不了,就拆分渴语,分發(fā)到多臺(tái)機(jī)器上茵瀑,開始運(yùn)算,運(yùn)算結(jié)果再進(jìn)行合并惜犀,最后輸出铛碑。
這就是 map(分) reduce(合) 中間還有shuffle(洗牌)。 map和reduce都是并行的虽界。
hadoop mapreduce是基于 文件
的汽烦,相當(dāng)于以數(shù)據(jù)為中心。 大量的磁盤網(wǎng)絡(luò)IO莉御。 一個(gè)mapreduce只能計(jì)算一個(gè)結(jié)果撇吞,不能迭代計(jì)算俗冻。 必須是前一個(gè)mapreduce的輸出文件作為下一個(gè)輸出。
spark就是解決mapreduce的慢的牍颈, spark是內(nèi)存計(jì)算迄薄, 將數(shù)據(jù)加載到內(nèi)存中計(jì)算, 所有速度快煮岁。 spark也有map reduce概念噪奄。
進(jìn)行迭代計(jì)算。 數(shù)據(jù)在內(nèi)存中人乓, 上一步的計(jì)算結(jié)果勤篮,可以在下一步進(jìn)行使用。
另外一個(gè)原因:
spark開發(fā)更容易色罚,hadoop的mapreduce很麻煩碰缔,每次都要有 map,reuduce, driver三個(gè)類。
spark介紹
Apache Spark 是專為大規(guī)模數(shù)據(jù)處理而設(shè)計(jì)的快速通用的計(jì)算引擎戳护,是一種開源的類Hadoop MapReduce的通用并行框架金抡,擁有Hadoop MapReduce所具有的優(yōu)點(diǎn)。
Spark不同于MapReduce的是腌且,Spark的Job中間輸出結(jié)果可以保存在內(nèi)存中梗肝,從而不再需要讀寫HDFS,因此Spark能更好地適用于數(shù)據(jù)挖掘與機(jī)器學(xué)習(xí)等需要迭代的MapReduce的算法铺董。
Spark 主要有三個(gè)特點(diǎn)
首先巫击,高級(jí) API 剝離了對(duì)集群本身的關(guān)注,Spark 應(yīng)用開發(fā)者可以專注于應(yīng)用所要做的計(jì)算本身精续。
其次坝锰,Spark 很快,支持交互式計(jì)算和復(fù)雜算法重付。
最后顷级,Spark 是一個(gè)通用引擎,可用它來完成各種各樣的運(yùn)算确垫,包括 SQL 查詢弓颈、文本處理、機(jī)器學(xué)習(xí)等删掀,而在 Spark 出現(xiàn)之前翔冀,我們一般需要學(xué)習(xí)各種各樣的引擎來分別處理這些需求。
總結(jié)一下:從各種方向上(比如開發(fā)速度和運(yùn)行速度等)來看爬迟,Spark都優(yōu)于Hadoop MapReduce橘蜜;同時(shí)菊匿,Spark還提供大數(shù)據(jù)生態(tài)的一站式解決方案
spark架構(gòu)
spark core是基礎(chǔ)付呕,上面都是轉(zhuǎn)成 core來執(zhí)行的计福。
spark是分布式,分成master和 work.
部署方式有很多種徽职, 不同方式象颖,對(duì)節(jié)點(diǎn)稱呼不同
- spark的自身集群管理 master worker, 發(fā)布的是driver
- YARN 集群配合 hdfs使用的, 這個(gè)使用最多姆钉, spark沒有存儲(chǔ)说订。 所有用yarn和hdfs最密切。
- mesos
- k8s
spark核心
spark core的數(shù)據(jù)類型計(jì)算三種 RDD潮瓶,Broadcast Variables陶冷,Accumulators
RDD:彈性分布式數(shù)據(jù)集
Broadcast Variables: 廣播變量 將變量廣播到所有執(zhí)行的節(jié)點(diǎn) 只讀
Accumulators: 累加器, 執(zhí)行節(jié)點(diǎn)可以將累加結(jié)果回傳到 driver, 執(zhí)行節(jié)點(diǎn)毯辅,只寫埂伦。
核心是 RDD,包括SQL的數(shù)據(jù)類型 DataFrame和DataSet以及 stream的 DStream也是對(duì)RDD包裝的。
RDD特點(diǎn)
1)一組分區(qū)(Partition)思恐,即數(shù)據(jù)集的基本組成單位;
2)一個(gè)計(jì)算每個(gè)分區(qū)的函數(shù);
3)RDD之間的依賴關(guān)系;
4)一個(gè)Partitioner沾谜,即RDD的分片函數(shù);
5)一個(gè)列表,存儲(chǔ)存取每個(gè)Partition的優(yōu)先位置(preferred location)胀莹。
spark的功能都是在上面RDD數(shù)據(jù)結(jié)構(gòu)特點(diǎn)上擴(kuò)展完成的基跑。
1. 分區(qū)
spark是分布式的, 分區(qū)就天然支持了描焰, 可以提高并行度媳否。 比如統(tǒng)計(jì)一個(gè)文件的word數(shù)量, 那不同分區(qū)荆秦,不同task進(jìn)行處理逆日,
最后將各個(gè)分區(qū)的結(jié)果合并就可以了。 分區(qū)可以改變萄凤。
2. 數(shù)據(jù)是只讀
RDD加的數(shù)據(jù)都是只讀的室抽。 只讀保證了任務(wù)失敗重跑冪等性。 每一步執(zhí)行都是產(chǎn)生新的RDD靡努,不會(huì)修改原RDD坪圾。
3. 函數(shù)
函數(shù)就是操作,這就是spark中的算子,RDD的操作算子包括兩類惑朦,一類叫做transformations兽泄,它是用來將RDD進(jìn)行轉(zhuǎn)化,構(gòu)建RDD的血緣關(guān)系漾月;另一類叫做actions病梢,它是用來觸發(fā)RDD的計(jì)算,得到RDD的相關(guān)計(jì)算結(jié)果或者將RDD保存的文件系統(tǒng)中。
就是所說的 惰性計(jì)算蜓陌,沒有觸發(fā)計(jì)算觅彰,都是記錄計(jì)算步驟,觸發(fā)了步驟钮热,才開始執(zhí)行填抬。
4. 依賴
RDDs通過操作算子進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換得到的新RDD包含了從其他RDDs衍生所必需的信息隧期,RDDs之間維護(hù)著這種血緣關(guān)系飒责,也稱之為依賴。
這是spark數(shù)據(jù)失敗重跑的依據(jù)仆潮。 DAG: 有向無環(huán)圖宏蛉。 spark的迭代計(jì)算。 函數(shù)式編程鏈?zhǔn)叫灾茫赗DD中會(huì)保存一個(gè)依賴檐晕, 在上一個(gè)執(zhí)行完。 每一步就一個(gè)點(diǎn)蚌讼, 這樣構(gòu)成一個(gè)圖辟灰。
5. 緩存
如果在應(yīng)用程序中多次使用同一個(gè)RDD,可以將該RDD緩存起來篡石,該RDD只有在第一次計(jì)算的時(shí)候會(huì)根據(jù)血緣關(guān)系得到分區(qū)的數(shù)據(jù)芥喇,在后續(xù)其他地方用到該RDD的時(shí)候,會(huì)直接從緩存處取而不用再根據(jù)血緣關(guān)系計(jì)算凰萨,這樣就加速后期的重用继控。
6. checkpoint
雖然RDD的血緣關(guān)系天然地可以實(shí)現(xiàn)容錯(cuò),當(dāng)RDD的某個(gè)分區(qū)數(shù)據(jù)失敗或丟失胖眷,可以通過血緣關(guān)系重建武通。但是對(duì)于長(zhǎng)時(shí)間迭代型應(yīng)用來說,隨著迭代的進(jìn)行珊搀,RDDs之間的血緣關(guān)系會(huì)越來越長(zhǎng)冶忱,一旦在后續(xù)迭代過程中出錯(cuò),則需要通過非常長(zhǎng)的血緣關(guān)系去重建境析,勢(shì)必影響性能囚枪。為此,RDD支持checkpoint將數(shù)據(jù)保存到持久化的存儲(chǔ)中劳淆,這樣就可以切斷之前的血緣關(guān)系链沼,因?yàn)閏heckpoint后的RDD不需要知道它的父RDDs了,它可以從checkpoint處拿到數(shù)據(jù)沛鸵。就是將數(shù)據(jù)持久化括勺, 切斷DAG圖。
編程模型
給個(gè)示例:
package org.jackson.exp
import org.apache.spark.{SparkConf, SparkContext}
object Wd {
def main(args: Array[String]): Unit = {
// 設(shè)置 conf
val conf = new SparkConf().setMaster("local[*]").setAppName("WC")
// 創(chuàng)建SparkContext,該對(duì)象是提交spark App的入口
val sc = new SparkContext(conf)
sc.textFile("/Users/zego/IdeaProjects/sparkOne/input").
flatMap(_.split(" ")). // 將一行進(jìn)行按 " "拆分
map((_, 1)). // 轉(zhuǎn)換數(shù)據(jù)類型 tuple
reduceByKey(_ + _). // 基于key進(jìn)行 value 相加
coalesce(1). // 修改分區(qū)數(shù)
saveAsTextFile("/Users/zego/IdeaProjects/sparkOne/output")
sc.stop()
}
}
不同分區(qū)疾捍,不同task