概览
1、大体上说,每一个Spark应用都是一个驱动程序,包含两部分,一部分是运行用户的主函数,另一部分是在集群中执行多种并行任务。
2、Spark提供了(抽象出来了)RDD弹性分布式数据集,是一个在集群中跨节点的分区的元素集合,可以进行并行操作。
3、RDD的创建有两种方式,第一种是由hadoop文件系统中的文件创建,也就是hdfs文件,也可以是hadoop支持的其它文件系统。第二种是由驱动程序中存在的Scala集合创建。当RDD创建好之后,可以进行转换。
4、RDD也可以保存在内存中,这样在执行并行操作时更加高效。
5、当节点故障时,RDD拥有自动恢复功能。容错性好。
引入Spark
1、Spark2.4.5支持lambda表达式方便的编写函数,否则的话也可以使用org.apache.spark.api.java.function包下的类完成相应功能。
2、Spark2.2.0之后已经不支持java7。
3、想要引入Spark,需要在maven中增加依赖
groupId = org.apache.spark
artifactId = spark-core_2.12
version = 2.4.5
4、如果想要访问HDFS集群,需要添加hadoop-client依赖
groupId = org.apache.hadoop
artifactId = hadoop-client
version = <your-hdfs-version>
5、最后在程序中导入Spark的类,来使用它
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.SparkConf;
初始化Spark
Java编写Spark程序的第一步是创建一个JavaSparkContext对象,有了它Spark才知道如何访问集群。为了创建JavaSparkContext对象,需要先创建一个SparkConf对象,包含应用的信息。
SparkConf conf = new SparkConf().setAppName(appName).setMaster(master);
JavaSparkContext sc = new JavaSparkContext(conf);
appName是应用名,master是一个Spark,或Mesos,或YARN集群URL地址,也可以是字符串"local",表示运行本地模式。
使用Spark shell
1、使用spark shell时,一个SparkContext对象已经自动创建好了,变量名是sc。自己再创建SparkContext是没用的。
2、可以通过–master 参数配置sc连接哪一个master集群地址。
3、可以通过–jars 参数配置向classpath添加jar包。
4、可以通过–packages 参数配置maven依赖。
5、可以通过–repositories 参数配置额外的仓库。
本地模式4个核心
$ ./bin/spark-shell --master local[4]
向classpath中添加一个jar包
$ ./bin/spark-shell --master local[4] --jars code.jar
通过maven坐标添加一个依赖
$ ./bin/spark-shell --master local[4] --packages "org.example:example:0.1"
spark-shell --help 可以查看完整的选项列表。spark-shell相当于spark-submit script。
RDD弹性分布式数据集
Spark主要围绕着RDD的概念转,RDD是一个可以进行并行操作的容错的元素集合。
有两种创建RDD的方式:1、将驱动程序中一个已存的集合并行化处理。2、从外部存储系统引入一个数据集,如HDFS,HBase,等任何提供Hadoop InputFormat的数据源。
- 并行化集合处理
并行化集合是通过在驱动程序中的已有集合上执行JavaSparkContext的parallelize()方法得到的。
集合中的数据通过拷贝形成一个可以进行并行操作的分布式数据集。
比如,创建一个并行集合,包含1-5共5个数字。
List<Integer> data = Arrays.asList(1, 2, 3, 4, 5);
JavaRDD<Integer> distData = sc.parallelize(data);
一旦创建,分布式数据集就可以进行平行操作。比如,调用distData.reduce((a, b) -> a + b) 将集合中元素求和。
平行集合的一个重要参数是数据集切分的分区数量,spark将会为集群中的每一个分区运行一个任务。典型情况是你想为集群中的每一个CPU分配2-4个分区,一般情况spark会根据集群自动设置分区数。你也可以在平行化处理时传入第二个参数手动设置,如sc.parallelize(data, 10)。
- 引入外部数据集
Spark支持从外部数据源创建RDD,包括任意hadoop支持的数据源,如hdfs,hbase等。支持的文件格式有文本文件,序列化文件,及其它Hadoop支持的InputFormat。
使用SparkContext的textFile()方法可以将文本文件创建成RDD,需要传入文件的URI地址,如hdfs:// , s3a:// 等,此方法将读取每一行,组成一个集合。
如:
JavaRDD<String> distFile = sc.textFile("data.txt");
一旦创建,distFile就可执行数据集操作,比如使用map和reduce进行求和操作。
distFile.map(s -> s.length()).reduce((a, b)