SparkShell操作

实验目的

1、了解Scala语言的基本语法

2、了解Spark Shell数据处理的原理

3、了解Spark 算子的使用

4、了解Spark shell和Mapreduce对数据处理的不同点

实验环境

1、Linux Ubuntu 14.04

2、jdk1.7

3、scala-2.10.4

4、hadoop-2.6.0-cdh5.4.5

5、spark-1.6.0-bin-hadoop2.6

实验内容

使用spark对数据进行WordCount统计、去重、排序、求平均值以及Join操作。

实验步骤

WordCount统计:
某电商网站数据文件/data/mydata/sparkshell/buyer_favorite,记录了用户对商品的收藏数据,数据及数据格式如下:

用户id(buyer_id),商品id(goods_id),收藏日期(dt)

  1. 用户id   商品id    收藏日期  
  2. 10181   1000481   2010-04-04 16:54:31  
  3. 20001   1001597   2010-04-07 15:07:52  
  4. 20001   1001560   2010-04-07 15:08:27  
  5. 20042   1001368   2010-04-08 08:20:30  
  6. 20067   1002061   2010-04-08 16:45:33  
  7. 20056   1003289   2010-04-12 10:50:55  
  8. 20056   1003290   2010-04-12 11:57:35  
  9. 20056   1003292   2010-04-12 12:05:29  
  10. 20054   1002420   2010-04-14 15:24:12  
  11. 20055   1001679   2010-04-14 19:46:04  
  12. 20054   1010675   2010-04-14 15:23:53  
  13. 20054   1002429   2010-04-14 17:52:45  
  14. 20076   1002427   2010-04-14 19:35:39  
  15. 20054   1003326   2010-04-20 12:54:44  
  16. 20056   1002420   2010-04-15 11:24:49  
  17. 20064   1002422   2010-04-15 11:35:54  
  18. 20056   1003066   2010-04-15 11:43:01  
  19. 20056   1003055   2010-04-15 11:43:06  
  20. 20056   1010183   2010-04-15 11:45:24  
  21. 20056   1002422   2010-04-15 11:45:49  
  22. 20056   1003100   2010-04-15 11:45:54  
  23. 20056   1003094   2010-04-15 11:45:57  
  24. 20056   1003064   2010-04-15 11:46:04  
  25. 20056   1010178   2010-04-15 16:15:20  
  26. 20076   1003101   2010-04-15 16:37:27  
  27. 20076   1003103   2010-04-15 16:37:05  
  28. 20076   1003100   2010-04-15 16:37:18  
  29. 20076   1003066   2010-04-15 16:37:31  
  30. 20054   1003103   2010-04-15 16:40:14  
  31. 20054   1003100   2010-04-15 16:40:16  

现要求统计用户收藏数据中,每个用户收藏商品数量。

1、存储有用户收藏数据的用户文件buyer_favorite,放在/data/mydata/sparkshell目录下。

2、使用jps查看Hadoop以及spark的相关进程是否已经启动,若未启动则执行启动命令。

  1. cd /data/mydata/sparkshell/  
  1. jps  
  1. /apps/hadoop/sbin/start-all.sh  
  1. /apps/spark/sbin/start-all.sh  

将/data/mydata/sparkshell/buyer_favorite文件,上传到HDFS上的/mysparkshell目录下。若hdfs目录不存在则创建。

  1. hadoop fs -mkdir /mysparkshell  
  1. hadoop fs -put /data/mydata/sparkshell/buyer_favorite /mysparkshell  

3、启动spark-shell

  1. spark-shell  

4、编写scala语句,统计用户收藏数据中,每个用户收藏商品数量。

先在spark-shell中,加载数据

  1. val rdd = sc.textFile("hdfs://localhost:9000/mysparkshell/buyer_favorite");  

编写算子,执行统计,并输出

  1. rdd.map(line=> (line.split('\t')(0),1)).reduceByKey(_+_).collect  

去重:
使用spark-shell,对上述实验中,用户收藏数据文件,进行统计。根据商品id进行去重,统计用户收藏数据中,都有哪些商品被收藏。

1、保证hadoop、spark框架相关进程为已启动状态,且保证所使用的数据,存放位置和上述实验一致。

