Spark SQL 下DateFrame的初步认识(1)

本文介绍了SparkSQL作为新一代SQL-on-Hadoop工具的发展历程及其相对于Shark的优势,包括数据兼容性、计算能力和未来的展望。此外,还详细讲解了DataFrame的概念及其实现方式,并通过具体案例展示了如何在实际环境中使用SparkSQL。

1, SparkSQL简介

SparkSQL的前身是Shark,给熟悉RDBMS但又不理解MapReduce的技术人员提供快速上手的工具,Hive应运而生,它是当时唯一运行在Hadoop上的SQL-on-Hadoop工具。但是MapReduce计算过程中大量的中间磁盘落地过程消耗了大量的I/O,降低的运行效率,为了提高SQL-on-Hadoop的效率,大量的SQL-on-Hadoop工具开始产生,其中表现较为突出的是:
MapR的Drill;Cloudera的Impala;Shark
其中Shark是伯克利实验室Spark生态环境的组件之一,它修改了下图所示的右下角的内存管理、物理计划、执行三个模块,并使之能运行在Spark引擎上,从而使得SQL查询的速度得到10-100倍的提升。
但是,随着Spark的发展,对于野心勃勃的Spark团队来说,Shark对于Hive的太多依赖(如采用Hive的语法解析器、查询优化器等等),制约了Spark的One Stack Rule Them All的既定方针,制约了Spark各个组件的相互集成,所以提出了SparkSQL项目。SparkSQL抛弃原有Shark的代码,汲取了Shark的一些优点,*如内存列存储(In-Memory Columnar Storage)、Hive兼容性等,重新开发了SparkSQL代码;由于摆脱了对Hive的依赖性,SparkSQL无论在数据兼容、性能优化、组件扩展方面都得到了极大的方便。*

2, SparkSQL的优势

(1) 数据兼容
SparkSQL可以处理一切存储介质和各种格式的数据,目前来看不但兼容Hive,还可以从RDD、parquet文件、JSON文件中获取数据,未来版本甚至支持获取RDBMS数据以及cassandra等NOSQL数据;同时SparkSQL可以通过扩展功能来支持更多的数据类型,例如Kudo等。

(2) 计算能力
由于SparkSQL基于Spark的高效计算引擎,导致其对于数据仓库的计算能力具有级大规模的提升(尤其在2.0版本钨丝计划成熟以后),提升包括两方面:

1) 计算速度
Spark的强大计算能力为保证,提升计算速度。
2) 计算复杂度
由于SparkSQL可以直接操作DataFrame,从而使数据仓库的数据可以直接使用复杂算法库中的算法(例如机器学习,图计算等),从而可以进行复杂升读的数据价值的挖掘。

3, SparkSQL的未来

(1) SparkSQL将是数据仓库引擎,将是数据挖掘的引擎,将是数据科学计算和分析的引擎
(2) DataFrame会让Spark(SQL)成为大数据计算引擎的霸主地位
(3) 传统数据库对于实时事务性分析具有优势:例如银行转账。
(4) 未来大数据解决方案雏形:Hive提供廉价的数据仓库存储,SparkSQL负责高速的计算,DataFrame负责复杂的数据挖掘

4. DataFrame简介

(1) 理解
Spark的DataFrame可以简单的理解为一个分布式的二维表,这样也就意味着他的每一列都带有名称和类型,也就意味着SparkSQL在基于每一列数据的元数据进行更加细粒度的分析,而不是如同以往分析RDD的时候那种粗粒度的分析。也就意味着这样SparkSQL基于DataFrame可以进行更加高效的性能优化。
(2) 与RDD的区别
DataFrame的数据特点有点类似下图,其包含了每个Record的Metadata信息,让你可以在优化时基于列内部进行优化(例如一共30列,你只需要其中10列,你就可以只获取其中10列的信息)
这里写图片描述

RDD的数据特点有点类似下图,框架只知道每个Record是个person,但是无法洞悉内部是什么,这样也就导致了框架无法洞悉Record内部的细节,也就在优化的时候闲置了SparkSQL的性能提升
这里写图片描述

5, 企业级实践发展历史

(1) 最开始阶段的文件存储
(2) JavaEE加数据库
(3) 数据局限导致Hive的出现,但是Hive的计算能力太慢,拖累数据的价值
(4) Hive计算引擎逐渐转向SparkSQL(大部分公司存在阶段)
(5) Hive+SparkSQL+DataFrame(小部分公司存在阶段)
(6) Hive+SparkSQL+DataFrame+DataSet(极少数公司存在阶段)

6,sparkSql 基础案例实战

一: spark on hive 实战步骤:
1, 切换到spar的conf目录下使用vi hive-site.xml创建hive-site.xml. 并填写如下内容

<configuration>
    <property>
        <name>hive.metastore.uris</name>
        <value>thrift://master:9083</value>
        <description>thrift URI for the remote metastore.Used by metastore client to connect to remote metastore. </description>
    </property>
</configuration>

用sparksql操作hive实际上是把hive 当做数据仓库。数据仓库肯定有元数据和数据本身。要访问真正的数据就要访问他的元数据。所以只需要配置hive.metastore.uris 即可。(不需在每台机器上配置)

