基于Hadoop的SparkSQL

1.了解Spark Shell、Spark SQL模式

2.学习使用Spark Shell、Spark SQL模式,创建表及查询数据

实验原理

Spark SQL的前身是Shark,Shark是伯克利实验室Spark生态环境的组件之一,它能运行在Spark引擎上,从而使得SQL查询的速度得到10-100倍的提升,但是,随着Spark的发展,由于Shark对于Hive的太多依赖(如采用Hive的语法解析器、查询优化器等等),制约了Spark的One Stack Rule Them All的既定方针,制约了Spark各个组件的相互集成,所以提出了SparkSQL项目。

SparkSQL抛弃了原有Shark的代码,汲取了Shark的一些优点,如内存列存储(In-MemoryColumnarStorage)、Hive兼容性等,重新开发了SparkSQL代码;由于摆脱了对Hive的依赖性,SparkSQL无论在数据兼容、性能优化、组件扩展方面都得到了极大的方便。

(Spark SQL 执行流程)

SQLContext具体的执行过程如下:

(1)SQL | HQL语句经过SqlParse解析成UnresolvedLogicalPlan。

(2)使用analyzer结合数据字典(catalog)进行绑定,生成resolvedLogicalPlan,在这个过程中,Catalog提取出SchemRDD,并注册类似case class的对象,然后把表注册进内存中。

(3)Analyzed Logical Plan经过Catalyst Optimizer优化器优化处理后,生成Optimized Logical Plan,该过程完成以后,以下的部分在Spark core中完成。

(4)Optimized Logical Plan的结果交给SparkPlanner,然后SparkPlanner处理后交给PhysicalPlan,经过该过程后生成Spark Plan。

(5)使用SparkPlan将LogicalPlan转换成PhysicalPlan。

(6)使用prepareForExecution()将PhysicalPlan转换成可执行物理计划。

(7)使用execute()执行可执行物理计划。

(8)生成DataFrame。

在整个运行过程中涉及到多个SparkSQL的组件,如SqlParse、analyzer、optimizer、SparkPlan等等。

实验环境

Linux Ubuntu 16.04

jdk-7u75-linux-x64

hadoop-2.6.0-cdh5.4.5

scala-2.10.5

spark-1.6.0-bin-hadoop2.6

实验内容

某电商平台,需要对订单数据进行分析,已知订单数据包括两个文件,分别为订单数据orders和订单明细数据order_items,orders记录了用户购买商品的订单ID,订单号,用户ID及下单日期。order_items记录了商品ID,订单ID以及明细ID。它们的结构与关系如下图所示:

实验步骤

1.首先检查Hadoop相关进程,是否已经启动。若未启动,切换到/apps/hadoop/sbin目录下,启动Hadoop。

view plain copy

  1. jps  
  2. cd /apps/hadoop/sbin  
  3. ./start-all.sh  

2.在Linux本地新建/data/spark5目录。

view plain copy

  1. mkdir -p /data/spark5  

3.切换到/data/spark5目录下,使用wget命令,下载http://172.16.103.12:60000/allfiles/spark5中的orders和order_items。

view plain copy

  1. cd /data/spark5  
  2. wget http://172.16.103.12:60000/allfiles/spark5/orders  
  3. wget http://172.16.103.12:60000/allfiles/spark5/order_items  

4.首先,在HDFS上新建/myspark5目录,然后将/data/spark5目录下的orders与order_items文件,上传到HDFS的/myspark5目录下。

view plain copy

  1. hadoop fs -mkdir /myspark5  
  2. hadoop fs -put /data/spark5/orders /myspark5  
  3. hadoop fs -put /data/spark5/order_items /myspark5  

5.启动Spark Shell。

view plain copy

  1. spark-shell  

6.在spark-shell下,使用case class方式定义RDD,创建orders表。

view plain copy

  1. val sqlContext = new org.apache.spark.sql.SQLContext(sc)  
  2. import sqlContext.implicits._  
  3. case class Orders(order_id:String,order_number:String,buyer_id:String,create_dt:String)  
  4. val dforders = sc.textFile("/myspark5/orders").map(_.split('\t')).map(line=>Orders(line(0),line(1),line(2),line(3))).toDF()  
  5. dforders.registerTempTable("orders")  

验证创建的表是否成功。

view plain copy

  1. sqlContext.sql("show tables").map(t=>"tableName is:"+t(0)).collect().foreach(println)  
  2. sqlContext.sql("select order_id,buyer_id from orders").collect  

7.在Spark Shell下,使用applyScheme方式定义RDD,创建order_items表。

view plain copy

  1. import org.apache.spark.sql._  
  2. import org.apache.spark.sql.types._  
  3. val rddorder_items = sc.textFile("/myspark5/order_items")  
  4. val roworder_items = rddorder_items.map(_.split("\t")).map( p=>Row(p(0),p(1),p(2) ) )  
  5. val schemaorder_items = "item_id order_id goods_id"  
  6. val schema = StructType(schemaorder_items.split(" ").map(fieldName=>StructField(fieldName,StringType,true)) )  
  7. val dforder_items = sqlContext.applySchema(roworder_items, schema)  
  8. dforder_items.registerTempTable("order_items")  

验证创建表是否成功。

view plain copy

  1. sqlContext.sql("show tables").map(t=>"tableName is:"+t(0)).collect().foreach(println)  
  2. sqlContext.sql("select order_id,goods_id from order_items ").collect  

8.将order表及order_items表进行join操作,统计该电商网站,都有哪些用户购买了什么商品。

view plain copy

  1. sqlContext.sql("select orders.buyer_id, order_items.goods_id from order_items  join orders on order_items.order_id=orders.order_id ").collect  

9.退出Spark shell模式

view plain copy

  1. exit  

下面演示Spark SQL模式

10.启动Spark SQL。

view plain copy

  1. spark-sql  

11.创建表orders及表order_items。

view plain copy

  1. create table orders (order_id string,order_number string,buyer_id string,create_dt string)  
  2. row format delimited fields terminated by '\t'  stored as textfile;  

view plain copy

  1. create table order_items(item_id string,order_id string,goods_id string)  
  2. row format delimited fields terminated by '\t'  stored as textfile;  

12.查看已创建的表。

view plain copy

  1. show tables;  

表名后的false意思是该表不是临时表。

13.将HDFS中/myspark5下的orders表和order_items表中数据加载进刚创建的两个表中。

view plain copy

  1. load data inpath '/myspark5/orders' into table orders;  
  2. load data inpath '/myspark5/order_items' into table order_items;  

14.验证数据是否加载成功。

view plain copy

  1. select * from orders;  
  2. select * from order_items; 

15.处理文件,将order表及order_items表进行join操作,统计该电商网站,都有哪些用户购买了什么商品。

view plain copy

  1. select orders.buyer_id, order_items.goods_id from order_items join orders on order_items.order_id=orders.order_id;  
  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值