一、DataFrame:有列名的RDD

首先,我们知道SparkSQL的目的是用sql语句去操作RDD,和Hive类似。SparkSQL的核心结构是DataFrame,如果我们知道RDD里面的字段,也知道里面的数据类型,就好比关系型数据库里面的一张表。那么我们就可以写SQL,所以其实这儿我们是不能用面向对象的思维去编程的。我们最好的方式就是把抽象成为一张表,然后去用SQL语句去操作它。

DataFrame的存储方式:它采用的存储是类似于数据库的表的形式进行存储的。一个数据表有几部分组成:1、数据,这个数据是一行一行进行存储的,一条记录就是一行,2、数据表的数据字典,包括表的名称,表的字段和字段的类型等元数据信息。那么DataFrame也是按照行进行存储的,这个类是Row,一行一行的进行数据存储。一般情况下处理粒度是行粒度的,不需要对其行内数据进行操作。

二、SparkSQL的程序入口:

在Spark2.0之前,是有sqlContext和hiveContext的概念的,因为这两个概念难以区分,Spark2.0之后统一称为SparkSession,除此之外SparkSession还封装了SparkConf和SparkContext。

值得注意的一点是:Hive有很多依赖包,所以这些依赖包没有包含在默认的Spark包里面。如果Hive依赖的包能在classpath找到,Spark将会自动加载它们。这些Hive依赖包必须复制到所有的工作节点上,因为它们为了能够访问存储在Hive的数据,会调用Hive的序列化和反序列化(SerDes)包。Hive的配置文件hive-site.xml、core-site.xml(security配置)和hdfs-site.xml(HDFS配置)是保存在conf目录下面。 
当使用Hive时,必须初始化一个支持Hive的SparkSession,用户即使没有部署一个Hive的环境仍然可以使用Hive。当没有配置hive-site.xml时,Spark会自动在当前应用目录创建metastore_db和创建由spark.sql.warehouse.dir配置的目录,如果没有配置,默认是当前应用目录下的spark-warehouse目录。

注意:从Spark 2.0.0版本开始,hive-site.xml里面的hive.metastore.warehouse.dir属性已经被spark.sql.warehouse.dir替代,用于指定warehouse的默认数据路径(必须有写权限)。

于是SparkSQL在与Hive有交互的情况下,需要指定支持Hive:

val conf = new SparkConf().setAppName(s"${this.getClass.getSimpleName}")
val spark = SparkSession.builder().config(conf).config("spark.sql.warehouse.dir",
"hdfs://hadoop1:9000/user/hive/warehouse").enableHiveSupport().getOrCreate()

回到正题,程序入口:

1.6版本:

val conf=new SparkConf()
conf.setAppName(s"${this.getClass.getSimpleName}").setMaster("local")
val sc=new SparkContext(conf)
val sqlContext = new SQLContext(sc)

2.0版本:

SparkSQL的程序入口缩减为一句

 val sparkSession=SparkSession.builder().appName(s"${this.getClass.getSimpleName}").master("local").getOrCreate()

两个版本一个获得sqlContext(或者hiveContext),一个获得sparkSession。

三、算了,还是放在一起写吧。。

case  class Person(var name:String,var age:Int)
object Test {
def main(args: Array[String]): Unit = {
//1.6版本入口
val conf=new SparkConf()
conf.setAppName(s"${this.getClass.getSimpleName}").setMaster("local")
val sc=new SparkContext(conf)
val sqlContext = new SQLContext(sc)
    //第一种创建DataFrame的方式:直接读取列式存储的格式,可以直接形成DataFrame(后续怎么操作呢?)
val df: DataFrame = sqlContext.read.json("")
    //第二种创建DataFrame的方式:因为rdd没有toDF()方法,需要进行隐式转化,通过map后形成一个数组
import sqlContext.implicits._
val df: DataFrame = sc.textFile("C:\\Users\\wangyongxiang\\Desktop\\plan\\person.txt").map(_.split(",")).map(p => Person(p(), p().trim.toInt)).toDF()
    //第二种方法的另一种形态,用sqlContext或者sparkSession的createDataFrame(),其实和toDF()方法是雷同的
val rdd: RDD[Person] = sc.textFile("C:\\Users\\wangyongxiang\\Desktop\\plan\\person.txt")
.map(_.split(",")).map(p => Person(p(), p().trim.toInt))
val df: DataFrame = sqlContext.createDataFrame(rdd)
    //第三种创建DataFrame:生成一个RowRDD,然后给出构造的描述
val rdd=sc.textFile("C:\\Users\\wangyongxiang\\Desktop\\plan\\person.txt")
val rowRDD: RDD[Row] = rdd.map(_.split(",")).map(p=>Row(p(),p().trim.toInt))
val schame=StructType(
StructField("name",StringType,true)::
StructField("age",IntegerType,true)::Nil
)
val df: DataFrame = sqlContext.createDataFrame(rowRDD,schame)
    //后续代码,可以创建临时视图作为查询,与mysql互操作要创建临时视图才能做查询
    //用hiveContext则直接在hive中创建表,然后将数据load到hive表中,可以直接进行条件查询,无需创建临时视图,后面与hive集成会有说明
df.registerTempTable("person")
sqlContext.sql("select * from person where age>21").show()
    //将处理后的数据用jdbc保存到mysql数据库中成为一张表,注意这里要使用user而不能使用username,因为系统也有一个username,会覆盖你的用户名
val properties=new Properties()
properties.put("user","root")
properties.put("password","root")
df.write.mode(SaveMode.Overwrite)jdbc("jdbc:mysql://localhost:3306/test","test",properties)
}
}

四、load和save操作。