2、编写scala语句,统计用户收藏数据中,都有哪些商品被收藏。

先加载数据,创建RDD

  1. val rdd = sc.textFile("hdfs://localhost:9000/mysparkshell/buyer_favorite");  

使用算子,对RDD进行统计,并将结果打印输出

  1. rdd.map(line => line.split('\t')(1)).distinct.collect  

排序:
电商网站一般都会对商品的访问情况,进行统计,现有一个文件/data/mydata/sparkshell/goods_visit文件,存储了各种商品,以及此商品的点击次数。

商品id(goods_id) 点击次数(click_num)

  1. 商品id  点击次数  
  2. 1010037 100  
  3. 1010102 100  
  4. 1010152 97  
  5. 1010178 96  
  6. 1010280 104  
  7. 1010320 103  
  8. 1010510 104  
  9. 1010603 96  
  10. 1010637 97  
  11. ... ...  

现根据商品的点击次数进行排序,并输出所有商品

输出结果样式

  1. 点击次数 商品ID  
  2. 96  1010603  
  3. 96  1010178  
  4. 97  1010637  
  5. 97  1010152  
  6. 100 1010102  
  7. 100 1010037  
  8. 103 1010320  
  9. 104 1010510  
  10. 104 1010280  

1、商品点击数据goods_visit,放在/data/mydata/sparkshell/目录下。将数据,上传到HDFS的 /mysparkshell目录下

  1. cd /data/mydata/sparkshell  
  1. hadoop fs -put /data/mydata/sparkshell/goods_visit /mysparkshell  

2、启动spark-shell

  1. spark-shell  

将测试数据变成RDD

  1. val rdd = sc.textFile("hdfs://localhost:9000/mysparkshell/goods_visit");  

使用算子,对RDD进行统计,并将结果打印输出

  1. rdd.map(line => ( line.split('\t')(1).toInt, line.split('\t')(0) ) ).sortByKey(true).collect  

3、输出结果样式为:

  1. scala> rdd.map(line => ( line.split('\t')(1).toInt, line.split('\t')(0) ) ).sortByKey(true).collect  
  2. res8: Array[(Int, String)] = Array((96,1010178), (96,1010603), (97,1010152), (97,1010637), (100,1010037), (100,1010102), (103,1010320), (104,1010280), (104,1010510))  

Join:
现有某电商在2011年12月15日的部分交易数据。数据有订单表orders和订单明细表order_items,表结构及数据分别为:

orders表:(订单id order_id, 订单号 order_number, 买家ID buyer_id, 下单日期 create_dt)

  1. 订单ID   订单号          买家ID    下单日期  
  2. 52304    111215052630    176474    2011-12-15 04:58:21  
  3. 52303    111215052629    178350    2011-12-15 04:45:31  
  4. 52302    111215052628    172296    2011-12-15 03:12:23  
  5. 52301    111215052627    178348    2011-12-15 02:37:32  
  6. 52300    111215052626    174893    2011-12-15 02:18:56  
  7. 52299    111215052625    169471    2011-12-15 01:33:46  
  8. 52298    111215052624    178345    2011-12-15 01:04:41  
  9. 52297    111215052623    176369    2011-12-15 01:02:20  
  10. 52296    111215052622    178343    2011-12-15 00:38:02  
  11. 52295    111215052621    178342    2011-12-15 00:18:43  

order_items表:(明细ID item_id, 订单ID order_id, 商品ID goods_id )

  1. 明细ID  订单ID   商品ID  
  2. 252578    52293    1016840  
  3. 252579    52293    1014040  
  4. 252580    52294    1014200  
  5. 252581    52294    1001012  
  6. 252582    52294    1022245  
  7. 252583    52294    1014724  
  8. 252584    52294    1010731  
  9. 252586    52295    1023399  
  10. 252587    52295    1016840  
  11. 252592    52296    1021134  
  12. 252593    52296    1021133  
  13. 252585    52295    1021840  
  14. 252588    52295    1014040  
  15. 252589    52296    1014040  
  16. 252590    52296    1019043  

orders表和order_items表,通过订单id进行关联,是一对多的关系。

下面,请使用spark-shell,查询在当天该电商网站,都有哪些用户又购买了什么商品。

