Spark的基本结构及SparkSQL组件的基本用法

本文主要侧重对Spark核心结构和组件的功能介绍。

Apache Spark简介

Apache Spark是一种快速的集群计算技术,专为快速计算而设计。它基于Hadoop MapReduce,它扩展了MapReduce模型,以有效地将其用于更多类型的计算,包括交互式查询和流处理。Spark的主要特性是它的内存中集群计算,提高了应用程序的处理速度。Spark旨在涵盖各种工作负载,如批处理应用程序,迭代算法,交互式查询和流式处理。除了在相应系统中支持所有这些工作负载之外,它还减少了维护单独工具的管理负担。
这里写图片描述

MapReduce与Spark迭代计算与查询对比

MapReduce被广泛应用于在集群上使用并行的分布式算法来处理和生成大型数据集。它允许用户使用一组高级操作符来编写并行计算,而不必担心工作分布和容错。不幸的是,在大多数当前框架中,在计算之间重复使用数据(例如:两个MapReduce作业之间)的唯一方法是将其写入外部稳定存储系统(例如:HDFS)。虽然这个框架提供了访问集群的计算资源的许多抽象,用户仍然想要更多。迭代和交互应用程序都需要跨并行作业更快的数据共享。由于复制,序列化和磁盘IO,MapReduce中的数据共享速度很慢。关于存储系统,大多数Hadoop应用程序,他们花费90%以上的时间做HDFS读写操作。
弹性分布式数据集(RDD)是Spark的基本数据结构。它是一个不可变的分布式对象集合。 RDD中的每个数据集划分为逻辑分区,可以在集群的不同节点上计算。 RDD可以包含任何类型的Python,Java或Scala对象,包括用户定义的类。形式上,RDD是只读的,分区的记录集合。 RDD可以通过对稳定存储器或其他RDD上的数据的确定性操作来创建。 RDD是可以并行操作的元件的容错集合。有两种方法来创建RDD - 并行化驱动程序中的现有集合,或引用外部存储系统中的数据集,例如共享文件系统,HDFS,HBase或提供Hadoop输入格式的任何数据源。Spark使用RDD的概念来实现更快和更高效的MapReduce操作。
这里写图片描述

这里写图片描述

SparkSQL简介及基本用法

Spark为结构化数据处理引入了一个称为Spark SQL的编程模块。它提供了一个称为DataFrame的编程抽象,并且可以充当分布式SQL查询引擎。Spark SQL允许您将结构化数据作为Spark中的分布式数据集(RDD)进行查询,在Python,Scala和Java中集成了API,这种紧密的集成使得可以轻松地运行SQL查询以及复杂的分析算法。
Spark Core(利用RDD数据结构设计)的数据源:文本文件,Avro文件等。
Spark SQL(适用于模式、表和记录)的数据源:Parquet文件,JSON文档,HIVE表和Cassandra数据库。可以使用Schema RDD作为临时表,将Schema RDD称为数据帧。
DataFrame是一个分布式数据集合,它被组织成命名列。从概念上讲,它相当于具有良好优化技术的关系表。DataFrame可以从不同来源的数组构造,例如Hive表,结构化数据文件,外部数据库或现有RDD。

这里写图片描述
与spark-shell同级启动目录下分别生成数据准备文件people.json和people.txt如下:
这里写图片描述
创建SQLContext

val sqlContext=new org.apache.spark.sql.SQLContext(sc)

读取JSON文档people.json

val dfs=sqlContext.read.json("people.json")

#Ouput:
#dfs: org.apache.spark.sql.DataFrame = [age: bigint, name: string]

显示数据框的数据

dfs.show   #或者dfs.show()

#Output:
#+----+-------+
#| age|   name|
#+----+-------+
#|null|Michael|
#|  30|   Andy|
#|  19| Justin|
#+----+-------+

查看DataFrame的Structure(Schema)

dfs.printSchema()

#Output:
#root
# |-- age: long (nullable = true)
# |-- name: string (nullable = true)

select,从DataFrame里选择某一列

dfs.select("name").show()

#Output:
#+-------+
#|   name|
#+-------+
#|Michael|
#|   Andy|
#| Justin|
#+-------+

filter,利用过滤器筛选样本

dfs.filter(dfs("age")>20).show()

#Output:
#+---+----+
#|age|name|
#+---+----+
#| 30|Andy|
#+---+----+

groupBy,对样本进行分组;count,进行分组后的每组计数

