1、背景
Hive是目前大數(shù)據(jù)領(lǐng)域,事實(shí)上的SQL標(biāo)準(zhǔn)。其底層默認(rèn)是基于MapReduce實(shí)現(xiàn)的,但是由于MapReduce速度實(shí)在比較慢,因此這幾年,陸續(xù)出來了新的SQL查詢引擎,包括Spark SQL,Hive On Tez,Hive On Spark等。
Spark SQL與Hive On Spark是不一樣的。Spark SQL是Spark自己研發(fā)出來的針對(duì)各種數(shù)據(jù)源,包括Hive、JSON、Parquet、JDBC、RDD等都可以執(zhí)行查詢的,一套基于Spark計(jì)算引擎的查詢引擎。因此它是Spark的一個(gè)項(xiàng)目,只不過提供了針對(duì)Hive執(zhí)行查詢的工功能而已,適合在一些使用Spark技術(shù)棧的大數(shù)據(jù)應(yīng)用類系統(tǒng)中使用。
而Hive On Spark,是Hive的一個(gè)項(xiàng)目,它是將Spark作為底層的查詢引擎(不通過MapReduce作為唯一的查詢引擎)。Hive On Spark,只適用于Hive,在可預(yù)見的未來,很有可能Hive默認(rèn)的底層引擎就從MapReduce切換為Spark了;適合于將原有的Hive數(shù)據(jù)倉庫以及數(shù)據(jù)統(tǒng)計(jì)分析替換為Spark引擎,作為全公司通用的大數(shù)據(jù)統(tǒng)計(jì)分析引擎。
Hive On Spark做了一些優(yōu)化:
1、Map Join
Spark SQL默認(rèn)對(duì)join是支持使用broadcast機(jī)制將小表廣播到各個(gè)節(jié)點(diǎn)上,以進(jìn)行join的。但是問題是,這會(huì)給Driver和Worker帶來很大的內(nèi)存開銷。因?yàn)閺V播的數(shù)據(jù)要一直保留在Driver內(nèi)存中。所以目前采取的是,類似乎MapReduce的Distributed Cache機(jī)制,即提高HDFS replica factor的復(fù)制因子,以讓數(shù)據(jù)在每個(gè)計(jì)算節(jié)點(diǎn)上都有一個(gè)備份,從而可以在本地進(jìn)行數(shù)據(jù)讀取。
2、Cache Table
對(duì)于某些需要對(duì)一張表執(zhí)行多次操作的場(chǎng)景,Hive On Spark內(nèi)部做了優(yōu)化,即將要多次操作的表cache到內(nèi)存中,以便于提升性能。但是這里要注意,并不是對(duì)所有的情況都會(huì)自動(dòng)進(jìn)行cache。所以說,Hive On Spark還有很多不完善的地方。
2、Hive的基本工作原理
Hive QL語句 =>
語法分析 => AST =>
生成邏輯執(zhí)行計(jì)劃 => Operator Tree =>
優(yōu)化邏輯執(zhí)行計(jì)劃 => Optimized Operator Tree =>
生成物理執(zhí)行計(jì)劃 => Task Tree =>
優(yōu)化物理執(zhí)行計(jì)劃 => Optimized Task Tree =>
執(zhí)行優(yōu)化后的Optimized Task Tree
3、Hive On Spark的計(jì)算原理
1、將Hive表作為Spark RDD來進(jìn)行操作;
2、使用Hive原語
對(duì)于一些針對(duì)RDD的操作,比如groupByKey、sortByKey等;不使用Spark的transformation操作和原語。如果那樣做的話,那么就需要重新實(shí)現(xiàn)一套Hive的原語,而且如果Hive增加了新功能,那么又要實(shí)現(xiàn)新的Spark原語。因此選擇將Hive的原語包裝為針對(duì)RDD的操作即可。3、新的物理執(zhí)行計(jì)劃生成機(jī)制
使用SparkCompiler將邏輯執(zhí)行計(jì)劃,即Operator Tree,轉(zhuǎn)換為Task Tree,提交Spark Task給Spark進(jìn)行執(zhí)行。SparkTask包裝了DAG,DAG包裝為SparkWork,SparkTask根據(jù)SparkWork表示的DAG計(jì)算。4、SparkContext生命周期
Hive On Spark會(huì)為每個(gè)用戶的會(huì)話,比如執(zhí)行一次SQL語句,創(chuàng)建一個(gè)SparkContext。但是Spark不允許在一個(gè)JVM內(nèi)創(chuàng)建多個(gè)SparkContext。因此,需要在單獨(dú)的JVM中啟動(dòng)每個(gè)會(huì)話的SparkContext,然后通過RPC與遠(yuǎn)程JVM中的SparkContext進(jìn)行通信。5、本地和遠(yuǎn)程運(yùn)行模式
Hive On Spark提供兩種運(yùn)行模式,本地和遠(yuǎn)程。如果將Spark Master設(shè)置為local,比如set spark.master=local,那么就是本地模式,SparkContext與客戶端運(yùn)行在一個(gè)JVM中。否則,如果將Spark Master設(shè)置為Master的地址,那么就是遠(yuǎn)程模式,SparkContext會(huì)在遠(yuǎn)程的JVM中啟動(dòng)。
遠(yuǎn)程模式下,每個(gè)用戶Session都會(huì)創(chuàng)建一個(gè)SparkClient,SparkClient啟動(dòng)RemoteDriver,RemoteDriver負(fù)責(zé)創(chuàng)建SparkContext。
4、Hive On Spark環(huán)境搭建
- 1、去官網(wǎng)下載apache-hive-1.2.1-bin.tar.gz
- 2、在/usr/local目錄下解壓縮
- 3、進(jìn)入conf目錄,mv hive-default.xml.template hive-site.xml,修改hive-site.xml
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop1:3306/hive_metadata_2?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>hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>hive</value>
</property>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse2</value>
</property>
- 4、在conf目錄下
mv hive-env.sh.template hive-env.sh
vi ./bin/hive-config.sh
export JAVA_HOME=/usr/java/latest
export HIVE_HOME=/usr/local/apache-hive-1.2.1-bin
export HADOOP_HOME=/usr/local/hadoop
- 5、添加mysql jar包
cp /usr/share/java/mysql-connector-java-5.1.17.jar /usr/local/apache-hive-1.2.1-bin/lib
- 6、MySQL建庫
create database if not exists hive_metadata_2;
grant all privileges on hive_metadata_2.* to 'hive'@'%' identified by 'hive';
grant all privileges on hive_metadata_2.* to 'hive'@'localhost' identified by 'hive';
grant all privileges on hive_metadata_2.* to 'hive'@'spark1' identified by 'hive';
flush privileges;
7、啟動(dòng)hive cli,./hive,
報(bào)錯(cuò),Relative path in absolute URI:%7Bsystem:user.name%7D
創(chuàng)建文件夾:
/home/grid/apache-hive-1.2.1-bin/iotmp
將hive-site.xml中所有的${system:java.io.tmpdir}改為上面的目錄,這里建議用WinSCP將hive-site.xml拷貝到windows上來,用notepad++這種工具,來進(jìn)行文本替換,比較方便。8、啟動(dòng)hive cli,./hive,
繼續(xù)報(bào)錯(cuò),F(xiàn)ound class jline.Terminal, but interface was expected
cp /usr/local/apache-hive-1.2.1-bin/lib/jline-2.12.jar /usr/local/hadoop/share/hadoop/yarn/lib
將hadoop原來的老的jline-0.9.94.jar,改名或者刪除9、啟動(dòng)hive cli,/usr/local/apache-hive-1.2.1-bin/bin/hive,成功啟動(dòng)
5、Hive On Spark使用
create table students(name string, age int);
load data local inpath '/usr/local/spark-study/resources/students.txt' into table students;
// 使用Hive On Spark非常簡(jiǎn)單
// 只要用set hive.execution.engine命令設(shè)置Hive的執(zhí)行引擎為spark即可
// 默認(rèn)是mr
set hive.execution.engine=spark;
// 這里,是完全可以將其設(shè)置為Spark Master的URL地址的
set spark.master=spark://192.168.1.107:7077
select * from students;