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支持还不算完备。
Data Frame是命名列的数据集,他在概念是等价于关系型数据库。DataFrames可以从很多地方构建,比如说结构化数据文件、hive中的表或者外部数据库,使用Dataset[row]的数据集,可以理解DataFrame就是一个Dataset[row].
原文链接:https://blog.youkuaiyun.com/weixin_38231448/article/details/89920804
一、SparkSession
Spark中所有功能的入口点是SparkSession类。
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>2.4.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--scala编译插件-->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>4.0.1</version>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<!--创建fatjar插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<!--编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
①.算子:
//普通的
package com.baizhi.qickdemo
import com.baizhi.User
import org.apache.spark.sql.SparkSession
case class User(id:Int,name:String,deptno:Int,salary:Double) {
}
object SparkSQLHelloWold01 {
def main(args: Array[String]): Unit = {
//1.构建SparkSession
val spark = SparkSession.builder()
.appName("hello world")
.master("local[*]")
.getOrCreate()
//可以将一个集合、RDD转换为Dataset或者是Dataframe
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL") //设置日志级别
//2.创建Dataset或者是Dataframe
var users:List[User]=List(new User(2,"lisi",2,1000),
new User(1,"zhangsan",1,1000),new User(3,"wangwu",1,1500))
val userDateframe = users.toDF()
//3.SparkSQL提供的算子或者SQL脚本
val resultDataFrame = userDateframe.select("id", "name", "salary", "deptNo")
//4.将SQL结果写出带外围系统
resultDataFrame.show()//打印最终结果
//5.关闭session
spark.close()
}
}
日志文件:
#自定义日志
log4j.rootLogger = FATAL,stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %p %d{yyyy-MM-dd HH:mm:ss} %c %m%n
②.SQL脚本:
package com.baizhi
import com.baizhi.User
import org.apache.spark.sql.SparkSession
case class User(id:Int,name:String,deptno:Int,salary:Double) {
}
object SparkSQLHelloWold01 {
def main(args: Array[String]): Unit = {
//1.构建SparkSession
val spark = SparkSession.builder()
.appName("hello world")
.master("local[*]")
.getOrCreate()
//可以将一个集合、RDD转换为Dataset或者是Dataframe
import spark.implicits._
spark.sparkContext.setLogLevel("FATAL")
//2.创建Dataset或者是Dataframe
var users:List[User]=List(new User(2,"lisi",2,1000),
new User(1,"zhangsan",1,1000),new User(3,"wangwu",1,1500))
val userDateframe = users.toDF()
//注册表
userDateframe.createOrReplaceTempView("t_user")
//3.SparkSQL提供的算子或者SQL脚本
val resultDataFrame = spark.sql("select id,name,deptNo,salary,salary * 12 as annual_salary from t_user")
//4.将SQL结果写出带外围系统
resultDataFrame.show()//打印最终结果
//5.关闭session
spark.close()
}
}
DataSet
Dataset与RDD类似,但是,它们不使用Java序列化或Kryo,而是使用专用的Encoder来序列化对象以便通过网络进行处理或传输。虽然Encoder和标准序列化都负责将对象转换为字节,但Encoder是动态生成的代码,并使用一种格式,允许Spark执行许多操作,如过滤,排序和散列,而无需将字节反序列化为对象。
①.json数据
json文件:
{
"name":"zly","age":20}
{
"name":"zly","age":21}
{
"name":"zly3","age":22}
package com.baizhi
import org.apache.spark.sql.{
Dataset, SparkSession}
case class Person2(name:String,age:Long){
}
object DataSet3 {
def main(args: Array[String]): Unit = {
//1.创建一个SparkSession对象
val sparkSession = SparkSession.builder().master("local[*]").appName("dataset1").getOrCreate()
//.2.设置日志等级
//引入隐式转换
//可以将一个集合、RDD转换为Dataset或者是Dataframe
import sparkSession.implicits._
sparkSession.sparkContext.setLogLevel("FATAL")
//创建dataset
val dataset = sparkSession.read.json("E:\\文档\\大数据\\feiq\\Recv Files\\08-Spark\\代码\\SparkSql\\src\\main\\resources\\word.json").as[Person2]
dataset.show()
//5.关闭sparkSession
sparkSession.stop()
}
}
②.RDD数据
//创建dataset
val Rdd = sparkSession.sparkContext.makeRDD(List((2,"zyl",20)))
val dataset = Rdd.toDS()
DataFrame
Data Frame
是命名列的数据集,他在概念是等价于关系型数据库。DataFrames可以从很多地方构建,比如说结构化数据文件、hive中的表或者外部数据库,使用Dataset[row]的数据集,可以理解DataFrame就是一个Dataset[row]。
①.json文件
//创建dataframe
val dataframe = sparkSession.read.json("E:\\文档\\大数据\\feiq\\Recv Files\\08-Spark\\代码\\SparkSql\\src\\main\\resources\\word.json")
dataframe.show()
②.元祖
//创建dataframe
val frame = sparkSession.sparkContext.parallelize(List("zyl1 23", "zyl2 24"))
.map(x => (x.split(" ")(0) ,x.split(" ")(1).toInt))
.toDF("theName","theAge")//可以自定义列名
frame.show()
③.自定义schema
package dataframe
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.types.{
BooleanType, DoubleType, IntegerType, StringType, StructField, StructType}
import org.apache.spark.sql.{
Row, SparkSession}
object TestCreateDataFrame04 {
def main(args: Array[String]): Unit = {
//1.构建SparkSession
val spark = SparkSession.builder()
.appName("hello world")
.master("local[*]")
.getOrCreate()
import spark.implicits._
//可以将一个集合、RDD转换为Dataset或者是Dataframe
spark.sparkContext.setLogLevel("FATAL")
val userRDD:RDD[Row] = spark.sparkContext.makeRDD(List((1,"张三",true,18,15000.0)))
.map(t=>Row(t._1,t._2,t._3,t._4,t._5))
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 userDataframe = spark.createDataFrame(userRDD, schema)
userDataframe.show()
//5.关闭session
spark.close()
}
}
④.java类型
定义一个java类型
package dataframe;
import java.io.Serializable;
public class JavaUser implements Serializable {
private Integer id;
private String name;
public JavaUser(Integer id,String name){
this.id=id;
this.name=name;
}
public JavaUser(){
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id=id;
}
public void setName(String name) {
this.name = name;
}
}
使用:
//创建一个集合
val userList = List(new