史上最简单的spark教程第十章-SparkSQL编程Java案例实践(二)

Spark-SQL的Java实践案例(二)

史上最简单的spark教程
所有代码示例地址:https://github.com/Mydreamandreality/sparkResearch

(提前声明:文章由作者:张耀峰 结合自己生产中的使用经验整理,最终形成简单易懂的文章,写作不易,转载请注明)
(文章参考:Elasticsearch权威指南,Spark快速大数据分析文档,Elasticsearch官方文档,实际项目中的应用场景)
(帮到到您请点点关注,文章持续更新中!)
Git主页 https://github.com/Mydreamandreality

在这里我们继续上一章节SparkSQL的案例啊,没有看上一章节的兄弟萌 点击这里哈https://blog.csdn.net/youbitch1/article/details/88852644

在这里插入图片描述
[给卢姥爷上香]


  • 上一章节的最开始,我们说为了实现sparkSQL的功能,spark提供了一种全新的RDD叫做
    DataFrame,但是我们的SparkSQL返回值一直是DataSet,可能有些兄弟就有点不理解了啊
  • Dataset其实是一个分布式的数据收集器
  • DataFrame可以从广泛的数据源中构成.比如:结构化的数据文件,Hive的table,外部数据库和RDD
  • DataFrame在Scala,Java,Python和R中都支持,在Java中为Dataset
  • 这就兄弟萌能理解为啥返回DataSet了吧
  • 更具体的东西咱写到后面再分析一波
    在这里插入图片描述

  • 上一章节的最后,我们以编程的方式运行sparkSQL查询,把dataframe注册成为临时表运行SQL语句(也可以称为临时视图)

  • 但是它有个很大的问题

    • 临时表是当前使用的SQLContext中的临时变量,在我们的的应用退出时这些临时表就不再存在了
    • 说白了就是临时视图是session级别的,它会随着session的消息而消失
  • 那如果我们想要一个临时视图在所有的session中互相传递使用,直到spark的应用终结,该咋办

    • 这个时候我们只需要创建一个全局临时视图即可

全局临时视图

  • 全局临时视图存在于系统数据库的global_temp
  • 全局临时视图的生命周期随spark程序的运行消失
  • 在这里插入图片描述
  • 来吧让我们用代码说话,代码案例:
        try {
            //创建全局临时视图
            dataset.createGlobalTempView("user");
            //全局临时视图绑定到系统保存的数据库“global_temp”
            Dataset<Row> globalUser = sparkSession.sql("SELECT * FROM global_temp.user");
            sparkSession.newSession().sql("SELECT * FROM global_temp.user");
        } catch (AnalysisException e) {
            e.printStackTrace();
        }
  • 代码还是很简单的
  • 首先创建我们的全局临时视图,使用createGlobalTempView函数创建(在上一章节中创建临时视图使用的函数是createOrReplaceTempView)
  • 其次我们说了,我们的全局临时视图绑定到我们的系统库 global_temp中,所以在查询的时候需要先指定我们的系统库(系统库无需关注,系统自带的)
  • 最后呢,我们说过,全局临时变量是跨会话的,所以你可以在新会话中执行我们的SQL语句
  • 在这里插入图片描述

创建DataSet

  • DataSet和RDD比较类似,不同的地方就是序列化的方式
  • RDD序列化是使用Java的serialization或者kryo实现序列化和反序列化的
  • DataSet是使用的encoder来实现对象的序列化和在网络中的传输
  • encoder有个动态的特性,Spark在执行比如sorting之类的操作时无需再把字节反序列化成对象
  • 代码示例:
        SparkSession sparkSession = SparkSession.builder().master("local")
                .appName("Java Spark SQL")
                .getOrCreate();
        Person person = new Person("spark",10);
        Encoder<Person> encoder = Encoders.bean(Person.class);
        Dataset<Person> dataset = sparkSession.createDataset(Collections.singletonList(person),encoder);
        dataset.show();
        //最终输出 {name:spark;age:10}


        /*常见类型的编码器*/
        Encoder<Integer> integerEncoder = Encoders.INT();
        Dataset<Integer> integerDataset = sparkSession.createDataset(Arrays.asList(1,2),integerEncoder);
        Dataset<Integer> result = integerDataset.map(new MapFunction<Integer, Integer>() {
            @Override
            public Integer call(Integer value) {
                return value+1;
            }
        },integerEncoder);
        result.collect();
        //最终输出 [2,3]
        
        
         /*通过提供一个类,可以将数据流转换为数据集。基于名称的映射*/
        String url = "/usr/local/text.json";
        Dataset<Person> personDataset = sparkSession.read().json(url).as(encoder);
        personDataset.show();
        //最终输出 name:...  age:,,,,
  • 上面这个案例如何理解?
  • 灵魂画手上线:
    *在这里插入图片描述
  • 这样就很好理解了,下面两个案例同理,只是数据类型为基础类型
    在这里插入图片描述

这章的最后在这里总结一下 RDD和dataframe,DataSet的区别

  • RDD
  • 弹性分布式数据集.是Spark对数据进行的一种抽象,可以理解为Spark对数据的一种组织方式.更简单些说.RDD就是一种数据结构.里面包含了数据和操作数据的方法
  • 关键字:
    • 弹性,分布式,数据集

  • DataFrame
  • 理解了RDD.DataFrame就容易理解些
  • RDD是一个数据集,DataFrame在RDD的基础上增加了Schema(描述数据的信息,可以认为是元数据,DataFrame曾经就叫做schemaRDD)
  • 做个对比,如果左边的数据是RDD,那么右边的就是dataframe
  • 在这里插入图片描述
  • DataFrame比RDD多了一个表头信息(Schema),像一张表,DataFrame还配套了新的操作数据的方法,DataFrameAPI 比如df.select()和SQL(select id, name from xx_table where …))等等
  • 正因为有了这层抽象,我们开发才能很爽啊,处理数据就变得很简单了
  • 不仅如此.通过DataFrame API或SQL处理数据.会自动经过Spark的优化器(Catalyst)的优化.即使你写的程序或SQL不高效,也可以运行的很快
  • 注意:DataFrame是用来处理结构化数据的

  • DataSet
  • 对于RDD而言,DataSet做了强类型支持,在RDD的每一行都做了数据类型约束
  • RDD转换DataFrame后不可逆,但RDD转换Dataset是可逆的
  • 下面这就是DataSet的数据
    在这里插入图片描述
这章就先到这里啦,这章我们知道了创建DataSet的方式还有RDD和dataframe,dataset的区别
下一章节写RDD和DataSet的转换操作吧

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章