原生的spark assembly jar是不依賴hive的,若是要使用spark hql必須將hive相關的依賴包打到spark assembly jar中來。打包方法:html
假設已經裝好了maven,sql
1添加環境變量,若是jvm的這些配置過小的話,可能致使在編譯過程當中出現OOM,所以放大一些:shell
export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=512m"
數據庫
2 將spark源碼下的scalastyle-config.xml,複製到assembly下apache
3 cd到spark源碼目錄,執行:jvm
mvn -Pyarn -Dhadoop.version=2.5.0-cdh5.3.0 -Dscala-2.10.4 -Phive -Phive-thriftserver -DskipTests clean packagesocket
(用cdh版本的只要寫 mvn -Pyarn -Phive -DskipTests clean package就能夠了)maven
注意hadoop.version和scala的版本設置成對應的版本oop
經 過漫長的編譯過程(我編譯了2個半小時),最終成功了,在assembly/target/scala-2.10目錄下面有spark- assembly-1.2.0-cdh5.3.0-hadoop2.5.0-cdh5.3.0.jar文件,用rar打開看看hive jdbc package有沒有包含在裏面,有的話說明編譯成功了。spa
前面介紹如何編譯包含hive的spark-assembly.jar了
cloudera manager裝好的spark,直接執行spark-shell進入命令行後,寫入以下語句:
val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc)
你會發現無法執行經過,由於cm裝的原生的spark是不支持spark hql的,咱們須要手動進行一些調整:
第一步,將編譯好的包含hive的JAR包上傳到hdfs上配置的默認的spark的sharelib目錄:/user/spark/share/lib
第二步:在你要運行spark-shell腳本的節點上的/opt/cloudera/parcels/CDH- 5.3.0-1.cdh5.3.0.p0.30/lib/spark/lib/目錄下面,下載這個jar到這個目錄:hadoop fs -get hdfs://n1:8020/user/spark/share/lib/spark-assembly-with-hive-maven.jar(具 體路徑替換成你本身的)。而後這個目錄下面原來會有個軟連接spark-assembly.jar指向的是spark-assembly-1.2.0- cdh5.3.0-hadoop2.5.0-cdh5.3.0.jar,咱們把這個軟連接刪除掉從新建立一個同名的軟連接:ln -s spark-assembly-with-hive-maven.jar spark-assembly.jar,指向咱們剛下載下來的那個JAR包,這個JAR包會在啓動spark-shell腳本時裝載到driver program的classpath中去的,sparkContext也是在driver中建立出來的,因此須要將咱們編譯的JAR包替換掉原來的 spark-assembly.jar包,這樣在啓動spark-shell的時候,包含hive的spark-assembly就被裝載到 classpath中去了。
第三步:在/opt/cloudera/parcels/CDH/lib/spark/conf/目錄下面建立一個 hive-site.xml。/opt/cloudera/parcels/CDH/lib/spark/conf目錄是默認的spark的配置目錄,當 然你能夠修改默認配置目錄的位置。hive-site.xml內容以下:
<?xml version="1.0" encoding="UTF-8"?> <!--Autogenerated by Cloudera Manager--> <configuration> <property> <name>hive.metastore.local</name> <value>false</value> </property> <property> <name>hive.metastore.uris</name> <value>thrift://n1:9083</value> </property> <property> <name>hive.metastore.client.socket.timeout</name> <value>300</value> </property> <property> <name>hive.metastore.warehouse.dir</name> <value>/user/hive/warehouse</value> </property> </configuration>
這個應該你們都懂的,總要讓spark找到hive的元數據在哪吧,因而就有了上面一些配置。
第四步:修改/opt/cloudera/parcels/CDH/lib/spark/conf/spark- defaults.conf,添加一個屬性:spark.yarn.jar=hdfs://n1:8020/user/spark/share/lib /spark-assembly-with-hive-maven.jar。這個是讓每一個executor下載到本地而後裝載到本身的classpath 下面去的,主要是用在yarn-cluster模式。local模式因爲driver和executor是同一個進程因此不要緊。
以上完事以後,運行spark-shell,再輸入:val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc) 應該就沒問題了。咱們再執行一個語句驗證一下是否是鏈接的咱們指定的hive元數據庫:hiveContext.sql("show tables").take(10) //取前十個表看看最後要重點說明一下這裏的第二步第三步和第四步,若是是yarn-cluster模式的話,應該替換掉集羣全部節點的spark- assembly.jar集羣全部節點的spark conf目錄都須要添加hive-site.xml,每一個節點spark-defaults.conf都須要添加 spark.yarn.jar=hdfs://n1:8020/user/spark/share/lib/spark-assembly-with- hive-maven.jar。能夠寫個shell腳原本替換,否則手動一個一個節點去替換也是蠻累的。