sparkPi源码解析
来源:互联网 发布:以下哪种立体匹配算法 编辑:程序博客网 时间:2024/05/21 21:47
在ubuntu的eclipse系统上,基于maven建立了第一个spark程序sparkPi,顺利执行正确结果。
现在对sparkPi源码进行解析,借此熟悉spark java API,为后面基于java的spark编程做准备。
sparkPi源码如下:
package sparkTest;/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.api.java.JavaSparkContext;import org.apache.spark.api.java.function.Function;import org.apache.spark.api.java.function.Function2;import java.util.ArrayList;import java.util.List;/** * Computes an approximation to pi * Usage: JavaSparkPi [slices] */public final class JavaSparkPi { public static void main(String[] args) throws Exception { SparkConf sparkConf = new SparkConf().setAppName("JavaSparkPi").setMaster("local"); JavaSparkContext jsc = new JavaSparkContext(sparkConf); int slices = (args.length == 1) ? Integer.parseInt(args[0]) : 2; int n = 100000 * slices; List<Integer> l = new ArrayList<Integer>(n); for (int i = 0; i < n; i++) { l.add(i); } JavaRDD<Integer> dataSet = jsc.parallelize(l, slices); int count = dataSet.map(new Function<Integer, Integer>() { @Override public Integer call(Integer integer) { double x = Math.random() * 2 - 1; double y = Math.random() * 2 - 1; return (x * x + y * y < 1) ? 1 : 0; } }).reduce(new Function2<Integer, Integer, Integer>() { @Override public Integer call(Integer integer, Integer integer2) { return integer + integer2; } }); System.out.println("Pi is roughly " + 4.0 * count / n); jsc.stop(); }}
源码解析:
1、SparkContext是
spark程序中非常核心的变量,所有spark程序的第一步都是创建+设置SparkContext。
sparkContext的作用是告诉spark如何访问集群cluster。
appName()设置程序名称,将会显示在cluster UI上。
master()是spark、Mesos、yarn集群的URL;或者是“local”字符串,表示在本地模式运行程序。
实际编程和运行程序时,并不会在编码中设置master(),因为这样灵活性不强。
常用的做法是,启动spark-submit -params,通过参数输入设置master()。
如果是本地测试程序,可以设置master为local。
2、parallelize()对输入数据进行并行化处理,处理后的数据就能进行RDD上的操作了,比如各种transformations、actions。
<span style="white-space:pre"></span>parallelize()
3、map操作是一种transformation,将map的函数参数在数据集上的每个element,操作一次,得到一个新的RDD。
<span style="white-space:pre"></span>map()
4、reduce操作是将RDD所有元素的聚合起来,通过reduce中的函数参数,从而得到一个最终结果。
<span style="white-space:pre"></span>reduce
5、map、reduce内的函数传递是spark程序中常见的方式。它的实现形式有两种。
new fuction():传统方式。
lamda表达式:更简洁。
6、函数Function是接口函数。T1为输入参数,R为返回值。同理Function2也一样,不同的是起实现函数call不同。
Interface Function<T1,R>; Function2<T1,T2,R>
<span style="white-space:pre"></span>new Function<Integer, Integer>()
<pre name="code" class="java"><span style="white-space:pre"></span>new Function2<Integer, Integer, Integer>()
7、spark除了map、reduce函数外,还支持许多数据操作,比如filter()、collect()、count()等等。
补充说明:
1、数据如何并行化处理?
<span style="white-space:pre"></span>List<Integer> data = Arrays.asList(1, 2, 3, 4, 5);<span style="white-space:pre"></span>JavaRDD<Integer> distData = sc.parallelize(data);通过上述操作,将普通集合data通过函数parallelize(),并行化处理后,就变成了分布式数据集distributed dataset(distData),这种类型就能被spark集群做并行处理了。
<span style="white-space:pre"></span>sc.parallelize(data, 10)我们也可以通过手动设置dataset的partitions个数,一个partition对应一个spark task。
如果没有设置partitions,则spark自动设置partitions个数。
2、spark支持的外部输入数据有哪些?
spark的输入数据可以来自hadoop的hdfs、local file system、Cassandra、HBase、Amazon S3、
textFile()函数用来将文件转化为RDD,转化结束后,新的RDD上就可以进行map、reduce、transformations、actions等操作。
textFile()函数中的参数path可以是directory、compress files、wildcards.
textFile()对文件的划分默认是64M一块(等同与HDFS系统),我们也可以根据参数修改划分标准。
val lines = textFile(“test.txt”)的解读。这句话并没有将test.txt加载到内存,也没有在文件上进行任何操作,只是使lines指向这个文件。
3、spark的RDD有两种创建方式:对以存在的数据集合进行并行化;对Hadoop HDFS、Hbase的数据进行转化。
4、spark支持两种操作:transformations、actions。
transformations:从已有数据集创建RDD数据集。比如:map就是一种transformation。
actions:对RDD上的dataset进行computation,return a value to the driver program.比如:reduce就是一种action。
transformations采取懒惰策略。即直到action需要result时,transformation才进行具体操作。之前都只是记住这些操作。
这种lazy策略,能够提高spark效率。避免transformation结果产生,只产生action结果。
对于如下操作:
<span style="white-space:pre"></span>JavaRDD<String> lines = sc.textFile("data.txt");<span style="white-space:pre"></span>JavaRDD<Integer> lineLengths = lines.map(s -> s.length());<span style="white-space:pre"></span>int totalLength = lineLengths.reduce((a, b) -> a + b);前面两步都没有直接执行,知道最后一部reduce,才触发真个spark程序执行。
reduce触发spark程序将task分解到集群中的每个机器上,每个机器执行其本地的map和reduce操作。向driver program返回其执行结果。
如果我们想在程序执行完毕后,查看lineLengths的值。可以使用如下方式,将其值persist().
lineLengths.persist(StorageLevel.MEMORY_ONLY());
5、RDD可以通过persist()和cache()让其贮存在内存中,加快下次访问RDD的速度。
RDD也支持将起贮存在disk,多节点之间的deplicated。
如何选取存储介质,需要根据具体情况。
如果不想等cache()满了以后自动触发清除操作,可以手动.unpersist()清除数据。
6、何为driver program,官方文档中反复提及。
可以理解为我们编写的spark源程序。
7、spark提供两种方式共享数据。
broadcast variables
accumulators
spark工作方式,简单参考图如下:
- sparkPi源码解析
- SparkPi源码解读
- 看example源码学spark系列(2)-SparkPi
- spark2.1源码分析2:从SparkPi分析一个job的执行
- Spark的Example---SparkPi
- SparkPi例子运行出错解决方法
- Spark实例演示之SparkPi
- 源码解析
- 源码解析
- sparkPi在yarn模式下运行
- IntelliJ IDEA单机运行SparkPi实例
- 运行示例sparkPi计算圆周率(1.1)
- Spark初体验(1)--SparkPi详解
- spark学习3之examples中的SparkPi
- 【JDk源码解析之一】ArrayList源码解析
- 【源码解析】-- ArrayList的源码解析
- EventBus源码解析(史上最全的源码解析)
- 【源码】Vector、Stack源码解析
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- 蓝桥杯:动态数组使用
- 后台开发面试题总结
- 安卓摇一摇
- JAVA 学到什么水平就可以转战 Android 了?
- sparkPi源码解析
- 去掉tabbar上方的黑线
- 设置导航栏的背景颜色
- 2016GDOI总结
- Appium Server 源码分析 (二) - main 方法
- zoj-3735 Josephina and RPG[概率dp]
- Prime Independence(质因子分解+二分图最大独立集)
- Gson学习
- 基于Servlet3.0 comet http长连接