常见的SQL On Hadoop框架
- hive(非常重要):最原始的on hadoop的方案,由facebook贡献;将sql转化为底层MR/Tez/Spark作业;hive的metastore存储了表和库的所有信息,而且他几乎是和所有 on hadoop的框架通用的,hive2.x.x版本速度上有了很大提升
- impala(生产上很少用):可以使用hive的metastore,它推荐的数据格式是parquet,故我们可以通过spark sql 将文本格式等数据转换为parquet格式
- presto(生产上很少用):facebook出产。DJ用的最多
- shark(淘汰):spark sql的前生,将spqrksql转换为RDD进行操作,已经舍弃
- drill(生产上很少用):可以用sql操作Habse、hdfs、s3、hive、等各种不同组件上的数据
- phoenix(重要):架构在Hbase之上的一种查询组件、(必选)可以用sql查询Hbase数据,也支持与spark、hive、kafka交互等,如引入phoenix-spark相关jar包后,spark可读取phoenix数据以及存储数据到phoenix上,可在github.com/apache/phoenix查看
- Spark SQL(极其重要):是spark的一个模块,用于出来结构化数据,它相较于RDD,底层自己会做一些优化。
- Hive、impala、prestore、spark sql 他们都是能共用一套MetaStore,故他们互相间的计算访问或迁移是非常简单的,没有任何壁垒
Spark SQL 简介
误区
- spark sql就是写sql!这个说法是非常片面的,它是通过sql、DataFrame、DataSet来处理结构化的数据
- hive on spark 就是spark sql!完全错误的观念,两个是完全不同的概念,完全不是同一个东西
spark sql的版本历史
- Shark:1.0之后被遗弃
- Spark SQL诞生版本:1.0
- spark SQL正式版本:1.3版本,此版本中推出了DataFrame,取代了原有的ShchemaRDD
- Spark SQL DataSet诞生:1.6版本,他更加的强约束
SQL
- spark sql 和hive的sql语法几乎没有区别,主要用于查询数据。而且生产上代码应多食用DF和DS的API避免直接使用SQL,因为一般做的是平台,是针对用户的web UI上的sql进行API封装,其次SQL不能让错误在编译时提前发现,sql写错了,也是申请到资源后Executor运行时报错,并不友好
SQL Combiner Hive(重要)
- 由于Spark SQL 与Hive可共用一套MetaStore,故Spark SQL 可通过Hive的MetaStore来访问操作hive上的数据(会Spark SQL 后Hive是真的可以被彻底放弃了)。
- 第一步:将hive-site.xml文件拷贝到Spark的conf目录下即可
- 第二步:将mysql的jdbc jar通过-jar以及-driver -class传给spark,注意虽然可cp jar到lib目录下,但是会使所有的作业生效,这样会影响别人不可取,可通过Spark UI查看相关的jars。
-
通过spark-shell脚本操作hive
[hadoop@hadoop001 lib]$ spark-shell --master local[2] --jars /home/hadoop/lib/mysql-connector-java.jar --driver-class-path /home/hadoop/lib/mysql-connector-java.jar 19/06/17 15:10:38 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable Setting default log level to "WARN". To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel). Spark context Web UI available at http://hadoop001:4040 Spark context available as 'sc' (master = local[2], app id = local-1560755459155). Spark session available as 'spark'. Welcome to ____ __ / __/__ ___ _____/ /__ _ / _ / _ `/ __/ '_/ /___/ .__/\_,_/_/ /_/\_ version 2.4.2 /_/ Using Scala version 2.11.12 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_161) Type in expressions to have them evaluated. Type :help for more information. scala> scala> spark.sql("show databases").show +------------+ |databaseName| +------------+ | default| | hadoop_g6| | ruoze_d6| +------------+
scala> spark.sql("use default").show()
++
||
++
++
scala> spark.sql("show tables").show()
+--------+-------------------+-----------+
|database| tableName|isTemporary|
+--------+-------------------+-----------+
| default| customer| false|
| default| dual| false|
| default| g6_access| false|
| default| g6_access_lzo| false|
| default|g6_access_lzo_split| false|
| default| g6_access_orc| false|
| default| g6_access_orc_none| false|
| default| g6_access_par| false|
| default| g6_access_par_zip| false|
| default| g6_access_rc| false|
| default| g6_access_seq| false|
| default| makedata_job| false|
| default| order| false|
| default| traffic_info| false|
| default| tv_info| false|
+--------+-------------------+-----------+
-
通过spark-sql脚本操作hive
[hadoop@hadoop001 bin]$ ./spark-sql --jars /home/hadoop/lib/mysql-connector-java.jar --driver-class-path /home/hadoop/lib/mysql-connector-java.jar
spark-sql (default)> show tables;
default customer false
default dual false
default g6_access false
default g6_access_lzo false
default g6_access_lzo_split false
default g6_access_orc false
default g6_access_orc_none false
default g6_access_par false
default g6_access_par_zip false
default g6_access_rc false
default g6_access_seq false
default makedata_job false
default order false
default traffic_info false
default tv_info false
Time taken: 13.567 seconds, Fetched 15 row(s)
-
通过Spark的beeline操作hive
[hadoop@hadoop001 sbin]$ /home/hadoop/app/spark-2.4.2-bin-2.6.0-cdh5.7.0/sbin/start-thriftserver.sh --jars /home/hadoop/lib/mysql-connector-java.jar --driver-class-path /home/hadoop/lib/mysql-connector-java.jar starting org.apache.spark.sql.hive.thriftserver.HiveThriftServer2, logging to /home/hadoop/app/spark-2.4.2-bin-2.6.0-cdh5.7.0/logs/spark-hadoop-org.apache.spark.sql.hive.thriftserver.HiveThriftServer2-1-hadoop001.out [hadoop@hadoop001 sbin]$ /home/hadoop/app/spark-2.4.2-bin-2.6.0-cdh5.7.0/bin/beeline -u jdbc:hive2://hadoop001:10000/default -
Connecting to jdbc:hive2://hadoop001:10000/default
19/06/17 15:27:31 INFO jdbc.Utils: Supplied authorities: hadoop001:10000
19/06/17 15:27:31 INFO jdbc.Utils: Resolved authority: hadoop001:10000
19/06/17 15:27:32 INFO jdbc.HiveConnection: Will try to open client transport with JDBC Uri: jdbc:hive2://hadoop001:10000/default
Connected to: Spark SQL (version 2.4.2)
Driver: Hive JDBC (version 1.2.1.spark2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
Beeline version 1.2.1.spark2 by Apache Hive
0: jdbc:hive2://hadoop001:10000/default> show tables;
+-----------+----------------------+--------------+--+
| database | tableName | isTemporary |
+-----------+----------------------+--------------+--+
| default | customer | false |
| default | dual | false |
| default | g6_access | false |
| default | g6_access_lzo | false |
| default | g6_access_lzo_split | false |
| default | g6_access_orc | false |
| default | g6_access_orc_none | false |
| default | g6_access_par | false |
| default | g6_access_par_zip | false |
| default | g6_access_rc | false |
| default | g6_access_seq | false |
| default | makedata_job | false |
| default | order | false |
| default | traffic_info | false |
| default | tv_info | false |
+-----------+----------------------+--------------+--+
15 rows selected (2.899 seconds)
0: jdbc:hive2://hadoop001:10000/default>
RDD and DataSet and DataFrame关系
- RDD很多高级函数操作(map、fileter、sort等)DataSet、DataFrame都会有
- RDD[T],spark并不知道T的具体结构,而DataSet、DataFrame,spark会了解其结构
- DataSet==RDD[Row]、DataFrame=RDD+Schema
- DataSet、DataFrame可直接转换为RDD
- DataSet可通过RDD[Row]货DF生成
- DataFrame可通过RDD[CaseClass]或者[Row]+Schema
-
SparkSession对象
SparkSession它是所有编程的入口,所有的context都可有通过它获取,创建方式如下:
val spark = SparkSession.builder().appName("XX").master("local[2]").config("XX","XX").getOrCreate() spark.stop()