[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也確定會變得更強大!