MapReduce编程模型的局限性
Spark是类Hadoop MapReduce的通用并行框架
诞生于加州大学伯克利分校AMP实验室,是一个基于内存的分布式计算框架
Spark SQL:高性能的基于Hadoop的SQL解决方案
Spark Streaming:可以实现高吞吐量、具备容错机制的准实时流处理系统
Spark GraphX:分布式图处理框架
Spark MLlib:构建在Spark上的分布式机器学习库
$SPARK_HOME/conf/spark-env.sh,$SPARK_HOME/conf/slaves
$SPARK_HOME/sbin/start-all.sh
spark-shell --master local[*]
spark-shell --master spark://MASTERHOST:7077
spark-shell --master yarn-client
scala>sc.textFile("hdfs://cluster1/data/hello.txt")
.flatMap(x=>x.split("\t"))
.map(x=>(x,1)).reduceByKey(_+_).collect
术语 | 说 明 |
---|---|
Application | 建立在Spark上的用户程序,包括Driver代码和运行在集群各节点Executor中的代码 |
Driver program | 驱动程序。Application中的main函数并创建SparkContext |
Cluster Manager | 在集群(Standalone、Mesos、YARN)上获取资源的外部服务 |
Worker Node | 集群中任何可以运行Application代码的节点 |
Executor | 某个Application运行在worker节点上的一个进程 |
Task | 被送到某个Executor上的工作单元 |
Job | 包含多个Task组成的并行计算,往往由Spark Action触发生成,一个Application中往往会产生多个Job |
Stage | 每个Job会被拆分成多组Task,作为一个TaskSet,其名称为Stage |
IDEA创建sparkapi依赖
<properties>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<encoding>UTF-8encoding>
<scala.version>2.11.8scala.version>
<spark.version>2.2.0spark.version>
<hadoop.version>2.7.1hadoop.version>
<scala.compat.version>2.11scala.compat.version>
properties>
<dependencies>
<dependency>
<groupId>org.scala-langgroupId>
<artifactId>scala-libraryartifactId>
<version>${scala.version}version>
dependency>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-core_2.11artifactId>
<version>${spark.version}version>
dependency>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-sql_2.11artifactId>
<version>${spark.version}version>
dependency>
<dependency>
<groupId>org.apache.hadoopgroupId>
<artifactId>hadoop-clientartifactId>
<version>${hadoop.version}version>
dependency>
dependencies>
import org.apache.spark.{SparkConf, SparkContext}
val conf=new SparkConf().setMaster("local[2]").setAppName("HelloSpark")
val sc=SparkContext.getOrCreate(conf)
import org.apache.spark.sql.SparkSession
val spark = SparkSession.builder
.master("local[2]")
.appName("appName")
.getOrCreate()
简单的解释
复杂的解释
RDD是弹性分布式数据集(Resilient Distributed Datasets)
分布式( Distributed)
数据的计算并非只局限于单个节点,而是多个节点之间协同计算得到
数据集( Datasets)
RDD是只读的、分区记录的集合,每个分区分布在集群的不同节点上
RDD并不存储真正的数据,只是对数据和操作的描述
弹性(Resilient)
自动进行存储方式的切换
,RDD优先存储内存中,内存不足将自动写入磁盘
基于Linage的高效容错机制
,在任何时候都能进行重算,根据数据血统,可以自动从节点失败中恢复分区,各个分片之间的数据互不影响
Stage失败自动重试 / Task失败自动重试
Checkpoint和Persist
, checkpoint持久化到文件系统
分区(分片)
信息,每个任务处理一个分区compute函数
,计算该分区中的数据依赖
分区器
决定数据(key-value)分配至哪个分区优先位置列表
,将计算任务分派到其所在处理数据块的存储位置/*使用集合创建RDD
* 1、Spark默认会根据集群的情况来设置分区的数量,也可以通过parallelize()第二参数来指定
* 2、Spark会为每一个分区运行一个任务进行处理
*/
val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd.count
rdd.partitions.size
val rdd=sc.parallelize(List(1,2,3,4,5,6),5)
rdd.partitions.size
val rdd=sc.makeRDD(List(1,2,3,4,5,6))
//通过加载文件产生RDD
val distFile=sc.textFile("file:///home/hadoop/data/hello.txt")
distFile.count
val distHDFSFile=sc.textFile("hdfs://hadoop000:8020/hello.txt")
//加载“file://……”时,以local运行仅需一份本地文件,以Spark集群方式运行,应保证每个节点均有该文件的本地副本
//支持目录、压缩文件以及通配符
sc.textFile("/my/directory")
sc.textFile("/my/directory/*.txt")
sc.textFile("/my/directory/*.gz")
/*
1、Spark默认访问HDFS
2、Spark默认为HDFS文件的每一个数据块创建一个分区,也可以通过textFile()第二个参数指定,但只能比数据块数量多
*/
/*其他创建RDD的方法
SparkContext.wholeTextFiles():可以针对一个目录中的大量小文件返回作为PairRDD
普通RDD:org.apache.spark.rdd.RDD[data_type]
PairRDD:org.apache.spark.rdd.RDD[(key_type,value_type)]
Spark 为包含键值对类型的 RDD 提供了一些专有的操作,比如:reduceByKey()、groupByKey()……
也可以通过键值对集合创建PairRDD:
sc.parallelize(List((1,2),(1,3)))
SparkContext.sequenceFile[K,V]() -->Hadoop SequenceFile的读写支持
SparkContext.hadoopRDD()、newAPIHadoopRDD() -->从Hadoop接口API创建
SparkContext.objectFile() -->RDD.saveAsObjectFile()的逆操作
*/
分区是RDD被拆分并发送到节点的不同块之一
对于转换操作,RDD的所有转换都不会直接计算结果
//将原RDD中每个元素都乘以2来产生一个新的RDD
val a=sc.parallelize(1 to 9)
val b=a.map(x=>x*2)
a.collect
b.collect
//map把普通RDD变成PairRDD
val a=sc.parallelize(List("dog","tiger","lion","cat","panther"))
val b=a.map(x=>(x,1))
b.collect
RDD常用的转换算子-filter算子
val a=sc.parallelize(1 to 10)
a.filter(_%2==0).collect
a.filter(_<4).collect
//map&filter
val rdd=sc.parallelize(List(1 to 6))
val mapRdd=rdd.map(_*2)
mapRdd.collect
val filterRdd=mapRdd.filter(_>5)
filterRdd.collect
RDD常用的转换算子-mapValues算子
val a=sc.parallelize(List("dog","tiger","lion","cat","panther","eagle"))
val b=a.map(x=>(x.length,x))
b.mapValues("x"+_+"x").collect
//输出结果:
//Array((3,xdogx), (5,xtigerx), (4,xlionx), (3,xcatx), (7,xpantherx), (5,xeaglex))
更多常用转换算子
val dis = sc.parallelize(List(1,2,3,4,5,6,7,8,9,9,2,6))
dis.distinct.collect
dis.distinct(2).partitions.length
val a = sc.parallelize(List("dog", "salmon", "pig"), 3)
val f = a.map(x=>(x.length,x))
f.reduceByKey((a,b)=>(a+b)).collect
f.reduceByKey(_+_).collect
f.groupByKey.collect
val a = sc.parallelize(List("dog", "salmon", "pig"), 3)
val f = a.map(x=>(x.length,x))
f.sortByKey().collect
f.sortByKey(false).collect
val u1 = sc.parallelize(1 to 3)
val u2 = sc.parallelize(3 to 4)
u1.union(u2).collect
(u1 ++ u2).collect
u1.intersection(u2).collect
val j1 = sc.parallelize(List("abe", "abby", "apple"))
.map(a => (a, 1))
val j2 = sc.parallelize(List("apple", "beatty", "beatrice")).map(a => (a, 1))
j1.join(j2).collect
j1.leftOuterJoin(j2).collect
j1.rightOuterJoin(j2).collect
RDD常用动作算子
count
val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd.count
collect
val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd.collect
take: 返回前n个元素
val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd.take(3)
first:返回RDD第一个元素
val rdd=sc.parallelize(List(1,2,3,4,5,6))
rdd.first
reduce:根据指定函数,对RDD中的元素进行两两计算,返回计算结果
val a=sc.parallelize(1 to 100)
a.reduce((x,y)=>x+y)
a.reduce(_+_) //与上面等价
val b=sc.parallelize(Array(("A",0), ("A",2), ("B",1), ("B",2), ("C",1)))
b.reduce((x,y)=>{(x._1+y._1,x._2+y._2)}) //(AABBC,6)
foreach:对RDD中的每个元素都使用指定函数,无返回值
val rdd=sc.parallelize(1 to 100)
rdd.foreach(println)
lookup:用于PairRDD,返回K对应的所有V值
val rdd=sc.parallelize(List(('a',1), ('a',2), ('b',3), ('c',4)))
rdd.lookup('a') //输出WrappedArray(1, 2)
最值:返回最大值、最小值
val y=sc.parallelize(10 to 30)
y.max //求最大值
y.min //求最小值
saveAsTextFile:保存RDD数据至文件系统
val rdd=sc.parallelize(1 to 10,2)
rdd.saveAsTextFile("hdfs://hadoop000:8020/data/rddsave/")