本文转自博客园,作者ID「netoxi」
http://www.cnblogs.com/netoxi/p/7223413.html
Spark SQL是Spark的结构化数据处理模块,特点如下:
-
数据兼容:可从Hive表、外部数据库(JDBC)、RDD、Parquet文件、JSON文件获取数据,可通过Scala方法或SQL方式操作这些数据,并把结果转回RDD。
-
组件扩展:SQL语法解析器、分析器、优化器均可重新定义。
-
性能优化:内存列存储、动态字节码生成等优化技术,内存缓存数据。
-
多语言支持:Scala、Java、Python、R。
原理
组成
-
Catalyst优化:优化处理查询语句的整个过程,包括解析、绑定、优化、物理计划等,主要由关系代数(relation algebra)、表达式(expression)以及查询优化(query optimization)组成。
-
Spark SQL内核:处理数据的输入输出,从不同数据源(结构化数据Parquet文件JSON文件、Hive表、外部数据库、已有RDD)获取数据,执行查询(expression of queries),并将查询结果输出成DataFrame。
-
Hive支持:对Hive数据的处理,主要包括HiveQL、MetaStore、SerDes、UDFs等。
执行流程
-
SqlParser对SQL语句解析,生成Unresolved逻辑计划(未提取Schema信息);
-
Catalyst分析器结合数据字典(catalog)进行绑定,生成Analyzed逻辑计划,过程中Schema Catalog要提取Schema信息;
-
Catalyst优化器对Analyzed逻辑计划优化,按照优化规则得到Optimized逻辑计划;
-
与Spark Planner交互,应用策略(strategy)到plan,使用Spark Planner将逻辑计划转换成物理计划,然后调用next函数,生成可执行物理计划。
性能
-
内存列式缓存:内存列式(in-memory columnar format)缓存(再次执行时无需重复读取),仅扫描需要的列,并自动调整压缩比使内存使用率和GC压力最小化。
-
动态代码和字节码生成技术:提升重复表达式求值查询的速率。
-
Tungsten优化:
-
由Spark自己管理内存而不是JVM,避免了JVM GC带来的性能损失。
-
内存中Java对象被存储成Spark自己的二进制格式,直接在二进制格式上计算,省去序列化和反序列化时间;此格式更紧凑,节省内存空间。
API
应用程序模板
通用读写方法
-
Spark SQL内置数据源短名称有json、parquet、jdbc,默认parquet(通过“spark.sql.sources.default”配置)。
-
保存模式:
-
读写文件代码(统一使用sqlContext.read和dataFrame.write)模板:
RDD转为DataFrame
1. 方法1
-
方法:使用反射机制推断RDD Schema。
-
场景:运行前知道Schema。
-
特点:代码简洁。
-
示例:
2. 方法2
-
方法:以编程方式定义RDD Schema。
-
场景:运行前不知道Schema。
-
示例:
Parquet文件数据源
-
Parquet优点:
-
高效、Parquet采用列式存储避免读入不需要的数据,具有极好的性能和GC;
-
方便的压缩和解压缩,并具有极好的压缩比例;
-
可直接读写Parquet文件,比磁盘更好的缓存效果。
-
Spark SQL支持根据Parquet文件自描述自动推断Schema,生成DataFrame。
-
编程示例:
-
分区发现(partition discovery)
-
与Hive分区表类似,通过分区列的值对表设置分区目录,加载Parquet数据源可自动发现和推断分区信息。
-
示例:有一个分区列为gender和country的分区表,加载路径“/path/to/table”可自动提取分区信息
-
创建的DataFrame的Schema:
-
分区列数据类型:支持numeric和string类型的自动推断,通过“spark.sql.sources.partitionColumnTypeInference.enabled”配置开启或关闭(默认开启),关闭后分区列全为string类型。
JSON文件数据源
-
Spark SQL支持根据JSON文件自描述自动推断Schema,生成DataFrame。
-
示例:
Hive数据源
-
HiveContext
-
操作Hive数据源须创建SQLContext的子类HiveContext对象。
-
Standalone集群:添加hive-site.xml到$SPARK_HOME/conf目录。
-
YARN集群:添加hive-site.xml到$YARN_CONF_DIR目录;添加Hive元数据库JDBC驱动jar文件到$HADOOP_HOME/lib目录。
-
最简单方法:通过spark-submit命令参数--file和--jar参数分别指定hive-site.xml和Hive元数据库JDBC驱动jar文件。
-
未找到hive-site.xml:当前目录下自动创建metastore_db和warehouse目录。
-
模板:
-
使用HiveQL
-
“spark.sql.dialect”配置:SQLContext仅sql,HiveContext支持sql、hiveql(默认)。
-
模板:
-
支持Hive特性
-
Hive查询语句,包括select、group by、order by、cluster by、sort by;
-
Hive运算符,包括:关系运算符(=、⇔、==、<>、<、>、>=、<=等)、算术运算符(+、-、*、/、%等)、逻辑运算符(and、&&、or、||等)、复杂类型构造函数、数据函数(sign、ln、cos等)、字符串函数(instr、length、printf);
-
用户自定义函数(UDF);
-
用户自定义聚合函数(UDAF);
-
用户自定义序列化格式(SerDes);
-
连接操作,包括join、{left | right | full} outer join、left semi join、cross join;
-
联合操作(union);
-
子查询:select col from (select a + b as col from t1) t2;
-
抽样(Sampling);
-
解释(Explain);
-
分区表(Partitioned table);
-
所有Hive DDL操作函数,包括create table、create table as select、alter table;
-
大多数Hive数据类型tinyint、smallint、int、bigint、boolean、float、double、string、binary、timestamp、date、array<>、map<>、struct<>。
数据库JDBC数据源
-
Spark SQL支持加载数据库表生成DataFrame。
-
模板(注意:需要相关JDBC驱动jar文件)
-
JDBC参数
DataFrame Operation
分类:
-
DataFrameAction
-
基础DataFrame函数(basic DataFrame functions)
-
集成语言查询(language integrated queries)
-
输出操作
-
RDD Operation
-
DataFrame本质是一个拥有多个分区的RDD,支持RDD Operation:coalesce、flatMap、foreach、foreachPartition、javaRDD、map、mapPartitions、repartition、toJSON、toJavaRDD等。
性能调优
缓存数据
-
内存列式(in-memory columnar format)缓存:Spark SQL仅扫描需要的列,并自动调整压缩比使内存使用率和GC压力最小化。
-
相关配置:
-
缓存/移除缓存代码模板:
参数调优
案例
数据准备
-
数据结构
-
职工基本信息(people)
-
部门基本信息(department)
-
职工考勤信息(attendance)
-
职工工资清单(salary)
-
建库、建表(spark-shell方式)
-
测试数据
-
职工基本信息(people.csv)
-
部门基本信息(department.csv)
-
职工考勤信息(attendance.csv)
-
职工工资清单(salary.csv)
-
上传数据文件至HDFS
查询部门职工数
-
HiveQL方式
-
Scala方式
-
结果
查询各部门职工工资总数,并排序
-
HiveQL方式
-
Scala方式
-
结果
查询各部门职工考勤信息
-
HiveQL方式
-
Scala方式
-
结果