1、电商数据orders订单数据及order_items明细数据,放在/data/mydata/sparkshell/join目录下

2、将/data/mydata/sparkshell/join目录下的数据,上传到HDFS的/mysparkshell目录下

  1. hadoop fs -put /data/mydata/sparkshell/join/orders /mysparkshell  
  1. hadoop fs -put /data/mydata/sparkshell/join/order_items /mysparkshell  

3、检查HDFS及spark服务是否已经启动,然后启动spark-shell

  1. spark-shell  

4、创建两个rdd,分别加载orders文件以及order_items文件中的数据。

  1. val rdd1 = sc.textFile("hdfs://localhost:9000/mysparkshell/orders");  
  2. val rdd2 = sc.textFile("hdfs://localhost:9000/mysparkshell/order_items");  

我们的目的是查询都有哪些用户购买了什么商品。所以对rdd1和rdd2进行map映射,得出关键的两个列的数据。

  1. val rdd11 = rdd1.map(line=> (line.split('\t')(0), line.split('\t')(2)) )  
  2. val rdd22 = rdd2.map(line=> (line.split('\t')(1), line.split('\t')(2)) )  

将rdd11以及rdd22中的数据,根据key值,进行join关联,得到最终结果

  1. val rddresult = rdd11 join rdd22  

最后将结果输出,查看输出效果。

  1. rddresult.collect  

最终的执行结果为:

  1. scala> rddresult.collect  
  2. res6: Array[(String, (String, String))] = Array((52296,(178343,1021134)), (52296,(178343,1021133)), (52296,(178343,1014040)), (52296,(178343,1019043)), (52295,(178342,1023399)), (52295,(178342,1016840)), (52295,(178342,1021840)), (52295,(178342,1014040)))  

将输出数据进行格式化

  1. (52296,(178343,1021134)),  
  2. (52296,(178343,1021133)),  
  3. (52296,(178343,1014040)),  
  4. (52296,(178343,1019043)),  
  5. (52295,(178342,1023399)),  
  6. (52295,(178342,1016840)),  
  7. (52295,(178342,1021840)),  
  8. (52295,(178342,1014040))  

可以看到上面数据关联后一共有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、电商数据goods及goods_visit文件数据,放在/data/mydata/sparkshell/avg目录下

2、将/data/mydata/sparkshell/avg目录下的数据,上传到HDFS的/mysparkshell目录下

  1. hadoop fs -mkdir -p /mysparkshell/avg  
  1. hadoop fs -put /data/mydata/sparkshell/avg/goods /mysparkshell/avg  
  1. hadoop fs -put /data/mydata/sparkshell/avg/goods_visit /mysparkshell/avg  

3、检查HDFS及spark服务是否已经启动,然后启动spark-shell

  1. spark-shell  

4、创建两个rdd,分别加载goods文件以及goods_visit文件中的数据。

  1. val rdd1 = sc.textFile("hdfs://localhost:9000/mysparkshell/avg/goods");  
  2. val rdd2 = sc.textFile("hdfs://localhost:9000/mysparkshell/avg/goods_visit");  

我们的目的是统计每个分类下,商品的平均点击次数,我们可以分三步来做。

首先,对rdd1和rdd2进行map映射,得出关键的两个列的数据。

  1. val rdd11 = rdd1.map(line=> (line.split('\t')(0), line.split('\t')(2)) )  
  2. val rdd22 = rdd2.map(line=> (line.split('\t')(0), line.split('\t')(1)) )  

rdd11的样式

  1. scala> rdd11.collect  
  2. 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...  

rdd22的样式

  1. scala> rdd22.collect  
  2. 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), (...  

其次,将rdd11以及rdd22中的数据,根据商品id,也就是key值进行关联,得到一张大表。表结构变为:(商品id,(商品分类,商品点击次数))

  1. val rddjoin = rdd11 join rdd22  

rddjoin的样式

  1. scala> rddjoin.collect  
  2. 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,(...  

最后,在大表的基础上,进行统计。得到每个分类,商品的平均点击次数。

  1. 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  

将结果输出,查看输出效果。

  1. 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  
  2. 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...  
  3. scala>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值