object saveAndLoadTest {
def main(args: Array[String]): Unit = {
val conf =new SparkConf().setAppName("").setMaster("local")
val sc=new SparkContext(conf)
val sqlContext=new SQLContext(sc) //read,load:读取
sqlContext.read.json("")
// sqlContext.read.jdbc("url","table",properties)
sqlContext.read.load("parquet路径")
sqlContext.read.format("json").load("路径")
val df: DataFrame = sqlContext.read.format("parquet").load("路径") //write,save保存
df.write.parquet("路径.parquet")
df.write.json("路径.json")
// df.write.jdbc("url","table",properties)
df.write.format("parquet").save("路径.parquet")
df.write.format(("json")).save("路径.json")
//保存模式可选择覆盖,追加等
df.write.mode(SaveMode.Overwrite).save("")
}
}

个人理解是read和load都是读取的作用,write和save都是保存的作用,通过上述的代码,我们可以完成文件格式转换的工作,将效率低的一些格式转化成parquet这种sparksql原生支持的文件类型

Spark SQL读写方法的更多相关文章

  1. 6.3 使用Spark SQL读写数据库

    Spark SQL可以支持Parquet.JSON.Hive等数据源,并且可以通过JDBC连接外部数据源 一.通过JDBC连接数据库 1.准备工作 ubuntu安装mysql教程 在Linux中启动M ...

  2. Spark SQL数据加载和保存实战

    一:前置知识详解: Spark SQL重要是操作DataFrame,DataFrame本身提供了save和load的操作, Load:可以创建DataFrame, Save:把DataFrame中的数 ...

  3. Spark SQL数据载入和保存实战

    一:前置知识具体解释: Spark SQL重要是操作DataFrame,DataFrame本身提供了save和load的操作. Load:能够创建DataFrame. Save:把DataFrame中 ...

  4. 理解Spark SQL(一)—— CLI和ThriftServer

    Spark SQL主要提供了两个工具来访问hive中的数据,即CLI和ThriftServer.前提是需要Spark支持Hive,即编译Spark时需要带上hive和hive-thriftserver ...

  5. Spark SQL中列转行(UNPIVOT)的两种方法

    行列之间的互相转换是ETL中的常见需求,在Spark SQL中,行转列有内建的PIVOT函数可用,没什么特别之处.而列转行要稍微麻烦点.本文整理了2种可行的列转行方法,供参考. 本文链接:https: ...

  6. Spark SQL DataFrame新增一列的四种方法

    方法一:利用createDataFrame方法,新增列的过程包含在构建rdd和schema中 方法二:利用withColumn方法,新增列的过程包含在udf函数中 方法三:利用SQL代码,新增列的过程 ...

  7. Spark SQL中 RDD 转换到 DataFrame (方法二)

    强调它与方法一的区别:当DataFrame的数据结构不能够被提前定义.例如:(1)记录结构已经被编码成字符串 (2) 结构在文本文件中,可能需要为不同场景分别设计属性等以上情况出现适用于以下方法.1. ...

  8. === $ spark sql 的特别的方法

    /** * Equality test. * {{{ * // Scala: * df.filter( df("colA") === df("colB") ) ...

  9. 使用 Spark SQL 高效地读写 HBase

    Apache Spark 和 Apache HBase 是两个使用比较广泛的大数据组件.很多场景需要使用 Spark 分析/查询 HBase 中的数据,而目前 Spark 内置是支持很多数据源的,其中 ...

随机推荐

  1. 试一下Markdown

    Markdown 没想到博客园居然能够有markdown这样的写法了,以前觉得有自定义CSS已经非常不错了,现在居然加入Markdown,太值得称赞了.国内的博客系统,应该首屈一指了. 强调 你要走, ...

  2. CentOS7.5 Linux搭建全文检索--Solr7.4.0单机服务

    一.Solr安装环境 1.官方参考文档 Solr教程参考指南:http://lucene.apache.org/solr/guide/7_4/solr-tutorial.html 2.Solr运行环境 ...

  3. thinkphp 点击某个class提交post值,返回回来用一个弹窗插件,提示返回来要说的话

    下一篇文章有讲到弹窗插件的怎么使用,自写教程 如果能帮到你,给点个赞鼓励一下 <=============  控制器  =================> public function ...

  4. db2 应用的最常见状态(转)

    db2 的应用最常见的状态为UOW Executing, UOW Waiting,  Connect Completed等,这里做一个简单的介绍. UOW全称是Unit Of Work, 可以认为是事 ...

  5. 部署不能产生class文件的问题

    项目clean和重新部署项目之后,还是不能产生class文件:查看“Problem”视图,是lib路径有问题,右击项目→“Build Path”→“Configure Build Path”,Libr ...

  6. [No0000105]java sdk 开发环境变量powershell 自动配置脚本

    # 设置Java SDK 环境变量 $softwares = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Unin ...

  7. gensim Word2Vec 训练和使用(Model一定要加载到内存中,节省时间!!!)

    训练模型利用gensim.models.Word2Vec(sentences)建立词向量模型该构造函数执行了三个步骤:建立一个空的模型对象,遍历一次语料库建立词典,第二次遍历语料库建立神经网络模型可以 ...

  8. Linux上mount 挂载windows共享文件权限问题

    在服务器部署的时候需要把文件夹设置在windows的共享文件上.在使用mount命令挂载到linux上后.文件路径和文件都是可以访问,但是不能写入,导致系统在上传文件的时候提示“权限不够,没有写权限” ...

  9. elastic search范围查询

    queryBuilder.must(QueryBuilders.rangeQuery("pt_longitude").from(minLongitude).to(maxLongit ...

  10. vue关于html页面id设置问题

    vue是一个前端框架,类似于angularJS等,vue在编写的时候需要在html页面指定id,但是不是都可以实现的,一般放在id需在div设置里才可以实现. (一) 在html里设置id: < ...