sparkSQL

sparkSQL

介绍
  • sparkSQL将SQL解析成spark任务来执行 , 使用更友好 .

  • Shark是基于Spark计算框架之上且兼容Hive语法的SQL执行引擎, 底层的计算采用了Spark , 性能比MapReduce的Hive大约快2倍之上 . 当数据全部加载到内存的情况下 , 性能几乎快10倍. Shark完全兼容了Hive , 但是Shark对于HIve的依赖性太强 , 不能和spark其他组件进行太好的集成 , 难以长远发展 .

Spark on Hive 和 Hive on Spark
  • hive on spark : 数据源来自hive表 , hive即负责存储有又负责sql的解析优化 , spark负责执行任务 .

  • spark on hive : 数据源在hive上 , hive只作为储存角色 , 执行任务的是spark , 负责sql的解析优化和执行 .

DataFrame

  • DataFrame 是一个分布式数据容器 , 与RDD类似 , 但是比较起来 DataFrame更加像mysql数据库的二维表格 , 数据的结构信息被称为schema . 和hive相似 ,DataFrame也支持嵌套数据类型(struct , array 和 map) . 从API上看 , DataFrame提供一套高层的关系操作 , 比RDD API要更加简单 , 友好 .

  • DataFrame的底层封装是RDD , 不过RDD的泛型是Row类型 .

SparkSQL的数据源

在这里插入图片描述

  • SparkSQL的数据来源可以是JSON类型的字符串 , JDBC操作的数据库 , Parquet , hive , mysql , HDFS , SQL , amazonS3等等 . 额外还有AVRO , CSV , HBASE , elasticsearch 等 .
sparkSQL底层框架

sql语句解析后成为一批未被解决的逻辑计划 , 在经过分析得到分析后的逻辑计划 , 再进过一批优化规则转换成一批最佳优化的逻辑计划 , 再经过SparkPlanner的策略转化成一批物理计划 .随后经过消费模型转换成一个个的Spark任务执行 .
在这里插入图片描述
SQl结果sql解析器变成一个未被解决的逻辑计划 , 经过分析器变成一个被分析好的逻辑计划 , 经过优化后成为优化后的逻辑计划 , 在经过Spark的操作成为物理计划 , 经过一系列操作后最后变成RDD .

谓词下推

在这里插入图片描述

API
  • json格式创建
    在这里插入图片描述
package com.java;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SQLContext;

/**
 * Created by Administrator on 2019/2/21.
 */
public class SparkSql_json {
        public static void main(String[] args){
            SparkConf conf = new SparkConf();
            conf.setMaster("local").setAppName("josn_sql");
            JavaSparkContext sparkContext = new JavaSparkContext(conf);
            // sparkSQL操作对象
            SQLContext sqlcont = new SQLContext(sparkContext);

            // 设置json模式和json格式数据的位置 , 不能读取嵌套的json格式
            DataFrame json = sqlcont.read().format("json").load("json");


            // 查看数据
            //json.show();
            // 查看scheme信息
            //json.printSchema();

            // 原生API
//            json.select("name","age").where(json.col("age").gt(18)).show(20);   //age>18 . 打印20条信息

            json.registerTempTable("jsonTable"); //将json数据加载到内存,注册成临时表 .
            DataFrame sql = sqlcont.sql("select name , age from jsonTable where age > 18");  //从临时表操作数据 , 返回到一个结果集
            sql.show();

//            JavaRDD<Row> rowJavaRDD = sql.javaRDD();  //DataFram还可以直接转换成RDD , row类对象有getString(0),getString(1)...的方法来获取参数值.
            sparkContext.stop();
        }
}


  • 非JSON格式反射创建
    在这里插入图片描述
package com.java;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.SQLContext;

/**
 * Created by Administrator on 2019/2/21.
 */
