Spark shell是一个特别适合快速开发Spark程序的工具。即使你对Scala不熟悉,仍然可以使用这个工具快速应用Scala操作Spark。
Spark shell使得用户可以和Spark集群交互,提交查询,这便于调试,也便于初学者使用Spark。
Spark shell是非常方便的,因为它很大程度上基于Scala REPL(Scala交互式shell,即Scala解释器),并继承了Scala REPL(读取-求值-打印-循环)(Read-Evaluate-Print-Loop)的所有功能。运行spark-shell,则会运行spark-submit,spark-shell其实是对spark-submit的一层封装。
下面是Spark shell的运行原理图:
RDD有两种类型的操作 ,分别是Transformation(返回一个新的RDD)和Action(返回values)。
1.Transformation:根据已有RDD创建新的RDD数据集build
2.Action:在RDD数据集运行计算后,返回一个值或者将结果写入外部存储
WordCount统计:某电商网站记录了大量的用户对商品的收藏数据,并将数据存储在名为buyer_favorite的文本文件中。文本数据格式如下:
用户id(buyer_id),商品id(goods_id),收藏日期(dt)
现要求统计用户收藏数据中,每个用户收藏商品数量。
1.在Linux上,创建/data/spark3/wordcount目录,用于存储实验所需的数据。
切换目录到/data/spark3/wordcount下,并从http://59.64.78.41:60000/allfiles/spark3/wordcount/buyer_favorite下载实验数据。
2.使用jps查看Hadoop以及Spark的相关进程是否已经启动,若未启动则执行启动命令。
将Linux本地/data/spark3/wordcount/buyer_favorite文件,上传到HDFS上的/myspark3/wordcount目录下。若HDFS上/myspark3目录不存在则需提前创建。
3.启动spark-shell
4.编写Scala语句,统计用户收藏数据中,每个用户收藏商品数量。
先在spark-shell中,加载数据。
执行统计并输出。
去重:使用spark-shell,对上述实验中,用户收藏数据文件进行统计。根据商品ID进行去重,统计用户收藏数据中都有哪些商品被收藏。
1.在Linux上,创建/data/spark3/distinct,用于存储实验数据。
切换到/data/spark3/distinct目录下,并从http://59.64.78.41:60000/allfiles/spark3/distinct/buyer_favorite下载实验数据。
2.使用jps查看Hadoop,Spark的进程。保证Hadoop、Spark框架相关进程为已启动状态。
3.将/data/spark3/distinct/buyer_favorite文件,上传到HDFS上的/myspark3/distinct目录下。若HDFS目录不存在则创建。
4.在Spark窗口,编写Scala语句,统计用户收藏数据中,都有哪些商品被收藏。
先加载数据,创建RDD。
对RDD进行统计并将结果打印输出。
排序:电商网站都会对商品的访问情况进行统计,现有一个goods_visit文件,存储了电商网站中的各种商品以及此各个商品的点击次数。
商品id(goods_id) 点击次数(click_num)
现根据商品的点击次数进行排序,并输出所有商品。
输出结果样式:
1.在Linux上,创建/data/spark3/sort,用于存储实验数据。
切换到/data/spark3/sort目录下,并从http://59.64.78.41:60000/allfiles/spark3/sort/goods_visit下载实验数据。
2.将/data/spark3/sort/goods_visit文件,上传到HDFS上的/spark3/sort/目录下。若HDFS目录不存在则需提前创建。
3.在Spark窗口,加载数据,将数据转变为RDD。
对RDD进行统计并将结果打印输出。
4.输出结果样式为:
Join:现有某电商在2011年12月15日的部分交易数据。数据有订单表orders和订单明细表order_items,表结构及数据分别为:
orders表:(订单id order_id, 订单号 order_number, 买家ID buyer_id, 下单日期 create_dt)
order_items表:(明细ID item_id, 订单ID order_id, 商品ID goods_id )
orders表和order_items表,通过订单id进行关联,是一对多的关系。
下面开启spark-shell,查询在当天该电商网站,都有哪些用户购买了什么商品。
1.在Linux上,创建/data/spark3/join,用于存储实验数据。
切换目录到/data/spark3/join目录下,并从http://59.64.78.41:60000/allfiles/spark3/join/order_items及http://59.64.78.41:60000/allfiles/spark3/join/orders下载实验数据。
2.在HDFS上创建/myspark3/join目录,并将Linux上/data/spark3/join目录下的数据,上传到HDFS。
3.在Spark窗口创建两个RDD,分别加载orders文件以及order_items文件中的数据。
4.我们的目的是查询每个用户购买了什么商品。所以对rdd1和rdd2进行map映射,得出关键的两个列的数据。
5.将rdd11以及rdd22中的数据,根据Key值,进行Join关联,得到最终结果。
6.最后将结果输出,查看输出效果。
最终的执行结果为:
7.将输出数据进行格式化:
可以看到上面数据关联后一共有3列,分别为订单ID,用户ID,商品ID。
求平均值:电商网站都会对商品的访问情况进行统计。现有一个goods_visit文件,存储了全部商品及各商品的点击次数。还有一个文件goods,记录了商品的基本信息。两张表的数据结构如下:
goods表:商品ID(goods_id),商品状态(goods_status),商品分类id(cat_id),评分(goods_score)
goods_visit表:商品ID(goods_id),商品点击次数(click_num)
商品表(goods)及商品访问情况表(goods_visit)可以根据商品id进行关联。现在统计每个分类下,商品的平均点击次数是多少?
1.在Linux上,创建目录/data/spark3/avg,用于存储实验数据。
切换到/data/spark3/avg目录下,并从http://59.64.78.41:60000/allfiles/spark3/avg/goods以及http://59.64.78.41:60000/allfiles/spark3/avg/goods_visit两个网址下载实验数据。
2.在HDFS上创建目录/myspark3/avg,并将Linux/data/spark3/avg目录下的数据,上传到HDFS的/myspark3/avg。
3.在Spark窗口创建两个RDD,分别加载goods文件以及goods_visit文件中的数据。
4.我们的目的是统计每个分类下,商品的平均点击次数,我们可以分三步来做。
首先,对rdd1和rdd2进行map映射,得出关键的两个列的数据。
用collect()方法启动程序。
查看rdd11的结果如下:
rdd11.collect
res2: Array[(String, String)] = Array((1000002,52137), (1000003,52137), (1000004,52137), (1000006,52137),
(1000007,52137), (1000008,52137), (1000010,52137), (1000011,52137), (1000015,52137), (1000018,52137),
(1000020,52137), (1000021,52137), (1000025,52137), (1000028,52137), (1000030,52137), (1000033,52137),
(1000035,52137), (1000037,52137), (1000041,52137), (1000044,52137), (1000048,52137), (1000050,52137),
(1000053,52137), (1000057,52137), (1000059,52137), (1000063,52137), (1000065,52137), (1000067,52137),
(1000071,52137), (1000073,52137), (1000076,52137), (1000078,52137), (1000080,52137), (1000082,52137),
(1000084,52137), (1000086,52137), (1000087,52137), (1000088,52137), (1000090,52137), (1000091,52137),
(1000094,52137), (1000098,52137), (1000101,52137), (1000103,52137), (1000106,52...
scala>>
用collect()方法启动程序。
rdd22.collect
查看rdd22的结果如下:
rdd22.collect
res3: Array[(String, String)] = Array((1010000,4), (1010001,0), (1010002,0), (1010003,0), (1010004,0),
(1010005,0), (1010006,74), (1010007,0), (1010008,0), (1010009,1081), (1010010,0), (1010011,0), (1010012,0),
(1010013,44), (1010014,1), (1010018,0), (1010019,542), (1010020,1395), (1010021,18), (1010022,13), (1010023,27),
(1010024,22), (1010025,295), (1010026,13), (1010027,1), (1010028,410), (1010029,2), (1010030,8), (1010031,6),
(1010032,729), (1010033,72), (1010034,3), (1010035,328), (1010036,153), (1010037,100), (1010038,4), (1010039,3),
(1010040,69), (1010041,1), (1010042,1), (1010043,21), (1010044,268), (1010045,11), (1010046,1), (1010047,1),
(1010048,59), (1010049,15), (1010050,19), (1010051,424), (1010052,462), (1010053,9), (1010054,41), (1010055,64),
(1010056,10), (1010057,3), (...
scala>
然后,将rdd11以及rdd22中的数据根据商品ID,也就是key值进行关联,得到一张大表。表结构变为:(商品id,(商品分类,商品点击次数))
用collect()方法启动程序。
查看rddjoin的结果如下:
rddjoin.collect
res4: Array[(String, (String, String))] = Array((1013900,(52137,0)), (1010068,(52007,1316)), (1018970,(52006,788)),
(1020975,(52091,68)), (1019960,(52111,0)), (1019667,(52045,16)), (1010800,(52137,6)), (1019229,(52137,20)), (1022649,
(52119,90)), (1020382,(52137,0)), (1022667,(52021,150)), (1017258,(52086,0)), (1021963,(52072,83)), (1015809,(52137,285)),
(1024340,(52084,0)), (1011043,(52132,0)), (1011762,(52137,2)), (1010976,(52132,34)), (1010512,(52090,8)), (1023965,(52095,0)),
(1017285,(52069,41)), (1020212,(52026,46)), (1010743,(52137,0)), (1020524,(52064,52)), (1022577,(52090,13)), (1021974,(52069,22)),
(1010543,(52137,0)), (1010598,(52136,53)), (1017212,(52108,45)), (1010035,(52006,328)), (1010947,(52089,8)), (1020964,(52071,86)),
(1024001,(52063,0)), (1020191,(52046,0)), (1015739,(...
scala>
最后,在大表的基础上,进行统计。得到每个分类,商品的平均点击次数。
rddjoin.map(x=>{(x._2._1, (x._2._2.toLong, 1))}).reduceByKey((x,y)=>{(x._1+y._1, x._2+y._2)}).map(x=>{(x._1, x._2._1*1.0/x._2._2)}).collect
将结果输出,查看输出效果。
scala> rddjoin.map(x=>{(x._2._1, (x._2._2.toLong, 1))}).reduceByKey((x,y)=>{(x._1+y._1, x._2+y._2)}).map(x=>
{(x._1, x._2._1*1.0/x._2._2)}).collect
res40: Array[(String, Double)] = Array((52009,463.3642857142857), (52135,36.69230769230769), (52128,9.0), (52072,42.8),
(52078,16.5), (52137,34.735241502683365), (52047,20.96551724137931), (52050,0.0), (52056,24.57894736842105),
(52087,17.008928571428573), (52085,31.17142857142857), (52007,547.3076923076923), (52052,19.6), (52081,50.833333333333336),
(52016,106.75), (52058,34.23170731707317), (52124,0.0), (52092,28.453703703703702), (52065,8.644444444444444), (52106,22.5),
(52120,96.7843137254902), (52027,114.7), (52089,17.81159420289855), (52098,57.793103448275865), (52038,74.2), (52061,52.609375),
(52104,49.0), (52014,45.4), (52012,53.26), (52100,22.0), (52043,23.0), (52030,532.48), (52023,150.0), (52083,57.857142857142854),
(52041,40.0), (52049,18.058823529411764), (52074,33.17647058...
scala>
Spark的核心就是RDD,所有在RDD上的操作会被运行在Cluster上,Driver程序启动很多Workers,Workers在(分布式)文件系统中读取数据后转化为RDD(弹性分布式数据集),然后对RDD在内存中进行缓存和计算。
对于Spark中的API来说,它支持的语言有Scala、Java和Python,由于Scala是Spark的原生语言,各种新特性肯定是Scala最先支持的,Scala语言的优势在于语法丰富且代码简洁,开发效率高。缺点在于Scala的API符号标记复杂,某些语法太过复杂,不易上手。对Java开发者而言,也可以使用Spark Java API。
RDD有两种类型的操作 ,分别是Action(返回values)和Transformations(返回一个新的RDD)。
某电商网站记录了大量用户对商品的收藏数据,并将数据存储在名为buyer_favorite1的文件中,数据格式以及数据内容如下:
用户ID(buyer_id),商品ID(goods_id),收藏日期(dt)
现分别使用Spark Scala API及Spark Java API对用户收藏数据,进行wordcount操作,统计每个用户收藏商品数量。
1.在Linux上创建/data/spark4目录,用于存储实验所需的数据。
切换到/data/spark4目录下,并从http://59.64.78.41:60000/allfiles/spark4/下载实验数据buyer_favorite1及spark-assembly-1.6.0-hadoop2.6.0.jar。
2.使用jps查看Hadoop以及Spark的相关进程是否已经启动,若未启动则执行启动命令。
将Linux本地/data/spark4/buyer_favorite文件,上传到HDFS上的/myspark4目录下。若HDFS上/myspark4目录不存在则创建。
3.打开已安装完Scala插件的Eclipse,新建一个Scala项目。
将项目命名为spark4。
在spark4项目下新建包名,命名为my.scala。
右键点击包名, 新建scala Object。
将scala object命名为ScalaWordCount。
4.右键项目,创建一个文件夹,名为lib。
将Linux上的/data/spark4/spark-assembly-1.6.0-hadoop2.6.0.jar文件,拷贝到lib目录下。右键jar包,点击Build Path=>Add to Build Path。
5.在Eclipse中,打开ScalaWordCount.scala文件。编写Scala语句,并统计用户收藏数据中,每个用户收藏商品数量。
package my.scala
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
object ScalaWordCount {
def main(args: Array[String]) {
val conf = new SparkConf()
conf.setMaster("local")
.setAppName("scalawordcount")
val sc = new SparkContext(conf)
val rdd = sc.textFile("hdfs://localhost:9000/myspark4/buyer_favorite1")
rdd.map(line => (line.split("\t")(0), 1))
.reduceByKey(_ + _)
.collect()
.foreach(println)
sc.stop()
}
}
第一步:创建Spark的配置对象sparkConf,设置Spark程序运行时的配置信息;
第二步:创建SparkContext对象,SparkContext是Spark程序所有功能的唯一入口,无论采用Scala、Java还是Python都必须有一个SparkContext;
第三步:根据具体的数据来源,通过SparkContext来创建RDD;
第四步:对初始的RDD进行Transformation级别的处理。(首先将每一行的字符串拆分成单个的单词,然后在单词拆分的基础上对每个单词实例计数为1;最后,在每个单词实例计数为1的基础上统计每个单词在文件出现的总次数)。
6.在Eclipse中执行代码
在控制界面console中查看的输出结果。
view plain copy
7.再次右键点击项目名,新建package,将包命名为my.java 。
右键点击包my.java,新建Class,命名为JavaWordCount。
8.打开JavaWordCount.java文件,编写Java代码,统计用户收藏数据中,每个用户收藏商品数量。
package my.java;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFunction;
import scala.Tuple2;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
public final class JavaWordCount {
private static final Pattern SPACE = Pattern.compile("\t");
public static void main(String[] args) throws Exception {
SparkConf sparkConf = new SparkConf().setMaster("local").setAppName("JavaWordCount");
JavaSparkContext ctx = new JavaSparkContext(sparkConf);
JavaRDD lines = ctx.textFile("hdfs://localhost:9000/myspark4/buyer_favorite1");
JavaRDD words = lines.flatMap(new FlatMapFunction() {
@Override
public Iterable call(String s) {
String word[]=s.split("\t",2);
return Arrays.asList(word[0]);
}
});
JavaPairRDD ones = words.mapToPair(new PairFunction() {
@Override
public Tuple2 call(String s) {
return new Tuple2(s, 1);
}
});
JavaPairRDD counts = ones.reduceByKey(new Function2() {
@Override
public Integer call(Integer i1, Integer i2) {
return i1 + i2;
}
});
List> output = counts.collect();
System.out.println(counts.collect());
counts.saveAsTextFile("hdfs://localhost:9000/myspark4/out");
ctx.stop();
}
}
9.在Eclipse上执行Java代码,并在Java代码指定输出目录下查看实验结果。
您的实验报告已经提交成功。
发送消息