dfs.groupBy("age").count().show()

#Output:
#+----+-----+                                                                    
#| age|count|
#+----+-----+
#|  19|    1|
#|null|    1|
#|  30|    1|
#+----+-----+

SQLContext使应用程序能够在运行SQL函数时以编程方式运行SQL查询,并将结果作为DataFrame返回。SparkSQL支持两种不同的方法将现有的RDD转换为DataFrames:
(1)使用反射来生成包含特定类型的对象的RDD的模式
Spark SQL的Scala接口支持将”包含case类的RDD”自动转换为DataFrame。 case类定义了表的模式。 “case类的参数的名称”使用”反射”读取,它们成为”列的名称”。

#创建sqlContext
val sqlContext=new org.apache.spark.sql.SQLContext(sc)

#导入用于将RDD隐式转换为DataFrame的所有SQL函数
import sqlContext.implicits._

#必须使用case类定义记录数据的模式
case class people(name: String, age: Int)

#从中读取数据people.txt并使用Map函数将其转换为DataFrame
val empl=sc.textFile("people.txt").map(_.split(",")).map(e => people(e(0),e(1).trim.toInt)).toDF()

#将DataFrame数据存储在表peoples中
empl.registerTempTable("peoples")

#选择DataFrame上的查询
val allrecords=sqlContext.sql("SELECT * FROM peoples")

#显示查询结果
allrecords.show
#Output:
#+-------+---+
#|   name|age|
#+-------+---+
#|Michael| 29|
#|   Andy| 30|
#| Justin| 19|
#+-------+---+

#带条件查询
val agefilter=sqlContext.sql("SELECT * FROM peoples WHERE age>=20 AND age<=35")
agefilter.show()
#Output:
#+-------+---+
#|   name|age|
#+-------+---+
#|Michael| 29|
#|   Andy| 30|
#+-------+---+

#以上两个查询是针对整个表DataFrame传递的,下面尝试通过对“查询后的结果”应用Transform来“从结果DataFrame获取数据”
agefilter.map(t=>"NAME:"+t(0)).collect().foreach(println)
#Output:
#NAME:Michael
#NAME:Andy

(2)通过编程接口创建DataFrame
通过编程接口,构造一个模式,然后将其应用到现有的RDD。根据以下三个步骤以编程方式创建一个DataFrame:a. 从原始RDD创建Row RDD;b. 创建与上一步里创建的Row RDD中“Row结构”匹配的StructType表示的模式;c. 通过sqlContext提供的createDataFrame方法将模式应用于Row RDD。

import org.apache.spark.sql.SQLContext
#Output:
#import org.apache.spark.sql.SQLContext

#创建SQLContext对象
val sqlContext=new SQLContext(sc)
#Output:
#warning: there was one deprecation warning; re-run with -deprecation for details
sqlContext: org.apache.spark.sql.SQLContext = org.apache.spark.sql.SQLContext@1a717d79

#从文本文件读取输入
val people=sc.textFile("file:///Users/yuyang/spark-2.0.1-bin-hadoop2.6/bin/people.txt")
#Output:
#people: org.apache.spark.rdd.RDD[String] = file:///Users/yuyang/spark-2.0.1-bin-hadoop2.6/bin/people.txt MapPartitionsRDD[1] at textFile at <console>:25

#以字符串格式创建编码模式,假设一个表的字段结构
val schemaString="name age"
#Output:
#schemaString: String = name age

#导入行功能
import org.apache.spark.sql.Row
#Output:
#import org.apache.spark.sql.Row

#导入SQL数据类型
import org.apache.spark.sql.types.{StructType,StructField,StringType}
#Output:
#import org.apache.spark.sql.types.{StructType, StructField, StringType}

#通过读取schemaString变量来生成模式
#将整个字符串以空格作为分隔符来读取每个字段,并且默认情况下,每个字段类型为String类型
val schema=StructType(schemaString.split(" ").map(fieldName=>StructField(fieldName,StringType,true)))
#Output:schema: org.apache.spark.sql.types.StructType = StructType(StructField(name,StringType,true), StructField(age,StringType,true))

#将RDD(people)转换为Rows,指定读取RDD数据的逻辑并将其存储到rowRDD中
val rowRDD=people.map(_.split(",")).map(p=>Row(p(0),p(1).trim))
#Output:
#rowRDD: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[3] at map at <console>:29