public class sparkSql_txt {
        public static void main(String[] args){
            SparkConf conf = new SparkConf().setMaster("local").setAppName("txt_sql");
            JavaSparkContext jsc = new JavaSparkContext(conf);
            SQLContext sql = new SQLContext(jsc);

            //读取数据
            JavaRDD<String> stringJavaRDD = jsc.textFile("./person.txt");

            JavaRDD<Person> pers = stringJavaRDD.map(new Function<String, Person>() {

                private static final long serialVersionUID = 1L ;

                @Override
                public Person call(String s) throws Exception {
                    Person p = new Person();

                    p.setId(s.split(",")[0]);
                    p.setName(s.split(",")[1]);
                    p.setAge(Integer.parseInt(s.split(",")[2]));
                    return p;
                }
            });

            // 传入Person.class , sqlContext通过反射创建DataFrame
            DataFrame dataFrame = sql.createDataFrame(pers, Person.class);
            dataFrame.show();
            dataFrame.printSchema();
        }
}

(person)

package com.java;

import java.io.Serializable;

/**
 * Created by Administrator on 2019/2/21.
 */
public class Person implements Serializable{

    private static final long setrialVersionUID = 1L;

    private String id;
    private String name;
    private Integer age;

    public static long getSetrialVersionUID() {
        return setrialVersionUID;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}


(非JSON格式动态创建)

package com.java;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.types.DataType;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;

/**
 * Created by Administrator on 2019/2/21.
 */
public class sparkSql_struct {
        public static void main(String[] args){
            SparkConf sc = new SparkConf().setMaster("local").setAppName("struct");
            JavaSparkContext jsc = new JavaSparkContext(sc);
            SQLContext sql = new SQLContext(jsc);

            JavaRDD<String> stringJavaRDD = jsc.textFile("./person.txt");

            //拿到数据
            JavaRDD<Row> map = stringJavaRDD.map(new Function<String, Row>() {
                @Override
                public Row call(String s) throws Exception {
                    return RowFactory.create(
                            s.split(",")[0],
                            s.split(",")[1],
                            Integer.parseInt(s.split(",")[2])
                    );
                }
            });

            // 拿到元数据信息
            List<StructField> asList = Arrays.asList(
                    DataTypes.createStructField("id",DataTypes.StringType,true), //字段名 , 类型 , 值是否可以为空
                    DataTypes.createStructField("name",DataTypes.StringType,true),
                    DataTypes.createStructField("age",DataTypes.IntegerType,true)
            );
            StructType schema = DataTypes.createStructType(asList);

			//生成DataFrame
            DataFrame df = sql.createDataFrame(map, schema); 
            df.printSchema();
            df.show();

			jsc.stop();
        }
}


  • parquet格式创建
    • parquet格式数据
      在这里插入图片描述
                // 与json模式操作相同  , 不同之处在于以下代码
            DataFrame json = sqlcont.read().format("parquet").load("./parquet");
           
    

    • JDBC
	package com.java;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.SaveMode;

import java.util.HashMap;
import java.util.Properties;

/**
 * Created by Administrator on 2019/2/21.
 */
public class sparkSQL_jdbc {
        public static void main(String[] args){
                SparkConf conf = new SparkConf();
                conf.setMaster("local").setAppName("mysql");
                //配置jion或者聚合操作shuffle数据时 分区的数量
                conf.set("spark.sql.shuffle.partitions","1");

                JavaSparkContext jsc = new JavaSparkContext(conf);
                SQLContext sqlContext = new SQLContext(jsc);

            HashMap<String, String> sqlContextHashMap = new HashMap<>();
            sqlContextHashMap.put("url","jdbc:mysql://localhost:3306/diy"); //数据库IP地址/数据库
            sqlContextHashMap.put("driver","com.mysql.jdbc.Driver");//驱动包
            sqlContextHashMap.put("user","root");//账号
            sqlContextHashMap.put("password","123456");//密码
            sqlContextHashMap.put("dbtable","tb_user");//数据库的表

            // jdbc模式读取数据库的数据
            DataFrame jdbc = sqlContext.read().format("jdbc").options(sqlContextHashMap).load();
            jdbc.show();

            // 写到数据库

            /**
             * SaveMode:
             *          Overwrite:覆盖
             *          Append:追加
             *          ErrorIfExists:如果存在就报错
             *          Ignore:如果存在就忽略
              */
            Properties p = new Properties();
            p.setProperty("user","root");
            p.setProperty("password","123456");
            jdbc.write().mode(SaveMode.Append).jdbc("jdbc:mysql://localhost:3306/diy","result2",p);

        }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值