您好,登錄后才能下訂單哦!
[TOC]
這里說(shuō)的Spark Thrift JDBCServer并不是網(wǎng)上大部分寫(xiě)到的Spark數(shù)據(jù)結(jié)果落地到RDB數(shù)據(jù)庫(kù)中所使用的JDBC方式,而是指Spark啟動(dòng)一個(gè)名為thriftserver的進(jìn)程以供客戶端提供JDBC連接,進(jìn)而使用SQL語(yǔ)句進(jìn)行查詢分析。
http://spark.apache.org/docs/2.3.3/sql-programming-guide.html#running-the-thrift-jdbcodbc-server
后面的文章分析中,我會(huì)先說(shuō)明一個(gè)基本的演進(jìn)過(guò)程,即為什么會(huì)使用到Spark Thrift JDBCServer,其在大數(shù)據(jù)生態(tài)棧中大致是處于一個(gè)什么樣的位置?我想理解了這些之后,使用Spark Thrift JDBCServer會(huì)顯得更加“自然”。不過(guò)如果讀者本身已經(jīng)經(jīng)歷過(guò)MapReduce、Hive、Spark On Yarn、Spark On Yarn With Hive、Spark SQL等的一些使用歷程,相信只要看過(guò)官方文檔的介紹,應(yīng)該就能知道其定位以及出現(xiàn)的原因。因此這部分實(shí)際上是介紹一些相關(guān)大數(shù)據(jù)組件的作用以及演進(jìn),通過(guò)這些介紹來(lái)理解Spark Thrift JDBCServer所處在的位置。
在實(shí)際工作場(chǎng)景中,可能這些環(huán)境都不是你自己搭建的,可能你只是需要去連接Spark Thrift JDBCServer以使用Spark SQL的分析能力,或者基于Spark Thrift JDBCServer開(kāi)發(fā)一些服務(wù)中間件,但仍然可以確定的是,你還是需要掌握其原理,并且熱切希望能自己搭個(gè)簡(jiǎn)單的環(huán)境體驗(yàn)一下。我會(huì)在已經(jīng)搭建的Hadoop偽分布式環(huán)境下,大致說(shuō)明如何應(yīng)用Spark Thrift JDBCServer,以及有哪些注意事項(xiàng)。
文章多數(shù)是按照個(gè)人的理解進(jìn)行說(shuō)明,如有相關(guān)錯(cuò)誤,還望批評(píng)指正。
大數(shù)據(jù)產(chǎn)品或大數(shù)據(jù)平臺(tái),不管底層的技術(shù)使用多么復(fù)雜,其最終都是希望產(chǎn)品交到用戶手中,能夠快速簡(jiǎn)單地使用起來(lái)進(jìn)行大數(shù)據(jù)分析,盡快和盡可能地處理大量數(shù)據(jù),以更好地挖掘數(shù)據(jù)的價(jià)值。而進(jìn)行數(shù)據(jù)分析最好用的工具或語(yǔ)言之一顯然就是SQL了,因此大多數(shù)據(jù)大數(shù)據(jù)產(chǎn)品、框架或技術(shù),一般都會(huì)提供SQL接口。放眼來(lái)看現(xiàn)在的比較主流的大數(shù)據(jù)框架,也是如此,比如有Hive、Spark SQL、Elasticsearch SQL、Druid SQL等。
這里會(huì)簡(jiǎn)要介紹
MapReduce是Hadoop的分布式計(jì)算框架,結(jié)合Hadoop的分布式存儲(chǔ)HDFS,使得大規(guī)模的批量數(shù)據(jù)處理成為可能。通過(guò)MapReduce提供的簡(jiǎn)單接口,用戶可以在不了解其底層的情況下,快速構(gòu)建分布式應(yīng)用程序,大大提高了開(kāi)發(fā)分布式數(shù)據(jù)處理程序的效率。
但由于MapReduce在數(shù)據(jù)處理過(guò)程中,中間生成結(jié)果都是存放在磁盤(pán),因此其處理速度很慢,盡管如此,對(duì)于大規(guī)模的離線數(shù)據(jù)處理,MapReduce仍然會(huì)是一個(gè)不錯(cuò)的選擇。
盡管基于MapReduce提供的接口開(kāi)發(fā)分布式程序已經(jīng)比較簡(jiǎn)單了,但由于仍然需要進(jìn)行編碼,這對(duì)于一些從來(lái)沒(méi)有接觸過(guò)編程的數(shù)據(jù)分析人員或運(yùn)維人員,其還是會(huì)有不少的學(xué)習(xí)成本。于是Hive便出現(xiàn)了。
Hive被稱(chēng)為SQL On Hadoop或者SQL On MapReduce,是一款建立在Hadoop之上的數(shù)據(jù)倉(cāng)庫(kù)的基礎(chǔ)框架,簡(jiǎn)單理解,在Hive上,你可以像在RDB中一樣,編寫(xiě)SQL語(yǔ)句來(lái)對(duì)你的數(shù)據(jù)進(jìn)行分析,Hive的解釋器會(huì)把SQL語(yǔ)句轉(zhuǎn)換為MapRedcue作業(yè),提交到Y(jié)arn上去運(yùn)行,這樣一來(lái),只要會(huì)寫(xiě)SQL語(yǔ)句,你就能構(gòu)建強(qiáng)大的MapReduce分布式應(yīng)用程序。
Hive提供了一個(gè)命令行終端,在安裝了Hive的機(jī)器上,配置好了元數(shù)據(jù)信息數(shù)據(jù)庫(kù)和指定了Hadoop的配置文件之后輸入hive命令,就可以進(jìn)入到hive的交互式終端,接下來(lái)只要編寫(xiě)SQL語(yǔ)句即可,這跟傳統(tǒng)RDB數(shù)據(jù)庫(kù)提供的終端是類(lèi)似的。
我們知道傳統(tǒng)的RDB數(shù)據(jù)庫(kù),比如MySQL,不僅提供了交互式終端操作,也可以在編碼在代碼中去連接MySQL以進(jìn)行操作,比如在Java中可以通過(guò)JDBC進(jìn)行連接,畢竟在實(shí)際業(yè)務(wù)中,更多時(shí)候是使用其提供的編程接口,而不是僅僅是交互式終端。
Hive也是類(lèi)似的。Hive除了提供前面的cli用戶接口,還提供了jdbc的用戶接口,但是如果需要使用該接口,則需要先啟動(dòng)hiveserver2服務(wù),啟動(dòng)該服務(wù)后,可以通過(guò)hive提供的beeline繼續(xù)以cli的方式操作hive(不過(guò)需要注意的是,此時(shí)是通過(guò)jdbc接口進(jìn)行操作hive的),也可以通過(guò)手工編寫(xiě)java代碼來(lái)進(jìn)行操作。
通過(guò)hiverserver2,就可以通過(guò)Java JDBC進(jìn)行連接,這樣以實(shí)現(xiàn)更多更復(fù)雜的業(yè)務(wù)邏輯。
Spark也是一個(gè)分布式計(jì)算引擎,其將處理的數(shù)據(jù)抽象為RDD或Dataset保存到內(nèi)存中,中間處理結(jié)果也保存到內(nèi)存中,因此其速度比MapReduce要快10到100倍。
基于Spark提供的接口和各種算子,可以十分輕易地開(kāi)發(fā)出功能強(qiáng)大的分布式數(shù)據(jù)處理程序。
使用Spark的基本功能時(shí),也是需要使用代碼進(jìn)行操作的,為了更方便地使用Spark,其也提供了SQL相關(guān)接口——Spark SQL。
這似乎跟Hive在MapReduce中提供的CLI功能很相似,不過(guò)與Hive不同的在于,使用Spark SQL,仍然需要一定程序地使用代碼進(jìn)行相關(guān)表的創(chuàng)建和元數(shù)據(jù)設(shè)置,之后才可以繼續(xù)使用SQL語(yǔ)句進(jìn)行表的操作,這點(diǎn)使用過(guò)Spark SQL的同學(xué)應(yīng)該很清楚。而使用Hive時(shí),直接編寫(xiě)SQL語(yǔ)句創(chuàng)建表、寫(xiě)入數(shù)據(jù)、分析數(shù)據(jù)即可,不需要額外的代碼操作。
如何避免前面Spark SQL中的這種尷尬?Spark SQL的其中一個(gè)分支就是Spark on Hive,也就是使用Hive中HQL的解析、邏輯執(zhí)行計(jì)劃翻譯、執(zhí)行計(jì)劃優(yōu)化等邏輯,可以近似認(rèn)為僅將物理執(zhí)行計(jì)劃從MR作業(yè)替換成了Spark作業(yè)。SparkSql整合hive就是獲取hive表中的元數(shù)據(jù)信息,然后通過(guò)SparkSql來(lái)操作數(shù)據(jù)。
跟hiveserver2的作用一樣,Spark Thrift JDBCServer是Spark的一個(gè)進(jìn)程,啟動(dòng)之后就可以通過(guò)Java JDBC代碼進(jìn)行連接操作,該進(jìn)程本質(zhì)上是Spark的一個(gè)Application。
Spark Thrift JDBCServer本身也是可以和Hive整合使用。
Spark Thrift JDBCServer的使用是基于下面和個(gè)方面的考慮:
現(xiàn)在一般Spark應(yīng)用程序會(huì)部署到Hadoop的Yarn上進(jìn)行調(diào)度,雖然Spark本身也提供了standalone的部署模式。
而在使用Spark SQL時(shí),因?yàn)榇蟛糠謹(jǐn)?shù)據(jù)一般都是保存在HDFS上,而Hive本身就是操作HDFS上的數(shù)據(jù),因此一般會(huì)將Spark SQL和Hive整合使用,即如2.6中所提到的,元數(shù)據(jù)信息是使用Hive表的,而真正處理數(shù)據(jù)時(shí)使用的計(jì)算引擎是Spark的。
當(dāng)希望通過(guò)Java JDBC的方式使用Spark SQL的能力時(shí),就可以使用Spark Thrift JDBCServer,并且其本身也是可以和Hive整合使用。
其使用非常簡(jiǎn)單,幾乎不用做任何操作,這里使用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
這里使用國(guó)內(nèi)的Apache鏡像源,下載速度非???!推薦大家使用:https://mirrors.tuna.tsinghua.edu.cn/apache/
將下載的安裝包解壓縮之后,直接啟動(dòng):
$ cd sbin/
$ ./start-thriftserver.sh
默認(rèn)偵聽(tīng)10000端口:
$ lsof -i:10000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 1414 yeyonghao 407u IPv6 0x3cb645c07427abbb 0t0 TCP *:ndmp (LISTEN)
前面說(shuō)過(guò)了,其本質(zhì)上是Spark的一個(gè)Application,因此可以看到這時(shí)4040端口也啟動(dòng)了:
$ 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進(jìn)程:
$ jps
901 SecondaryNameNode
1445 Jps
806 DataNode
1414 SparkSubmit
729 NameNode
1132 NodeManager
1053 ResourceManager
我這里另外還啟動(dòng)了Hadoop的偽分布式環(huán)境。
不妨打開(kāi)瀏覽器看一下4040端口的頁(yè)面:
可以說(shuō)是相當(dāng)熟悉的頁(yè)面了,注意右上角其名稱(chēng)為:Thrift JDBC/ODBC Server,啟動(dòng)Thriftserver,其本質(zhì)上就是提交了Spark的一個(gè)Application?。ㄈ绻惺褂眠^(guò)Spark Shell的同學(xué)也應(yīng)該知道,Spark Shell也是Spark的一個(gè)Application)
那么如何進(jìn)行連接操作呢?Spark提供了一個(gè)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>
之后就可以進(jìn)行各種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)
這時(shí)再去前面說(shuō)的4040頁(yè)面看一下:
可以看到我們的操作其實(shí)都是被轉(zhuǎn)換為了Spark Application中的一個(gè)個(gè)Job進(jìn)行操作。
既然其是一個(gè)JDBC服務(wù),那么當(dāng)然可以通過(guò)Java代碼來(lái)進(jìn)行操作。
創(chuàng)建一個(gè)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>
編寫(xiě)代碼如下:
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));
}
}
}
啟動(dòng)后運(yùn)行結(jié)果如下:
id: 1, name: xpleaf
前面的方式創(chuàng)建表和寫(xiě)入的數(shù)據(jù),都是保存在內(nèi)存中,因此只要thirfserver退出,數(shù)據(jù)就會(huì)丟失,所以為了持久化這些數(shù)據(jù),后面我們?yōu)榕cHive進(jìn)行整合。
整合Hive的一個(gè)明顯好處是,我們既可以借助了HDFS進(jìn)行分布式存儲(chǔ),持久化我們的數(shù)據(jù),也可以借助Spark本身的快速計(jì)算能力以快速處理數(shù)據(jù),而這中間,需要借助Hive來(lái)做“中間人”,本質(zhì)上我們是使用了Hive創(chuàng)建的各種元數(shù)據(jù)信息表。
安裝Hive前需要先搭建Hadoop環(huán)境,這里不介紹Hadoop環(huán)境如何搭建,在我的機(jī)器上,已經(jīng)搭建了一個(gè)Hadoop的偽分布式環(huán)境。
$ jps
901 SecondaryNameNode
1557 RemoteMavenServer
806 DataNode
729 NameNode
1834 Jps
1547
1132 NodeManager
1053 ResourceManager
實(shí)際上Hive安裝的三個(gè)前提條件為:
JDK // Java環(huán)境
HADOOP // Hadoop環(huán)境
MySQL // 關(guān)系型數(shù)據(jù)庫(kù),持久化存儲(chǔ)Hive的元數(shù)據(jù)信息
這里是假設(shè)這三個(gè)步驟都已經(jīng)完成。
Hive的下載依然可以使用前面介紹的國(guó)內(nèi)Apache鏡像源:
https://mirrors.tuna.tsinghua.edu.cn/apache/hive/hive-2.3.5/apache-hive-2.3.5-bin.tar.gz
即這里使用的版本為2.3.5。
下載完成后,解壓縮到指定目錄,然后再配置相關(guān)文件。
(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驅(qū)動(dòng)拷貝到$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元數(shù)據(jù)庫(kù)
~/app2/hive/bin$ ./schematool -initSchema -dbType mysql -userName root -passWord root
成功后可以在mysql中看到創(chuàng)建的hive數(shù)據(jù)庫(kù)和相關(guān)表:
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測(cè)試
啟動(dòng)Hive Cli:
~/app2/hive/bin$ ./hive
創(chuàng)建相關(guān)表并寫(xiě)入數(shù)據(jù):
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作業(yè)信息...
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)
官方文檔關(guān)于這部分的說(shuō)明:
Configuration of Hive is done by placing your hive-site.xml
, core-site.xml
and hdfs-site.xml
files in conf/
.
其實(shí)也就是將Hive的配置文件hive-site.xml,Hadoop的配置文件core-site.xml和hdfs-site.xml放到Spark的配置目錄下。
之后再啟動(dòng)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
但是后面會(huì)看到其并沒(méi)有啟動(dòng):
$ lsof -i:10000
查看啟動(dòng)日志,看到其報(bào)錯(cuò)信息如下:
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驅(qū)動(dòng),可以將之前hive下的該驅(qū)動(dòng)拷貝到spark的jars目錄下:
cp ~/app2/hive/lib/mysql-connector-java-5.1.39.jar ~/app2/spark/jars/
然后再啟動(dòng),看日志時(shí)發(fā)現(xiàn)其還是報(bào)錯(cuò):
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中有一個(gè)VERSION表保存其版本為2.1.0。
參考:https://yq.aliyun.com/articles/624494
這里我在spark的hive-site.xml中關(guān)閉版本驗(yàn)證:
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
修改完成后可以看到成功啟動(dòng)的日志信息:
...
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
看一下端口號(hào):
~/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)
這里我們啟動(dòng)beeline進(jìn)行操作:
~/app2/spark/bin$ ./beeline
Beeline version 1.2.1.spark2 by Apache Hive
之前我們?cè)贖ive中創(chuàng)建了一張person表,如果跟Hive整合成功,那么這里也應(yīng)該可以看到,因?yàn)楣灿玫氖峭粋€(gè)metastore,如下查看其中的數(shù)據(jù):
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)
可以看到,沒(méi)有問(wèn)題,再查看4040端口:
這里我們?cè)賱?chuàng)建一張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)
這時(shí)可以去保存元數(shù)據(jù)信息的mysql數(shù)據(jù)庫(kù)中看一下,在tbls表中保存了我們創(chuàng)建的數(shù)據(jù)表信息:
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)
可以看到已經(jīng)有person2表的信息了,說(shuō)明Thirftserver與Hive整合成功。
前面3.2其實(shí)已經(jīng)整合了Hive,這里再跟Yarn做整合。
前面說(shuō)了,Thirftserver本質(zhì)上就是Spark的一個(gè)Application,因此,我們也可以在啟動(dòng)Thirftserver時(shí)指定master為yarn,其實(shí)就是將Thirftserver這個(gè)Spark Application部署到Y(jié)arn上,讓Yarn為其分配資源,調(diào)度其作業(yè)的執(zhí)行。
官方文檔關(guān)于這點(diǎn)說(shuō)明如下:
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.:
……
也就是說(shuō)saprk-submit腳本接收的參數(shù),start-thriftserver.sh也能接收。
現(xiàn)在,使用下面的啟動(dòng)方式:
~/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
可以看到其報(bào)錯(cuò)信息,關(guān)鍵為:
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
之后再啟動(dòng)就沒(méi)有問(wèn)題了,看日志可以知道,其本質(zhì)上就是把Thirftserver作為Spark Application,然后提交到Y(jié)arn上去調(diào)度:
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端口,看一下這個(gè)Application的信息:
之后我們連接Thirftserver之后,所執(zhí)行的操作,在Spark中會(huì)被轉(zhuǎn)換為相應(yīng)的Job(注意是Spark Application的Job,其又可能包含多個(gè)Stage,而Stage又會(huì)包含多個(gè)Task,對(duì)這部分不了解的同學(xué)可以先學(xué)習(xí)一下Spark Core相關(guān)內(nèi)容),其資源調(diào)度都是由Yarn完成的。
這時(shí)如果訪問(wèn)原來(lái)的4040端口,會(huì)跳轉(zhuǎn)到Y(jié)arn對(duì)該Application的監(jiān)控,不過(guò)界面還是熟悉的Spark UI,如下:
之后通過(guò)beeline或者JDBC連接操作時(shí),可以看到這里有job的運(yùn)行信息:
還可以看到session信息:
在生產(chǎn)環(huán)境中,可能更多會(huì)看到Spark SQL跟Hive的整合使用或3.3所提到的Spark Thirft JDBCServer On Yarn With Hive,不管哪一種情況,其都是出于下面的核心目的進(jìn)行考慮的:
而當(dāng)考慮是否需要提供JDBC的方式進(jìn)行連接時(shí),則可以考慮使用Spark Thirft JDBCServer。
除了前面提及的,其實(shí)可以使用SQL進(jìn)行分析的大數(shù)據(jù)平臺(tái)或者框架還有Storm SQL、Flink SQL,都是目前相當(dāng)熱門(mén)和流行的。
另外,還有Elasticsearch和Druid這些集數(shù)據(jù)存儲(chǔ)和分析于一體的大數(shù)據(jù)框架,也是非常流行,同樣支持SQL的查詢。
根據(jù)筆者對(duì)Elasticsearch一直以來(lái)的使用和了解情況,雖然起初Elasticsearch是作為對(duì)標(biāo)Solr的一個(gè)全文檢索框架而誕生,但逐漸會(huì)發(fā)現(xiàn)隨著版本的迭代更新,Elasticsearch加入了越來(lái)越多的數(shù)據(jù)分析算子,在6.0版本之后更是直接加入了SQL的數(shù)據(jù)分析查詢能力,盡管目前該能力還相對(duì)薄弱,但隨著時(shí)間的推移,Elasticsearch SQL也肯定會(huì)變得更強(qiáng)大!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。