[Spark] 05 - Spark SQL
关于Spark SQL (Structured Query Language),首先会想到一个问题:Apache Hive vs Apache Spark SQL – 13 Amazing Differences
Hive has been known to be the component of Big data ecosystem where legacy mappers and reducers are needed to process data from HDFS whereas Spark SQL is known to be the component of Apache Spark API which has made processing on Big data ecosystem a lot easier and real-time.
原理解析
Ref: https://www.bilibili.com/video/av27076260/?p=9
小比较:
Hive: SQL --> map/reduce,Hive on Spark 就是把map/reduce直接换为Spark。
Spark SQL: SQL integrated in Spark;可直接读取Hive的保存的文件,兼容Hive。
架构图:
转化过程:
Catalyst's general tree transformation framework
(一)SQL Parser 转化为 Abstract Syntax Tree。
(二)逻辑最佳化,只保留需要的部分:
Parquet格式时,将字符串透过字典编码压缩成整数,缩小资料量;
RDBMS时,将筛选推到资料源端。
(三)可执行的物理计划,并产生 JVM bytecode。
智能选择 “Broadcast Join” or "Shuffle Join" 来减少网络流量
低阶优化,减少比较消耗的物件。
优化示例:
def add_demographics(events):
u = sqlCtx.table("users")
events.join(u, events.user_id) == u.user_id).withColumn("city", zipToCity(df.zip)) events = add_demographics(sqlCtx.load("/data/events", "parquet"))
training_data = events.where(events.city == "New York").select(events.timestamp).collect()
抽象语法树:
Spark SQL DataFrame
Dataframe作为新的数据结构,可以操作更为细粒度。(能看到RDD内部的结构化信息)
Spark SQL编程使用的是:SparkSession 接口,类似之前的SparkContext 的地位。
“关系型数据库” 与 "机器学习" 的结合。
基本概念
一、SparkSession
PySpark交互环境下,会自动生成 SparkSession 和 SparkContext。
from pyspark import SparkContext, SparkConf
from pyspark.sql import SparkSession spark = SparkSession.builder.config(conf=SparkConf()).getOrCreate()
二、DataFrame
读取文件
/usr/local/spark/examples/src/main/resources/ 文件夹下有实例文件以供实验。
df = spark.read.text("people.txt")
df = spark.read.format("text").load("people.txt") # 等价的方式
df = spark.read.json("people.json") df = spark.read.parquet("people.parquet") df.show()
从HDFS中读取文件。
from pyspark.sql import SQLContext
sc = SparkContext()
sqlcontext = SQLContext(sc)
#format后面为告诉程序读取csv格式,load后面为hdfs地址,hdfs后面跟着hadoop的名字,然后文件目录(这块有点懵,如果报错,跟着报错查修)
data = sqlcontext.read.format("com.databricks.spark.csv").\
options(header="true",inferschema="true").\
load("hdfs://cdsw1.richstone.com/test1/5min.csv")
data.show(5)
result = data.groupBy("type").count().orderBy("count")
result.show()
保存文件
注意,最后 newpeople.json 是目录,有点意思。
peopleDF = spark.read.format("json").load("file:///usr/local/spark/examples/src/main/resources/people.json") peopleDF.select("name", "age").write.format("json").save("file:///usr/local/spark/mycode/sparksql/newpeople.json")
除了如上的json,还支持 text, parquet 格式 的文件。
三、常用操作
df.printSchema() # 模式信息
df.select(df["name",df["age"]+1]).show() # age列的value都加1
df.filter(df["age"]>20).show()
df.groupBy("age").count().show()
df.sort(df["age"]).desc()).show()
df.sort(df["age"]).desc().df["name"].asc()).show() # 轻松实现 "二次排序"
RDD转换为DataFrame
一、利用"反射"机制推断RDD模式
使用反射来推断包含特定对象类型的RDD的模式(schema)。适用于写spark程序的同时,已经知道了模式,使用反射可以使得代码简洁。
结合样本的名字,通过反射读取,作为列的名字。
这个RDD可以隐式转化为一个SchemaRDD,然后注册为一个表。表可以在后续的sql语句中使用。
第一步、转化为Row形式的RDD格式
from pyspark.sql import Row people = spark.sparkContext.textFile("..."). \
... map(lambda line: line.split(",")). \
... map(lambda p: Row(name=p[0], age=int(p[1])))
这里转换为了Row对象。
第二步、RDD格式 转换为 DataFrame
这里只是通过DataFrame的sql比较方便的查询了下数据而已。
注意理解:people是rdd,经过一次转变df后,又变回rdd,完成一次 “反射” 过程。
schemaPeople = spark.createDataFrame(people)
# 必须注册为临时表才能供下面的查询使用
schemaPeople.createOrReplaceTempView("people")
personDF = spark.sql("select name, age from people where age > 20")
# 再转化回RDD形式,而df的一行也就是p,其中包含name, age两个元素
personsRDD = personsDF.rdd.map(lambda p: "Name: " + p.name + "," + "Age: " + str(p.age))
personsRDD.foreach(print)
Output:
Name: Michael,Age: 29
Name: Andy,Age: 30
二、用编程方式去定义RDD模式
当无法提前获知数据结构时。
Jeff: 数据文件中没有说明“数据类型”,只是全都是字符串。而“反射”方案中的rdd是含有类型的。
from pyspark.sql.types import *
from pyspark.sql import Row # 生成"表头"
schemaString = "name age"
fields = [ StructField(field_name, StringType(), True) for field_name in schemaString.split(" ") ]
schema = StructType(fields) # 生成"记录"
lines = spark.sparkContext.textFile("file:/// ... people.txt")
parts = lines.map(lambda x: x.split(","))
people = parts.map(lambda p: Row(p[0], p[1].strip()))
#--------------------------------------------------------------
# 拼接“表头”和“记录”
schemaPeople = spark.createDataFrame(people, schema) schemaPeople.createOrReplaceTempView("people")
results = spark.sql("SELECT name,age FROM people")
results.show()
连接数据库
一、启动MySQL并创建数据
启动数据库。
service mysql start
mysql -u root -p
创建数据。
create database spark;
use spark; create table student (id int(4), name char(20), gender char(4), age int(4)); insert into student values(1, 'Xueqian', 'F', 23)
insert into student values(2, 'Weiliang', 'M', 24) select * from student
Spark调用MySQL,需安装JDBC驱动程序:mysql-connector-java-5.1.40.tar.gz
二、连接数据库
做个查询,测试一下连接。
>>> use spark;
>>> select * from student;
三、插入记录
(1) 设置“表头”
(2) 设置“记录”
转变为Row的形式
rowRDD = studentRDD.map(lambda p: Row(int(p[].strip()), p[].strip(), p[].strip(), int(p[].strip())))
(3) 拼接“表头”和“记录”
studentDF = spark.createDataFrame(rowRDD, schema)
(4) 写入数据库
DataFrame形式的数据 写入 数据库。
prop = {}
prop['user'] = 'root'
prop['password'] = ''
prop['driver'] = "com.mysql.jdbc.Driver" # 构建好参数后
studentDF.write.jdbc("jdbc:mysql://localhost:3306/spark",'student','append', prop)
(5) 查看效果
End.
[Spark] 05 - Spark SQL的更多相关文章
- [Spark][Python][DataFrame][SQL]Spark对DataFrame直接执行SQL处理的例子
[Spark][Python][DataFrame][SQL]Spark对DataFrame直接执行SQL处理的例子 $cat people.json {"name":" ...
- [Spark][Hive][Python][SQL]Spark 读取Hive表的小例子
[Spark][Hive][Python][SQL]Spark 读取Hive表的小例子$ cat customers.txt 1 Ali us 2 Bsb ca 3 Carls mx $ hive h ...
- Spark Shell启动时遇到<console>:14: error: not found: value spark import spark.implicits._ <console>:14: error: not found: value spark import spark.sql错误的解决办法(图文详解)
不多说,直接上干货! 最近,开始,进一步学习spark的最新版本.由原来经常使用的spark-1.6.1,现在来使用spark-2.2.0-bin-hadoop2.6.tgz. 前期博客 Spark ...
- 大数据技术之_27_电商平台数据分析项目_02_预备知识 + Scala + Spark Core + Spark SQL + Spark Streaming + Java 对象池
第0章 预备知识0.1 Scala0.1.1 Scala 操作符0.1.2 拉链操作0.2 Spark Core0.2.1 Spark RDD 持久化0.2.2 Spark 共享变量0.3 Spark ...
- Hive on Spark和Spark sql on Hive,你能分的清楚么
摘要:结构上Hive On Spark和SparkSQL都是一个翻译层,把一个SQL翻译成分布式可执行的Spark程序. 本文分享自华为云社区<Hive on Spark和Spark sql o ...
- [Spark][Python]spark 从 avro 文件获取 Dataframe 的例子
[Spark][Python]spark 从 avro 文件获取 Dataframe 的例子 从如下地址获取文件: https://github.com/databricks/spark-avro/r ...
- [Spark][Python]Spark 访问 mysql , 生成 dataframe 的例子:
[Spark][Python]Spark 访问 mysql , 生成 dataframe 的例子: mydf001=sqlContext.read.format("jdbc").o ...
- Spark Shell & Spark submit
Spark 的 shell 是一个强大的交互式数据分析工具. 1. 搭建Spark 2. 两个目录下面有可执行文件: bin 包含spark-shell 和 spark-submit sbin 包含 ...
- 【转】科普Spark,Spark是什么,如何使用Spark
本博文是转自如下链接,为了方便自己查阅学习和他人交流.感谢原博主的提供! http://www.aboutyun.com/thread-6849-1-1.html http://www.aboutyu ...
随机推荐
- c语言的图形库
图形库链接http://www.easyx.cn/ 使用图形库头文件easyx.h或graphics.h 同样在里面下载图形库帮助文档进行查询 vs vc都可使用图形库 图形库窗口: initgrap ...
- Python中模块与包的导入(朴实易懂版的总结)
这几天,被python包与模块的导入问题,折磨的不行,以前想的很简单,其实不然,经查资料研究,特总结如下: 基本注意点 模块:一般指一个py文件:包:含有许多py文件的文件夹,含有 或不含有(Pyth ...
- Java虚拟机详解(七)------虚拟机监控和分析工具(1)——命令行
通过前面的几篇博客,我们介绍了Java虚拟机的内存分配以及内存回收等理论知识,了解这些知识对于我们在实际生产环境中提高系统的运行效率是有很大的帮助的.但是话又说回来,在实际生产环境中,线上项目正在运行 ...
- C笔记_常用快捷键
1.第一部分 Ctrl + up/down 以光标所在行为中心上下移动文本: Ctrl + left/right 左右跳过一个单词或符号: Ctrl + end 跳至文本末尾: Ctrl + dele ...
- 随笔编号-15 重构--改善既有代码的设计--Day01--学习笔记
最近公司开发的系统在进行大批量数据查询的时候发现响应速度变得让人无法忍受,so 老大安排我进行代码重构的工作,主要目的就是为提高代码的执行效率.减小方法之间的响应时间.降低方法之间的耦合度.= =! ...
- jsDeliver+github使用教程,免费的cdn
欢迎访问我的个人博客皮皮猪:http://www.zhsh666.xyz 前言:CDN的全称是Content Delivery Network,即内容分发网络.CDN是构建在网络之上的内容分发网络,依 ...
- CENTOS服务器基础教程-U盘系统盘制作
什么都要用到一点点,会一点点,现在的USB3.0基本上服务器都已经支持.小编给大家介绍基础篇:如何使用U盘制作系统安装盘 工具/原料 U盘 UltraISO工具 方法/步骤 准备一个U ...
- 大转盘(CocosCreator)
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 1.在场景中搭建大转盘场景,假设 奖项有n项,对应的每项旋转角度如下: 第几项 需要旋转的角度 0 360/n/2 1 360/ ...
- Codeforces Round #506 (Div. 3) 1029 D. Concatenated Multiples
题意: 给定n个数字,和一个模数k,从中选出两个数,直接拼接,问拼接成的数字是k的倍数的组合有多少个. 思路: 对于a,b两个数,假定len = length of (b),那么a,b满足条件就是a ...
- POJ 3207 Ikki's Story IV - Panda's Trick 2-sat模板题
题意: 平面上,一个圆,圆的边上按顺时针放着n个点.现在要连m条边,比如a,b,那么a到b可以从圆的内部连接,也可以从圆的外部连接.给你的信息中,每个点最多只会连接的一条边.问能不能连接这m条边,使这 ...