2,启动集群
(1). 启动dfs 服务 start-dfs.sh
//>metastore.log 2>& 1& 此造作为了增加日志信息
(2) 启动hive 数据仓库服务 hive –service metastore >metastore.log 2>& 1&
(3) 启动spark服务 start-all.sh
(4)启动sparkshell ./spark-shell –master spark://master:7077
,
3,案例实战
1. Spark on hive 实战 在spark-shell 模式下
Val hiveContext= new org.apache.spark.sql.hive.HiveContext(sc)
hiveContext.sql(“use hive”) //使用hive 数据库
hiveContext.sql(“show tables”).collect.foreach(println) // 查询数据库中的表
//此处操作的数据来自于搜狗实验室
hiveContext.sql(“select count(*) from sogouq1”).collect.foreach(println)(注意此时使用的是spark的引擎)
hiveContext.sql(“select count(*) from sogouq2 where website like ‘%baidu%’”).collect.foreach(println)

hiveContext.sql(“select count(*) from sogouq2 where s_seq=1 and c_seq=1 and website like ‘%baidu%’”).collect.foreach(println)

4, 不基于hive 的实战代码,在spark-shell 模式下

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

(可以创建很多hiveContext,hivecongtext连接的是数据仓库,程序本身(spark中的job),job在程序中并行运行,如果都hive的数据,如果用句柄,对句柄的占用比较麻烦,所有用多个实例。从查询的角度来说,有多个实例也很正常)

val  df=sqlcontext.read.json(“library/examples/src/main/resources/people.json”) //读取json 数据
df.show()
df.printSchema
df.select(“name”).show()
df.select(df(“name”),df(“age”)+1).show()

### Spark SQLDataFrame 的关系及使用方法 #### 关系分析 Spark SQL 是 Apache Spark 中的一个模块,用于处理结构化数据。它提供了一个编程抽象称为 DataFrame,并作为分布式 SQL 查询引擎的作用[^1]。DataFrame 是一种以表格形式存储的数据结构,类似于传统数据库中的表或者 Pandas 中的 DataFrame。然而,Spark DataFrame 是分布式的,能够在大规模集群上进行高效的并行计算。 Spark SQL 提供了两种主要的方式来操作数据:一是通过 DataFrame API 进行编程式操作;二是通过标准的 SQL 查询语言来进行声明式操作[^2]。这两种方式最终都会被 Catalyst 优化器编译成底层的 RDD 操作,从而保证性能最优。 --- #### 使用方法对比 ##### 1. **DataFrame API** 通过 DataFrame API 可以编写更加灵活和强大的代码逻辑。以下是其特点: - 支持链式调用,便于构建复杂的 ETL 流程。 - 自动利用 Catalyst 优化器对查询计划进行优化。 - 数据不可变且延迟执行,适合批处理场景。 下面是一个简单的例子展示了如何使用 DataFrame API 来完成 WordCount: ```python from pyspark.sql import SparkSession from pyspark.sql.functions import col, split, explode if __name__ == "__main__": spark = SparkSession.builder \ .appName("WordCount") \ .master("local[*]") \ .getOrCreate() # 加载文本文件到 DataFrame df = spark.read.text("/path/to/input/file") # 将每行拆分为单词列表 words_df = df.select(explode(split(col("value"), "\\s+")).alias("word")) # 对每个单词计数 result_df = words_df.groupBy("word").count().orderBy(col("count").desc()) # 展示结果 result_df.show(truncate=False) spark.stop() ``` 此代码片段说明了如何通过 DataFrame API 实现分词、聚合以及排序功能[^4]。 --- ##### 2. **SQL 风格** 对于熟悉 SQL 的用户来说,可以直接注册临时视图并通过 SQL 查询来获取所需的结果。这种方式的优点在于语法简单直观,易于维护。 继续以上述 WordCount 为例,可以改写为如下 SQL 形式: ```python from pyspark.sql import SparkSession if __name__ == "__main__": spark = SparkSession.builder \ .appName("WordCount_SQL") \ .master("local[*]") \ .getOrCreate() # 加载文本文件到 DataFrame 并创建临时视图 df = spark.read.text("/path/to/input/file") df.createOrReplaceTempView("lines") # 执行 SQL 查询统计单词频率 word_count_df = spark.sql(""" SELECT word, COUNT(*) AS count FROM ( SELECT EXPLODE(SPLIT(value, '\\s+')) AS word FROM lines ) GROUP BY word ORDER BY count DESC """) # 显示前几条记录 word_count_df.show(truncate=False) spark.stop() ``` 上述代码同样实现了基于 SQL 的 WordCount 功能[^5]。 --- #### 联系与区别 | 特性 | DataFrame API | SQL 风格 | |---------------------|---------------------------------------|---------------------------------------| | 编程模型 | 基于 Python 或 Scala 的函数式编程 | 类似传统的 SQL 查询 | | 学习曲线 | 较陡峭 | 如果已有 SQL 基础,则较为平缓 | | 性能 | 同样由 Catalyst 优化 | 同样由 Catalyst 优化 | | 灵活性 | 更加灵活,适用于复杂业务逻辑 | 主要针对固定模式的查询需求 | 两者的核心差异体现在表达方式的不同:前者更适合开发者习惯,而后者则更贴近分析师的需求[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值