Spark SQL
Spark SQL是用于结构化数据处理的一个模块 同Spark RDD不同地方在于Spark SQL的API可以给Spark计算引擎提供更多地信息 例如:数据结构 计算算子等 在内部Spark可以通过这些信息有针对对任务做优化和调整 这里有几种方式和Spark SQL进行交互 例如Dataset API和SQL等 这两种API可以混合使用 Spark SQL的一个用途是执行SQL查询 Spark SQL还可用于从现有Hive安装中读取数据 从其他编程语言中运行SQL时 结果将作为Dataset/DataFrame返回 使用命令行或JDBC/ODBC与SQL接口进行交互Dataset是一个分布式数据集合在Spark 1.6提供一个新的接口 Dataset提供RDD的优势(强类型 使用强大的lambda函数)以及具备了Spark SQL执行引擎的优点 Dataset可以通过JVM对象构建 然后可以使用转换函数等(例如:map flatMap filter等) 目前Dataset API支持Scala和Java 目前Python对Dataset支持还不算完备DataFrame是命名列的数据集 他在概念是等价于关系型数据库 DataFrames可以从很多地方构建 比如说结构化数据文件 hive中的表或者外部数据库 使用Dataset[row]的数据集 可以理解DataFrame就是一个Dataset[Row]
任意数据 ==》 RDD
元组、样例类
toDF
SparkSession
Spark中所有功能的入口点是SparkSession类 要创建基本的SparkSession 只需要使用SparkSession.buildeacr()
- 依赖
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>2.4.3</version>
</dependency>
- Drvier程序
object SparkSQL {
def main(args: Array[String]): Unit = {
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[10]")
.getOrCreate()
//2.引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//3.关闭spark
spark.stop()
}
}
创建Dataset/DataFrame
Dataset
Dataset与RDD类似 但是他们不适用Java序列化或Kryo 而是使用专用的Encoder来序列化对象以便通过网络进行处理或传输 虽然Encoder和标准序列化都负责将对象转换为字节 但Encoder是动态生成的代码 并使用一种格式 允许spark执行许多操作 如过滤 排序和散列 而无需将字节反序列化对象
- case-class
case class Person(id:Int,name:String,age:Int,sex:Boolean)
object SparkSQL {
def main(args: Array[String]): Unit = {
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[10]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val dataset:Dataset[Person]=
List(Person(1,"zhangsan",18,true),Person(2,"wangwu",28,true)).toDS()
//3.SparkSQL提供的算子或者SQL脚本
val data = dataset.select($"id",$"name")
//4.将SQL结果写出到外围系统
data.show()
//3.关闭spark
spark.stop()
}
}
+---+--------+
| id| name|
+---+--------+
| 1|zhangsan|
| 2| wangwu|
+---+--------+
- Tuple元组
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[10]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val dataset:Dataset[(Int,String,Int,Boolean)]=
List((1,"xiaoh",18,true),(2,"xiaos",28,true)).toDS()
//3.SparkSQL提供的算子或者SQL脚本
val data = dataset.select($"_1",$"_2")
//4.将SQL结果写出到外围系统
data.show()
//3.关闭spark
spark.stop()
+---+-----+
| _1| _2|
+---+-----+
| 1|xiaoh|
| 2|xiaos|
+---+-----+
//或者 val data = dataset.selectExpr("_1 as id","_2 as name","(_3 *10) as age
+---+-----+---+
| id| name|age|
+---+-----+---+
| 1|xiaoh|180|
| 2|xiaos|280|
+---+-----+---+
- json数据
{
"name":"张三","age":18}
{
"name":"lisi","age":28}
{
"name":"wangwu","age":38}
case class Person(name:String,age:Long)
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val personDataset:Dataset[Person] = spark.read.json("D:\\ideaProject\\bigdataCodes\\SparkSQLHelloWord\\src\\main\\resources\\user_json.txt").as[Person]
//3.SparkSQL提供的算子或者SQL脚本
personDataset.select("name","age")
//4.将SQL结果写出到外围系统
personDataset.show()
//3.关闭spark
spark.stop()
}
+---+--------+
|age| name|
+---+--------+
| 18|zhangsan|
| 28| lisi|
| 38| wangwu|
+---+--------+
- rdd
元组
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val userRDD=spark.sparkContext.makeRDD(List((1,"小黑",true,18,1500),(2,"小白",false,20,1100))).toDS()
//3.SparkSQL提供的算子或者SQL脚本
//4.将SQL结果写出到外围系统
userRDD.show()
//3.关闭spark
spark.stop()
+---+----+-----+---+----+
| _1| _2| _3| _4| _5|
+---+----+-----+---+----+
| 1|小黑| true| 18|1500|
| 2|小白|false| 20|1100|
+---+----+-----+---+----+
case-class
case class Person(id:Int,name:String,sex:Boolean,age:Int,salary:Double)
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val userRDD = spark.sparkContext.makeRDD(List(Person(1,"小黑",true,18,1000),Person(2,"小白",false,20,1500))).toDS()
//3.SparkSQL提供的算子或者SQL脚本
//4.将SQL结果写出到外围系统
userRDD.show()
//3.关闭spark
spark.stop()
+---+----+-----+---+------+
| id|name| sex|age|salary|
+---+----+-----+---+------+
| 1|小黑| true| 18|1000.0|
| 2|小白|false| 20|1500.0|
+---+----+-----+---+------+
DataFrame
Data Frame是命名列得数据集 等价于关系型数据块库 构建DataFrames有很多种方式 比如结构化数据文件 hive中得表或者外部数据库 使用Dataset[row]的数据集 也可以说DataFrame就是一个Dataset[Row]
- json文件
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val frame = spark.read.json("D:\\ideaProject\\bigdataCodes\\SparkSQLHelloWord\\src\\main\\resources\\user_json.txt")
//3.SparkSQL提供的算子或者SQL脚本
//4.将SQL结果写出到外围系统
frame.show()
//3.关闭spark
spark.stop()
+---+--------+
|age| name|
+---+--------+
| 18|zhangsan|
| 28| lisi|
| 38| wangwu|
+---+--------+
- case class
case class Person(name:String,age:Int)
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val frame=List(Person("zhangsan",20),Person("lisi",25)).toDF("name","age")
//3.SparkSQL提供的算子或者SQL脚本
//4.将SQL结果写出到外围系统
frame.show()
//3.关闭spark
spark.stop()
+--------+---+
| name|age|
+--------+---+
|zhangsan| 20|
| lisi| 25|
+--------+---+
- Tuple元组
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val frame=List(("海绵宝宝",20),("章鱼哥",25)).toDF("name","age")
//3.SparkSQL提供的算子或者SQL脚本
//4.将SQL结果写出到外围系统
frame.show()
//3.关闭spark
spark.stop()
+--------+---+
| name|age|
+--------+---+
|海绵宝宝| 20|
| 章鱼哥| 25|
+--------+---+
- RDD转换
Row
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val userRDD=spark.sparkContext
.makeRDD(List((1,"派大星",false,21,5000.00),
(2,"珊迪",true,23,6000.00),
(3,"蟹老板",false,26,8000.00)))
.map(t=>Row(t._1,t._2,t._3,t._4,t._5))
//3.SparkSQL提供的算子或者SQL脚本
val fields = Array(new StructField("id", IntegerType),
new StructField("name", StringType),
new StructField("sex", BooleanType),
new StructField("age", IntegerType),
new StructField("salary", DoubleType))
val schema = new StructType(fields)
val frame = spark.createDataFrame(userRDD, schema)
//4.将SQL结果写出到外围系统
frame.show()
//3.关闭spark
spark.stop()
+---+------+-----+---+------+
| id| name| sex|age|salary|
+---+------+-----+---+------+
| 1|派大星|false| 21|5000.0|
| 2| 珊迪| true| 23|6000.0|
| 3|蟹老板|false| 26|8000.0|
+---+------+-----+---+------+
Javabean
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val userRDD=spark.sparkContext
.makeRDD(List(new Person(1,"王昭君",false,21,5000.00),
new Person(2,"安琪拉",true,23,6000.00),
new Person(3,"妲己",false,26,8000.00)))
//3.SparkSQL提供的算子或者SQL脚本
val frame = spark.createDataFrame(userRDD, classOf[Person])
//4.将SQL结果写出到外围系统
frame.show()
//3.关闭spark
spark.stop()
这里的person须是javaBean对象 如果是Scala的类 用户需要额外提供get方法
case-class
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val userRDD=spark.sparkContext
.makeRDD(List(Person(1,"王昭君",false,21,5000.00),
Person(2,"安琪拉",true,23,6000.00),
Person(3,"妲己",false,26,8000.00)))
//3.SparkSQL提供的算子或者SQL脚本
val frame = spark.createDataFrame(userRDD)
//4.将SQL结果写出到外围系统
frame.show()
//3.关闭spark
spark.stop()
+---+------+-----+---+------+
| id| name| sex|age|salary|
+---+------+-----+---+------+
| 1|王昭君|false| 21|5000.0|
| 2|安琪拉| true| 23|6000.0|
| 3| 妲己|false| 26|8000.0|
+---+------+-----+---+------+
tuple元组
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
val userRDD=spark.sparkContext
.makeRDD(List((1,"王昭君",false,21,5000.00),
(2,"安琪拉",true,23,6000.00),
(3,"妲己",false,26,8000.00)))
//3.SparkSQL提供的算子或者SQL脚本
val frame = spark.createDataFrame(userRDD)
//4.将SQL结果写出到外围系统
frame.show()
//3.关闭spark
spark.stop()
+---+------+-----+---+------+
| _1| _2| _3| _4| _5|
+---+------+-----+---+------+
| 1|王昭君|false| 21|5000.0|
| 2|安琪拉| true| 23|6000.0|
| 3| 妲己|false| 26|8000.0|
+---+------+-----+---+------+
不加对象是元组 元组的格式t._1 加了对象是case-class
Dataset/DataFrame API操作
准备数据
1,Michael,false,29,2000
5,Lisa,false,19,1000
3,Justin,true,19,1000
2,Andy,true,30,5000
4,Kaine,false,20,5000
-尝试将文本数据转变为DataFrame
//1.创建SparkSession
val spark = SparkSession.builder()
.appName("hellosql")
.master("local[*]")
.getOrCreate()
//引入改隐式转换 主要是将RDD转换为DataFrame/Dataset
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
val persons=List("1,Michael,false,29,2000,5,Lisa,false,19,1000,3,Justin,true,19,1000,2,Andy,true,30,5000,4,Kaine,false,20,5000")
val personlines = spark.sparkContext.parallelize(persons)
//2.创建Dataset或者是Dataframe
val userRDD:RDD[Person]= personlines.map(line=>line.split(","))
.map(ts=>Person(ts(0).toInt,ts(1),ts(2).toBoolean,ts(3).toInt,ts(4).toDouble))
val frame = userRDD.toDF()
//3.SparkSQL提供的算子或者SQL脚本
//4.将SQL结果写出到外围系统
frame.printSchema()
frame.show()
//3.关闭spark
spark.stop()
root
|-- id: integer (nullable = false)
|-- name: string (nullable = true)
|-- sex: boolean (nullable = false)
|-- age: integer (nullable = false)
|-- salary: double (nullable = false)
+---+-------+-----+---+------+
| id| name| sex|age|salary|
+---+-------+-----+---+------+
| 1|Micha