[TOC]html
这里说的Spark Thrift JDBCServer并非网上大部分写到的Spark数据结果落地到RDB数据库中所使用的JDBC方式,而是指Spark启动一个名为thriftserver的进程以供客户端提供JDBC链接,进而使用SQL语句进行查询分析。java
http://spark.apache.org/docs/2.3.3/sql-programming-guide.html#running-the-thrift-jdbcodbc-servermysql
后面的文章分析中,我会先说明一个基本的演进过程,即为何会使用到Spark Thrift JDBCServer,其在大数据生态栈中大体是处于一个什么样的位置?我想理解了这些以后,使用Spark Thrift JDBCServer会显得更加“天然”。不过若是读者自己已经经历过MapReduce、Hive、Spark On Yarn、Spark On Yarn With Hive、Spark SQL等的一些使用历程,相信只要看过官方文档的介绍,应该就能知道其定位以及出现的缘由。所以这部分其实是介绍一些相关大数据组件的做用以及演进,经过这些介绍来理解Spark Thrift JDBCServer所处在的位置。web
在实际工做场景中,可能这些环境都不是你本身搭建的,可能你只是须要去链接Spark Thrift JDBCServer以使用Spark SQL的分析能力,或者基于Spark Thrift JDBCServer开发一些服务中间件,但仍然能够肯定的是,你仍是须要掌握其原理,而且热切但愿能本身搭个简单的环境体验一下。我会在已经搭建的Hadoop伪分布式环境下,大体说明如何应用Spark Thrift JDBCServer,以及有哪些注意事项。sql
文章多数是按照我的的理解进行说明,若有相关错误,还望批评指正。shell
大数据产品或大数据平台,无论底层的技术使用多么复杂,其最终都是但愿产品交到用户手中,可以快速简单地使用起来进行大数据分析,尽快和尽量地处理大量数据,以更好地挖掘数据的价值。而进行数据分析最好用的工具或语言之一显然就是SQL了,所以大多数据大数据产品、框架或技术,通常都会提供SQL接口。放眼来看如今的比较主流的大数据框架,也是如此,好比有Hive、Spark SQL、Elasticsearch SQL、Druid SQL等。数据库
这里会简要介绍apache
MapReduce是Hadoop的分布式计算框架,结合Hadoop的分布式存储HDFS,使得大规模的批量数据处理成为可能。经过MapReduce提供的简单接口,用户能够在不了解其底层的状况下,快速构建分布式应用程序,大大提升了开发分布式数据处理程序的效率。编程
但因为MapReduce在数据处理过程当中,中间生成结果都是存放在磁盘,所以其处理速度很慢,尽管如此,对于大规模的离线数据处理,MapReduce仍然会是一个不错的选择。json
尽管基于MapReduce提供的接口开发分布式程序已经比较简单了,但因为仍然须要进行编码,这对于一些历来没有接触过编程的数据分析人员或运维人员,其仍是会有很多的学习成本。因而Hive便出现了。
Hive被称为SQL On Hadoop或者SQL On MapReduce,是一款创建在Hadoop之上的数据仓库的基础框架,简单理解,在Hive上,你能够像在RDB中同样,编写SQL语句来对你的数据进行分析,Hive的解释器会把SQL语句转换为MapRedcue做业,提交到Yarn上去运行,这样一来,只要会写SQL语句,你就能构建强大的MapReduce分布式应用程序。
Hive提供了一个命令行终端,在安装了Hive的机器上,配置好了元数据信息数据库和指定了Hadoop的配置文件以后输入hive命令,就能够进入到hive的交互式终端,接下来只要编写SQL语句便可,这跟传统RDB数据库提供的终端是相似的。
咱们知道传统的RDB数据库,好比MySQL,不只提供了交互式终端操做,也能够在编码在代码中去链接MySQL以进行操做,好比在Java中能够经过JDBC进行链接,毕竟在实际业务中,更多时候是使用其提供的编程接口,而不是仅仅是交互式终端。
Hive也是相似的。Hive除了提供前面的cli用户接口,还提供了jdbc的用户接口,可是若是须要使用该接口,则须要先启动hiveserver2服务,启动该服务后,能够经过hive提供的beeline继续以cli的方式操做hive(不过须要注意的是,此时是经过jdbc接口进行操做hive的),也能够经过手工编写java代码来进行操做。
经过hiverserver2,就能够经过Java JDBC进行链接,这样以实现更多更复杂的业务逻辑。
Spark也是一个分布式计算引擎,其将处理的数据抽象为RDD或Dataset保存到内存中,中间处理结果也保存到内存中,所以其速度比MapReduce要快10到100倍。
基于Spark提供的接口和各类算子,能够十分轻易地开发出功能强大的分布式数据处理程序。
使用Spark的基本功能时,也是须要使用代码进行操做的,为了更方便地使用Spark,其也提供了SQL相关接口——Spark SQL。
这彷佛跟Hive在MapReduce中提供的CLI功能很类似,不过与Hive不一样的在于,使用Spark SQL,仍然须要必定程序地使用代码进行相关表的建立和元数据设置,以后才能够继续使用SQL语句进行表的操做,这点使用过Spark SQL的同窗应该很清楚。而使用Hive时,直接编写SQL语句建立表、写入数据、分析数据便可,不须要额外的代码操做。
如何避免前面Spark SQL中的这种尴尬?Spark SQL的其中一个分支就是Spark on Hive,也就是使用Hive中HQL的解析、逻辑执行计划翻译、执行计划优化等逻辑,能够近似认为仅将物理执行计划从MR做业替换成了Spark做业。SparkSql整合hive就是获取hive表中的元数据信息,而后经过SparkSql来操做数据。
跟hiveserver2的做用同样,Spark Thrift JDBCServer是Spark的一个进程,启动以后就能够经过Java JDBC代码进行链接操做,该进程本质上是Spark的一个Application。
Spark Thrift JDBCServer自己也是能够和Hive整合使用。
Spark Thrift JDBCServer的使用是基于下面和个方面的考虑:
如今通常Spark应用程序会部署到Hadoop的Yarn上进行调度,虽然Spark自己也提供了standalone的部署模式。
而在使用Spark SQL时,由于大部分数据通常都是保存在HDFS上,而Hive自己就是操做HDFS上的数据,所以通常会将Spark SQL和Hive整合使用,即如2.6中所提到的,元数据信息是使用Hive表的,而真正处理数据时使用的计算引擎是Spark的。
当但愿经过Java JDBC的方式使用Spark SQL的能力时,就可使用Spark Thrift JDBCServer,而且其自己也是能够和Hive整合使用。
其使用很是简单,几乎不用作任何操做,这里使用spark-2.3.3-bin-hadoop2.6.tgz版本,下载连接以下:
https://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-2.3.3/spark-2.3.3-bin-hadoop2.6.tgz
这里使用国内的Apache镜像源,下载速度很是快!推荐你们使用:https://mirrors.tuna.tsinghua.edu.cn/apache/
将下载的安装包解压缩以后,直接启动:
$ cd sbin/ $ ./start-thriftserver.sh
默认侦听10000端口:
$ lsof -i:10000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 1414 yeyonghao 407u IPv6 0x3cb645c07427abbb 0t0 TCP *:ndmp (LISTEN)
前面说过了,其本质上是Spark的一个Application,所以能够看到这时4040端口也启动了:
$ lsof -i:4040 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 1414 yeyonghao 270u IPv6 0x3cb645c07427d3fb 0t0 TCP *:yo-main (LISTEN)
使用jps命令查看,能够看到有SparkSubmit进程:
$ jps 901 SecondaryNameNode 1445 Jps 806 DataNode 1414 SparkSubmit 729 NameNode 1132 NodeManager 1053 ResourceManager
我这里另外还启动了Hadoop的伪分布式环境。
不妨打开浏览器看一下4040端口的页面:
能够说是至关熟悉的页面了,注意右上角其名称为:Thrift JDBC/ODBC Server,启动Thriftserver,其本质上就是提交了Spark的一个Application!(若是有使用过Spark Shell的同窗也应该知道,Spark Shell也是Spark的一个Application)
那么如何进行链接操做呢?Spark提供了一个beeline链接工具。
$ cd bin/ $ ./beeline
而后链接上Thriftserver:
Beeline version 1.2.1.spark2 by Apache Hive beeline> !connect jdbc:hive2://localhost:10000 Connecting to jdbc:hive2://localhost:10000 Enter username for jdbc:hive2://localhost:10000: Enter password for jdbc:hive2://localhost:10000: 2019-07-13 15:58:40 INFO Utils:310 - Supplied authorities: localhost:10000 2019-07-13 15:58:40 INFO Utils:397 - Resolved authority: localhost:10000 2019-07-13 15:58:40 INFO HiveConnection:203 - Will try to open client transport with JDBC Uri: jdbc:hive2://localhost:10000 Connected to: Spark SQL (version 2.3.3) Driver: Hive JDBC (version 1.2.1.spark2) Transaction isolation: TRANSACTION_REPEATABLE_READ 0: jdbc:hive2://localhost:10000>
以后就能够进行各类SQL操做:
0: jdbc:hive2://localhost:10000> create table person 0: jdbc:hive2://localhost:10000> ( 0: jdbc:hive2://localhost:10000> id int, 0: jdbc:hive2://localhost:10000> name string 0: jdbc:hive2://localhost:10000> ); +---------+--+ | Result | +---------+--+ +---------+--+ No rows selected (1.116 seconds) 0: jdbc:hive2://localhost:10000> insert into person values(1,'xpleaf'); +---------+--+ | Result | +---------+--+ +---------+--+ No rows selected (1.664 seconds) 0: jdbc:hive2://localhost:10000> select * from person; +-----+---------+--+ | id | name | +-----+---------+--+ | 1 | xpleaf | +-----+---------+--+ 1 row selected (0.449 seconds)
这时再去前面说的4040页面看一下:
能够看到咱们的操做其实都是被转换为了Spark Application中的一个个Job进行操做。
既然其是一个JDBC服务,那么固然能够经过Java代码来进行操做。
建立一个Maven工程,添加下面的依赖:
<dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-jdbc</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-core</artifactId> <version>1.2.1</version> </dependency>
编写代码以下:
package cn.xpleaf.spark; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; /** * @author xpleaf * @date 2019/7/13 4:06 PM */ public class SampleSparkJdbcServer { public static void main(String[] args) throws Exception { Class.forName("org.apache.hive.jdbc.HiveDriver"); Connection connection = DriverManager.getConnection("jdbc:hive2://localhost:10000"); Statement statement = connection.createStatement(); String sql = "select * from person"; ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()) { int id = resultSet.getInt("id"); String name = resultSet.getString("name"); System.out.println(String.format("id: %s, name: %s", id, name)); } } }
启动后运行结果以下:
id: 1, name: xpleaf
前面的方式建立表和写入的数据,都是保存在内存中,所以只要thirfserver退出,数据就会丢失,因此为了持久化这些数据,后面咱们为与Hive进行整合。
整合Hive的一个明显好处是,咱们既能够借助了HDFS进行分布式存储,持久化咱们的数据,也能够借助Spark自己的快速计算能力以快速处理数据,而这中间,须要借助Hive来作“中间人”,本质上咱们是使用了Hive建立的各类元数据信息表。
安装Hive前须要先搭建Hadoop环境,这里不介绍Hadoop环境如何搭建,在个人机器上,已经搭建了一个Hadoop的伪分布式环境。
$ jps 901 SecondaryNameNode 1557 RemoteMavenServer 806 DataNode 729 NameNode 1834 Jps 1547 1132 NodeManager 1053 ResourceManager
实际上Hive安装的三个前提条件为:
JDK // Java环境 HADOOP // Hadoop环境 MySQL // 关系型数据库,持久化存储Hive的元数据信息
这里是假设这三个步骤都已经完成。
Hive的下载依然可使用前面介绍的国内Apache镜像源:
https://mirrors.tuna.tsinghua.edu.cn/apache/hive/hive-2.3.5/apache-hive-2.3.5-bin.tar.gz
即这里使用的版本为2.3.5。
下载完成后,解压缩到指定目录,而后再配置相关文件。
(1)配置hive-env.sh
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home export HADOOP_HOME=/Users/yeyonghao/app/hadoop export HIVE_HOME=/Users/yeyonghao/app2/hive
(2)配置hive-site.xml
<property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>root</value> </property> <property> <name>hive.querylog.location</name> <value>/Users/yeyonghao/app2/hive/tmp</value> </property> <property> <name>hive.exec.local.scratchdir</name> <value>/Users/yeyonghao/app2/hive/tmp</value> </property> <property> <name>hive.downloaded.resources.dir</name> <value>/Users/yeyonghao/app2/hive/tmp</value> </property>
(3)将mysql驱动拷贝到$HIVE_HOME/lib目录下
直接从maven中下载:
~/app2/hive/lib$ wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.39/mysql-connector-java-5.1.39.jar
(4)初始化Hive元数据库
~/app2/hive/bin$ ./schematool -initSchema -dbType mysql -userName root -passWord root
成功后能够在mysql中看到建立的hive数据库和相关表:
mysql> use hive; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +---------------------------+ | Tables_in_hive | +---------------------------+ | AUX_TABLE | | BUCKETING_COLS | | CDS | | COLUMNS_V2 | | COMPACTION_QUEUE | | COMPLETED_COMPACTIONS | | COMPLETED_TXN_COMPONENTS | | DATABASE_PARAMS | | DBS | | DB_PRIVS | | DELEGATION_TOKENS | | FUNCS | | FUNC_RU | | GLOBAL_PRIVS | | HIVE_LOCKS | | IDXS | | INDEX_PARAMS | | KEY_CONSTRAINTS | | MASTER_KEYS | | NEXT_COMPACTION_QUEUE_ID | | NEXT_LOCK_ID | | NEXT_TXN_ID | | NOTIFICATION_LOG | | NOTIFICATION_SEQUENCE | | NUCLEUS_TABLES | | PARTITIONS | | PARTITION_EVENTS | | PARTITION_KEYS | | PARTITION_KEY_VALS | | PARTITION_PARAMS | | PART_COL_PRIVS | | PART_COL_STATS | | PART_PRIVS | | ROLES | | ROLE_MAP | | SDS | | SD_PARAMS | | SEQUENCE_TABLE | | SERDES | | SERDE_PARAMS | | SKEWED_COL_NAMES | | SKEWED_COL_VALUE_LOC_MAP | | SKEWED_STRING_LIST | | SKEWED_STRING_LIST_VALUES | | SKEWED_VALUES | | SORT_COLS | | TABLE_PARAMS | | TAB_COL_STATS | | TBLS | | TBL_COL_PRIVS | | TBL_PRIVS | | TXNS | | TXN_COMPONENTS | | TYPES | | TYPE_FIELDS | | VERSION | | WRITE_SET | +---------------------------+ 57 rows in set (0.00 sec)
(5)Hive测试
启动Hive Cli:
~/app2/hive/bin$ ./hive
建立相关表并写入数据:
hive> show databases; OK default Time taken: 0.937 seconds, Fetched: 1 row(s) hive> show tables; OK Time taken: 0.059 seconds hive> create table person > ( > id int, > name string > ); OK Time taken: 0.284 seconds hive> insert into person values(1,'xpleaf'); ...省略提交MapReduce做业信息... MapReduce Jobs Launched: Stage-Stage-1: Map: 1 HDFS Read: 4089 HDFS Write: 79 SUCCESS Total MapReduce CPU Time Spent: 0 msec OK Time taken: 17.54 seconds hive> select * from person; OK 1 xpleaf Time taken: 0.105 seconds, Fetched: 1 row(s)
官方文档关于这部分的说明:
Configuration of Hive is done by placing your hive-site.xml
, core-site.xml
and hdfs-site.xml
files in conf/
.
其实也就是将Hive的配置文件hive-site.xml,Hadoop的配置文件core-site.xml和hdfs-site.xml放到Spark的配置目录下。
以后再启动Thirftserver:
~/app2/spark/sbin$ ./start-thriftserver.sh starting org.apache.spark.sql.hive.thriftserver.HiveThriftServer2, logging to /Users/yeyonghao/app2/spark/logs/spark-yeyonghao-org.apache.spark.sql.hive.thriftserver.HiveThriftServer2-1-yeyonghaodeMacBook-Pro.local.out
可是后面会看到其并无启动:
$ lsof -i:10000
查看启动日志,看到其报错信息以下:
980 Caused by: org.datanucleus.store.rdbms.connectionpool.DatastoreDriverNotFoundException: The specified datastore driver ("com.mysql.jdbc.Driver") was not found in the CLASSPATH. Please check your CLASS PATH specification, and the name of the driver. 981 at org.datanucleus.store.rdbms.connectionpool.AbstractConnectionPoolFactory.loadDriver(AbstractConnectionPoolFactory.java:58) 982 at org.datanucleus.store.rdbms.connectionpool.BoneCPConnectionPoolFactory.createConnectionPool(BoneCPConnectionPoolFactory.java:54) 983 at org.datanucleus.store.rdbms.ConnectionFactoryImpl.generateDataSources(ConnectionFactoryImpl.java:238) 984 ... 91 more
也就是找不到mysql驱动,能够将以前hive下的该驱动拷贝到spark的jars目录下:
cp ~/app2/hive/lib/mysql-connector-java-5.1.39.jar ~/app2/spark/jars/
而后再启动,看日志时发现其仍是报错:
Caused by: MetaException(message:Hive Schema version 1.2.0 does not match metastore's schema version 2.1.0 Metastore is not upgraded or corrupt)
缘由,看spark jars目录下提供的jar包:
~/app2/spark/jars$ ls hive-
hive-beeline-1.2.1.spark2.jar hive-cli-1.2.1.spark2.jar hive-exec-1.2.1.spark2.jar hive-jdbc-1.2.1.spark2.jar hive-metastore-1.2.1.spark2.jar显然都是hive 1.x的版本。
但我安装的Hive是2.x版本,在mysql中有一个VERSION表保存其版本为2.1.0。
参考:https://yq.aliyun.com/articles/624494
这里我在spark的hive-site.xml中关闭版本验证:
<property> <name>hive.metastore.schema.verification</name> <value>false</value> </property>
修改完成后能够看到成功启动的日志信息:
... 2019-07-13 17:16:47 INFO ContextHandler:781 - Started o.s.j.s.ServletContextHandler@1774c4e2{/sqlserver/session,null,AVAILABLE,@Spark} 2019-07-13 17:16:47 INFO ContextHandler:781 - Started o.s.j.s.ServletContextHandler@f0381f0{/sqlserver/session/json,null,AVAILABLE,@Spark} 2019-07-13 17:16:47 INFO ThriftCLIService:98 - Starting ThriftBinaryCLIService on port 10000 with 5...500 worker threads
看一下端口号:
~/app2/spark/sbin$ lsof -i:10000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 5122 yeyonghao 317u IPv6 0x3cb645c07a5bcbbb 0t0 TCP *:ndmp (LISTEN)
这里咱们启动beeline进行操做:
~/app2/spark/bin$ ./beeline Beeline version 1.2.1.spark2 by Apache Hive
以前咱们在Hive中建立了一张person表,若是跟Hive整合成功,那么这里也应该能够看到,由于共用的是同一个metastore,以下查看其中的数据:
beeline> !connect jdbc:hive2://localhost:10000 Connecting to jdbc:hive2://localhost:10000 Enter username for jdbc:hive2://localhost:10000: Enter password for jdbc:hive2://localhost:10000: 2019-07-13 17:20:02 INFO Utils:310 - Supplied authorities: localhost:10000 2019-07-13 17:20:02 INFO Utils:397 - Resolved authority: localhost:10000 2019-07-13 17:20:02 INFO HiveConnection:203 - Will try to open client transport with JDBC Uri: jdbc:hive2://localhost:10000 Connected to: Spark SQL (version 2.3.3) Driver: Hive JDBC (version 1.2.1.spark2) Transaction isolation: TRANSACTION_REPEATABLE_READ 0: jdbc:hive2://localhost:10000> show tables; +-----------+------------+--------------+--+ | database | tableName | isTemporary | +-----------+------------+--------------+--+ | default | person | false | +-----------+------------+--------------+--+ 1 row selected (0.611 seconds) 0: jdbc:hive2://localhost:10000> select * from person; +-----+---------+--+ | id | name | +-----+---------+--+ | 1 | xpleaf | +-----+---------+--+ 1 row selected (1.842 seconds)
能够看到,没有问题,再查看4040端口:
这里咱们再建立一张person2表:
0: jdbc:hive2://localhost:10000> create table person2 0: jdbc:hive2://localhost:10000> ( 0: jdbc:hive2://localhost:10000> id int, 0: jdbc:hive2://localhost:10000> name string 0: jdbc:hive2://localhost:10000> ); +---------+--+ | Result | +---------+--+ +---------+--+ No rows selected (0.548 seconds)
这时能够去保存元数据信息的mysql数据库中看一下,在tbls表中保存了咱们建立的数据表信息:
mysql> select * from tbls; +--------+-------------+-------+------------------+-----------+-----------+-------+----------+---------------+--------------------+--------------------+ | TBL_ID | CREATE_TIME | DB_ID | LAST_ACCESS_TIME | OWNER | RETENTION | SD_ID | TBL_NAME | TBL_TYPE | VIEW_EXPANDED_TEXT | VIEW_ORIGINAL_TEXT | +--------+-------------+-------+------------------+-----------+-----------+-------+----------+---------------+--------------------+--------------------+ | 1 | 1563008351 | 1 | 0 | yeyonghao | 0 | 1 | person | MANAGED_TABLE | NULL | NULL | | 6 | 1563009667 | 1 | 0 | yeyonghao | 0 | 6 | person2 | MANAGED_TABLE | NULL | NULL | +--------+-------------+-------+------------------+-----------+-----------+-------+----------+---------------+--------------------+--------------------+ 2 rows in set (0.00 sec)
能够看到已经有person2表的信息了,说明Thirftserver与Hive整合成功。
前面3.2其实已经整合了Hive,这里再跟Yarn作整合。
前面说了,Thirftserver本质上就是Spark的一个Application,所以,咱们也能够在启动Thirftserver时指定master为yarn,其实就是将Thirftserver这个Spark Application部署到Yarn上,让Yarn为其分配资源,调度其做业的执行。
官方文档关于这点说明以下:
his script accepts all bin/spark-submit command line options, plus a --hiveconf option to specify Hive properties. You may run ./sbin/start-thriftserver.sh --help for a complete list of all available options. By default, the server listens on localhost:10000. You may override this behaviour via either environment variables, i.e.: ……
也就是说saprk-submit脚本接收的参数,start-thriftserver.sh也能接收。
如今,使用下面的启动方式:
~/app2/spark/sbin$ ./start-thriftserver.sh --master yarn starting org.apache.spark.sql.hive.thriftserver.HiveThriftServer2, logging to /Users/yeyonghao/app2/spark/logs/spark-yeyonghao-org.apache.spark.sql.hive.thriftserver.HiveThriftServer2-1-yeyonghaodeMacBook-Pro.local.out failed to launch: nice -n 0 bash /Users/yeyonghao/app2/spark/bin/spark-submit --class org.apache.spark.sql.hive.thriftserver.HiveThriftServer2 --name Thrift JDBC/ODBC Server --master yarn Spark Command: /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/bin/java -cp /Users/yeyonghao/app2/spark/conf/:/Users/yeyonghao/app2/spark/jars/* -Xmx1g org.apache.spark.deploy.SparkSubmit --master yarn --class org.apache.spark.sql.hive.thriftserver.HiveThriftServer2 --name Thrift JDBC/ODBC Server spark-internal ======================================== Exception in thread "main" java.lang.Exception: When running with master 'yarn' either HADOOP_CONF_DIR or YARN_CONF_DIR must be set in the environment. at org.apache.spark.deploy.SparkSubmitArguments.validateSubmitArguments(SparkSubmitArguments.scala:288) at org.apache.spark.deploy.SparkSubmitArguments.validateArguments(SparkSubmitArguments.scala:248) at org.apache.spark.deploy.SparkSubmitArguments.<init>(SparkSubmitArguments.scala:120) at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:130) at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala) full log in /Users/yeyonghao/app2/spark/logs/spark-yeyonghao-org.apache.spark.sql.hive.thriftserver.HiveThriftServer2-1-yeyonghaodeMacBook-Pro.local.out
能够看到其报错信息,关键为:
When running with master 'yarn' either HADOOP_CONF_DIR or YARN_CONF_DIR must be set in the environment.
直接在spark-env.sh中添加:
HADOOP_CONF_DIR=/Users/yeyonghao/app/hadoop/etc/hadoop YARN_CONF_DIR=/Users/yeyonghao/app/hadoop/etc/hadoop
以后再启动就没有问题了,看日志能够知道,其本质上就是把Thirftserver做为Spark Application,而后提交到Yarn上去调度:
73 2019-07-13 17:35:22 INFO Client:54 - Application report for application_1563008220920_0002 (state: ACCEPTED) 74 2019-07-13 17:35:22 INFO Client:54 - 75 client token: N/A 76 diagnostics: N/A 77 ApplicationMaster host: N/A 78 ApplicationMaster RPC port: -1 79 queue: default 80 start time: 1563010521752 81 final status: UNDEFINED 82 tracking URL: http://192.168.1.2:8088/proxy/application_1563008220920_0002/ 83 user: yeyonghao 84 2019-07-13 17:35:23 INFO Client:54 - Application report for application_1563008220920_0002 (state: ACCEPTED) 85 2019-07-13 17:35:24 INFO Client:54 - Application report for application_1563008220920_0002 (state: ACCEPTED) 86 2019-07-13 17:35:25 INFO Client:54 - Application report for application_1563008220920_0002 (state: ACCEPTED) 87 2019-07-13 17:35:26 INFO Client:54 - Application report for application_1563008220920_0002 (state: ACCEPTED) 88 2019-07-13 17:35:27 INFO Client:54 - Application report for application_1563008220920_0002 (state: ACCEPTED) 89 2019-07-13 17:35:28 INFO YarnClientSchedulerBackend:54 - Add WebUI Filter. org.apache.hadoop.yarn.server.webproxy.amfilter.AmIpFilter, Map(PROXY_HOSTS -> 192.168.1.2, PROXY_URI_BASES -> http://192.1 68.1.2:8088/proxy/application_1563008220920_0002), /proxy/application_1563008220920_0002 90 2019-07-13 17:35:28 INFO JettyUtils:54 - Adding filter org.apache.hadoop.yarn.server.webproxy.amfilter.AmIpFilter to /jobs, /jobs/json, /jobs/job, /jobs/job/json, /stages, /stages/json, /stages/stag e, /stages/stage/json, /stages/pool, /stages/pool/json, /storage, /storage/json, /storage/rdd, /storage/rdd/json, /environment, /environment/json, /executors, /executors/json, /executors/threadDump, /executors/threadDump/json, /static, /, /api, /jobs/job/kill, /stages/stage/kill. 91 2019-07-13 17:35:28 INFO YarnSchedulerBackend$YarnSchedulerEndpoint:54 - ApplicationMaster registered as NettyRpcEndpointRef(spark-client://YarnAM) 92 2019-07-13 17:35:28 INFO Client:54 - Application report for application_1563008220920_0002 (state: RUNNING) 93 2019-07-13 17:35:28 INFO Client:54 - 94 client token: N/A 95 diagnostics: N/A 96 ApplicationMaster host: 192.168.1.2 97 ApplicationMaster RPC port: 0 98 queue: default 99 start time: 1563010521752 100 final status: UNDEFINED 101 tracking URL: http://192.168.1.2:8088/proxy/application_1563008220920_0002/ 102 user: yeyonghao 103 2019-07-13 17:35:28 INFO YarnClientSchedulerBackend:54 - Application application_1563008220920_0002 has started running.
能够查看8088端口,看一下这个Application的信息:
以后咱们链接Thirftserver以后,所执行的操做,在Spark中会被转换为相应的Job(注意是Spark Application的Job,其又可能包含多个Stage,而Stage又会包含多个Task,对这部分不了解的同窗能够先学习一下Spark Core相关内容),其资源调度都是由Yarn完成的。
这时若是访问原来的4040端口,会跳转到Yarn对该Application的监控,不过界面仍是熟悉的Spark UI,以下:
以后经过beeline或者JDBC链接操做时,能够看到这里有job的运行信息:
还能够看到session信息:
在生产环境中,可能更多会看到Spark SQL跟Hive的整合使用或3.3所提到的Spark Thirft JDBCServer On Yarn With Hive,无论哪种状况,其都是出于下面的核心目的进行考虑的:
而当考虑是否须要提供JDBC的方式进行链接时,则能够考虑使用Spark Thirft JDBCServer。
除了前面说起的,其实可使用SQL进行分析的大数据平台或者框架还有Storm SQL、Flink SQL,都是目前至关热门和流行的。
另外,还有Elasticsearch和Druid这些集数据存储和分析于一体的大数据框架,也是很是流行,一样支持SQL的查询。
根据笔者对Elasticsearch一直以来的使用和了解状况,虽然起初Elasticsearch是做为对标Solr的一个全文检索框架而诞生,但逐渐会发现随着版本的迭代更新,Elasticsearch加入了愈来愈多的数据分析算子,在6.0版本以后更是直接加入了SQL的数据分析查询能力,尽管目前该能力还相对薄弱,但随着时间的推移,Elasticsearch SQL也确定会变得更强大!