#基于模式schema应用rowRDD创建DataFrame
val peopleDataFrame=sqlContext.createDataFrame(rowRDD,schema)
#Output:
#peopleDataFrame: org.apache.spark.sql.DataFrame = [name: string, age: string]

#将数据帧存储到名为peopleTempTab的表中
peopleDataFrame.registerTempTable("peopleTempTab")
#Output:
#there was one deprecation warning; re-run with -deprecation for details

val personsRDD=sqlContext.sql("select name,age from peopleTempTab where age>20").rdd
#Output:
#personsRDD: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[9] at rdd at <console>:29

personsRDD.foreach(t=>println("Name:"+t(0)+",Age:"+t(1)))
#Output:
#Name:Michael,Age:29
#Name:Andy,Age:30

这里写图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spark SQLSpark生态系统中的一个组件,它提供了一种用于结构化数据处理的高级数据处理接口。Spark SQL支持使用SQL语言进行数据查询和处理,并且可以与Spark的其他组件(如Spark Streaming、MLlib等)无缝集成。Spark SQL还支持使用DataFrame API进行数据处理,这使得开发人员可以使用Scala、Java、Python和R等编程语言进行数据处理。Spark SQL还支持将数据存储在各种数据源中,如Hive、JSON、Parquet等。Spark SQL的主要优点是可以处理大规模的结构化数据,并且具有高性能和可扩展性。 ### 回答2: SparkSQL是Apache Spark中的一种组件,它用于处理结构化和半结构化数据。与传统的Spark核心功能相比,SparkSQL提供了更高级的数据处理工具,使得用户可以使用SQL查询和操作结构化数据。 SparkSQL基本概念包括DataFrame和Dataset。DataFrame是强类型的分布式数据集,它可以看作是一个表,每一列都有一个名字和数据类型。Dataset是比DataFrame更加丰富的API,它可以以编程的方式进行查询和操作数据。 SparkSQL支持使用标准的SQL查询语言进行数据查询和聚合。用户可以编写SQL语句来过滤、聚合和排序数据,并通过SparkSQL将结果存储在DataFrame或Dataset中。 SparkSQL还支持多种数据格式的读取和写入,包括Parquet、Avro、JSON和CSV等。用户可以通过提供Schema来从这些格式中读取数据,并可以选择将数据以这些格式写入磁盘。 另外,SparkSQL还提供了与Hive的集成,使得用户可以使用Hive的元数据和UDF函数。用户可以通过SparkSQL查询Hive表,并将查询结果存储在Hive表中。 SparkSQL还支持缓存数据以提高查询性能。用户可以使用DataFrame或Dataset的persist()方法将数据持久化到内存或磁盘中,并可以通过调用unpersist()方法来释放缓存的数据。 总结来说,SparkSQL是Apache Spark中用于处理结构化和半结构化数据的组件,它提供了DataFrame和Dataset的概念,支持使用SQL语言进行数据查询和聚合,以及多种数据格式的读写,还具备与Hive的集成以及数据缓存等功能。 ### 回答3: Spark SQL是Apache Spark的一个模块,它提供了用于处理结构化数据的SQL查询和集成,使得在Spark中可以方便地进行数据处理和分析。 Spark SQL的核心是DataFrames,它是一种可处理具有命名列的分布式数据集的数据结构。DataFrames可以由多种数据源创建,包括结构化数据、Parquet文件、JSON文件、Hive表等。与传统的RDD相比,DataFrames具有更高的性能和更强的优化能力,因为它们提供了类似于传统数据库的结构化查询API。 通过Spark SQL,我们可以使用标准的SQL查询语言来查询和操作DataFrames中的数据。Spark SQL支持常见的SQL操作,如SELECT、JOIN、GROUP BY等,还支持用户自定义函数和聚合函数的定义。这使得开发人员可以使用熟悉的SQL语法来处理和分析数据,无需编写复杂的MapReduce或Spark程序。 除了SQL查询,Spark SQL还提供了用于将DataFrames转换为RDD的接口,以及将RDD转换为DataFrames的接口。这使得在需要深度定制数据处理逻辑时可以灵活地切换和使用两者之间的API。 总之,Spark SQL是一个强大而灵活的数据处理工具,它通过提供SQL查询和集成的方式,使得在Spark中可以方便地处理和分析结构化数据。它不仅提供了与传统数据库类似的性能和优化能力,还提供了与Spark的其他组件(如MLlib和GraphX)的无缝集成,使得在Spark平台上进行大规模数据处理变得更加简单和高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值