开源社区在分布式计算框架基础上构建了支持SQL的引擎,典型的代表是MapReduce之上的Hive以及Spark之上的Spark SQL,这些数据分析引擎通常不支持标准SQL,而是对SQL进行了选择性支持,并进行了适当扩展,其中最主流的数据分析语言为HQL(Hive Query Language)。
目前构建在Hadoop之上的SQL引擎主要分为两类,基于计算引擎和基于MPP架构:
Hive是构建在分布式计算框架之上的SQL引擎,使用了Hadoop中的分布式存储系统HDFS/HBase和分布式计算框架MapReduce/Tez/Spark等。Hive是Hadoop生态系统中的重要部分,目前是应用最广泛的SQL On Hadoop解决方案。
Hive对外提供了三种访问方式,包括Web UI、CLI(Client Line Interface)和Thrift协议(支持JDBC/ODBC),而在Hive后端,主要由三个服务组件构成。
Hive最初是构建在MapReduce计算引擎之上的,Hive逐步支持其他更高效的DAG计算引擎,包括Tez、Spark等,用户可个性化指定每个HQL的执行引擎。
相比于MapReduce计算引擎,新型DAG计算引擎采用以下优化机制让HQL具有更高的执行性能:
Spark SQL是构建在分布式计算框架Spark之上的结构化数据处理引擎,不仅支持类HQL查询语言,也提供了一套结构化编程接口DataFrame/DataSet。Spark SQL是一个异构化数据处理引擎,支持多种数据源,包括HDFS(各种文件格式)、Hive、关系型数据库等,用户可以使用Spark SQL提供的类HQL语言和结构化编程结构处理这些数据源中的数据。
Spark SQL基本架构主要由四层构成:
(1)用户接口层
Spark SQL提供了两套访问接口:
(2) SQL引擎层:将查询语言翻译成最高效的分布式Spark程序
Spark SQL引擎层主要职责是将HQL或DataFrame/DataSet程序编译成可分布式运行的Spark程序,涉及生成逻辑计划、物理计划、查询优化与执行等。最重要的组件是查询优化器catalyst,确保生成最优化的分布式程序。
(3) 计算引擎层:Spark Core
SQL引擎层的输入是HQL或DataFrame/DataSet程序,而输出则是基于RDD模型的Sprk分布式计算程序,这些程序会直接运行在Spark计算引擎层。
(4) 存储层:支持各种数据源,包括HDFS、Hive、关系型数据库、HBase等
Spark SQL另一个强大之处是对数据源进行了抽象,内置了大量存储引擎的支持,包括HDFS(支持各种数据存储格式,包括行存储格式Text和Sequence File,列式存储格式Parquet和ORC等)、Hive、各种关系数据库等,用户也可以根据需要将特定数据存储引擎接入Spark SQL,进而利用其强大而灵活的引擎进行数据分析。
Spark SQL与Hive均支持类SQL语言,能够很方便地处理海量数据,也有明显的区别。
Spark SQL与Hive对比如下表所示:
Spark SQL | Hive | |
---|---|---|
Spark SQL | Hive | |
查询语言 | 类HQL与DataFrame/DataSet API | HQL |
元信息存储 | Hive Metastore(如果处理的数据来自三方存储引擎,比如MySQL,则由对应引擎自己负责元信息存储) | Hive Metastore |
查询引擎 | 将查询语言翻译成最高效的分布式Spark程序 | 将HQL翻译成对应的分布式程序 |
分布式计算引擎 | Spark Core | MapReduce、Tez或Spark |
分布式存储引擎 | 支持各种数据源,包括HDFS、Hive、关系型数据库、HBase等 | 主要是HDFS和HBase |
Hive数据表是多层级的,Hive中可以有多个数据库,每个数据库中可以存在多个数据表,每个数据表可进一步划分为多个分区或者数据桶,每个分区内部也可以有多个数据桶。
Create [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
[(col_name data_type [COMMENT col_comment],...)]
[PARTITIONED BY (col_name data_type [COMMENT col_comment],...)]
[CLUSTERED BY (col_name,col_name,...) INTO num_buckets BUCKETS]
[
[ROW FORMAT row_format]
[STORED AS file_format]
]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value,...)]
[AS select_statement];
按照数据表语法定义顺序,依次解析各个关键字的含义:
1)数据表的类别。Hive数据表分为三类:临时表(TEMPORARY TABLE)、外部表(EXTERNAL TABLE)和受管理表(MANAGED TABLE),其区别如下:
2)数据类型(data_type)。Hive提供了丰富的数据类型,不仅提供类似于关系型数据库中的基本数据类型,也提供了对高级数据类型(包括数据、映射表、结构体和联合体)。的支持,具体包括:
3)分区表与分桶表。为了加速数据处理,数据表可进一步划分成更小的存储单位,即分区或分桶。
4)行格式(row format)。该配置用于指定每行的数据格式,对行格式存储格式有意义,语法定义如下:
DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char] [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]
关键字含义如下:
实例:创建一个名为person的数据表,由name(姓名)和score(课程成绩)两个字段构成,其中score数据类型为map,key为课程名,value是得分。
CREATE TABLE person(name STRING,score map<STRING,INT>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ','
MAP KEYS TERMINATED BY ':';
对应的数据存储格式为:
Tom 'Math':80,'Chinese':89,'English':95
Bob 'Chinese':60,'Math':80,'English':99
5)数据格式(file format)。Hive支持多种数据格式,包括:
6)数据存放位置(HDFS path)。每个数据表对应的数据将被存在一个单独目录中,具体由配置参数hive.metastore.warehouse.dir指定,默认是/user/hive/warehouse/databasename.db/tablename/,比如数据库school中的表student存放路径则为:/user/hive/warehouse/school.db/student/中。
7)表属性。Hive允许用户为数据表增加任意表属性,每个表属性以key/value的形式存在,Hive也预定义了一些表属性,比如:
Hive提供了两种删除数据表的语法:
DROP TABLE [IF EXISTS] table_name[PURGE];
删除指定数据表的数据和元信息,其中数据将被移动到垃圾箱,除非设置了"PURGE"标志,则跳过垃圾箱直接永久清除。如果数据表是外表,则仅会清理元信息。
TRUNCATE TABLE table_name [PARTITION partition_spec];
删除指定数据表的全部数据或某个分区,默认情况下,删除的数据将被移动到垃圾箱。
HQL数据查询语句的语法与标准SQL非常类似,具体如下:
[WITH CommonTableExpression (,CommonTableExpression)*]
SELECT [ALL | DISTINCT] select_expr,select_expr,...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list]
[ORDER BY col_list]
[CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list]]
[LIMIT number]
1) WITH CommonTableExpression (,CommonTableExpression):Hive提供了一种将子查询作为一个数据表的语法,叫做Common Table Expression(CTE),比如从表t中选出两种类型的数据,并合并在一起作为输出:
with t1 as (select * from t where key='5'),
t2 as (select * from t where key = '4')
select * from t1 union all select * from t2;
2) ORDER BY和CLUSTER BY:DISTRIBUTE BY语句能按照指定的字段或表达式对数据进行划分,输出到对应的Reduce Task或者文件中。CLUSTER BY等价于DISTRIBUTE BY与SORT BY组合。如下两条HQL语句等级:
SELECT col1,col2 FROM t1 CLUSTER BY coll
SELECT col1,col2 FROM t1 DISTRIBUTE BY coll SORT BY coll
实例:当数据量特别大,需要对最终结果进行排序时,建议采用DISTRIBUTE BY结合SORT BY语句,比如统计每个url对应的用户行为日志,并按照访问时间对结果排序,如果采用DISTRIBUTE B + SORT BY方式,HQL语句如下:
set mapreduce.job.reduces=2
select url_id,log_time,log_type FROM behavior DISTRIBUTE BY url_id SORT BY user_id,log_time;