總結:Hive,Hive on Spark和SparkSQL區別

Hive on Mapreduce
Hive的原理你們能夠參考這篇大數據時代的技術hive:hive介紹,實際的一些操做能夠看這篇筆記:新手的Hive指南,至於還有興趣看Hive優化方法能夠看看我總結的這篇Hive性能優化上的一些總結html

Hive on Mapreduce執行流程java


執行流程詳細解析mysql

Step 1:UI(user interface) 調用 executeQuery 接口,發送 HQL 查詢語句給 Driver
Step 2:Driver 爲查詢語句建立會話句柄,並將查詢語句發送給 Compiler, 等待其進行語句解析並生成執行計劃
Step 3 and 4:Compiler 從 metastore 獲取相關的元數據
Step 5:元數據用於對查詢樹中的表達式進行類型檢查,以及基於查詢謂詞調整分區,生成計劃
Step 6 (6.1,6.2,6.3):由 Compiler 生成的執行計劃是階段性的 DAG,每一個階段均可能會涉及到 Map/Reduce job、元數據的操做、HDFS 文件的操做,Execution Engine 將各個階段的 DAG 提交給對應的組件執行。
Step 7, 8 and 9:在每一個任務(mapper / reducer)中,查詢結果會以臨時文件的方式存儲在 HDFS 中。保存查詢結果的臨時文件由 Execution Engine 直接從 HDFS 讀取,做爲從 Driver Fetch API 的返回內容。
Hive on Mapreduce特色
關係數據庫裏,表的加載模式是在數據加載時候強制肯定的(表的加載模式是指數據庫存儲數據的文件格式),若是加載數據時候發現加載的數據不符合模式,關係數據庫則會拒絕加載數據,這個就叫「寫時模式」,寫時模式會在數據加載時候對數據模式進行檢查校驗的操做。Hive在加載數據時候和關係數據庫不一樣,hive在加載數據時候不會對數據進行檢查,也不會更改被加載的數據文件,而檢查數據格式的操做是在查詢操做時候執行,這種模式叫「讀時模式」。在實際應用中,寫時模式在加載數據時候會對列進行索引,對數據進行壓縮,所以加載數據的速度很慢,可是當數據加載好了,咱們去查詢數據的時候,速度很快。可是當咱們的數據是非結構化,存儲模式也是未知時候,關係數據操做這種場景就麻煩多了,這時候hive就會發揮它的優點。
關係數據庫一個重要的特色是能夠對某一行或某些行的數據進行更新、刪除操做,hive**不支持對某個具體行的操做,hive對數據的操做只支持覆蓋原數據和追加數據**。Hive也不支持事務和索引。更新、事務和索引都是關係數據庫的特徵,這些hive都不支持,也不打算支持,緣由是hive的設計是海量數據進行處理,全數據的掃描時常態,針對某些具體數據進行操做的效率是不好的,對於更新操做,hive是經過查詢將原表的數據進行轉化最後存儲在新表裏,這和傳統數據庫的更新操做有很大不一樣。
Hive也能夠在hadoop作實時查詢上作一份本身的貢獻,那就是和hbase集成,hbase能夠進行快速查詢,可是hbase不支持類SQL的語句,那麼此時hive能夠給hbase提供sql語法解析的外殼,能夠用類sql語句操做hbase數據庫。
Hive能夠認爲是MapReduce的一個封裝、包裝。Hive的意義就是在業務分析中將用戶容易編寫、會寫的Sql語言轉換爲複雜難寫的MapReduce程序,從而大大下降了Hadoop學習的門檻,讓更多的用戶能夠利用Hadoop進行數據挖掘分析。
與傳統數據庫之間對比—From:Hive和傳統數據庫進行比較sql

比較項    SQL    HiveQL
ANSI SQL    支持    不徹底支持
更新    UPDATE\INSERT\DELETE    insert OVERWRITE\INTO TABLE
事務    支持    不支持
模式    寫模式    讀模式
數據保存    塊設備、本地文件系統    HDFS
延時    低    高
多表插入    不支持    支持
子查詢    徹底支持    只能用在From子句中
視圖    Updatable    Read-only
可擴展性    低    高
數據規模    小    大
….    ……    ……
SparkSQL
SparkSQL簡介
SparkSQL的前身是Shark,給熟悉RDBMS但又不理解MapReduce的技術人員提供快速上手的工具,hive應運而生,它是當時惟一運行在Hadoop上的SQL-on-hadoop工具。可是MapReduce計算過程當中大量的中間磁盤落地過程消耗了大量的I/O,下降的運行效率,爲了提升SQL-on-Hadoop的效率,Shark應運而生,但又由於Shark對於Hive的太多依賴(如採用Hive的語法解析器、查詢優化器等等),2014年spark團隊中止對Shark的開發,將全部資源放SparkSQL項目上shell

​ 其中SparkSQL做爲Spark生態的一員繼續發展,而再也不受限於Hive,只是兼容Hive;而Hive on Spark是一個Hive的發展計劃,該計劃將Spark做爲Hive的底層引擎之一,也就是說,Hive將再也不受限於一個引擎,能夠採用Map-Reduce、Tez、Spark等引擎。數據庫

SparkSQL的兩個組件express

SQLContext:Spark SQL提供SQLContext封裝Spark中的全部關係型功能。能夠用以前的示例中的現有SparkContext建立SQLContext。
DataFrame:DataFrame是一個分佈式的,按照命名列的形式組織的數據集合。DataFrame基於R語言中的data frame概念,與關係型數據庫中的數據庫表相似。經過調用將DataFrame的內容做爲行RDD(RDD of Rows)返回的rdd方法,能夠將DataFrame轉換成RDD。能夠經過以下數據源建立DataFrame:已有的RDD、結構化數據文件、JSON數據集、Hive表、外部數據庫。
SparkSQL運行架構
相似於關係型數據庫,SparkSQL也是語句也是由Projection(a1,a2,a3)、Data Source(tableA)、Filter(condition)組成,分別對應sql查詢過程當中的Result、Data Source、Operation,也就是說SQL語句按Operation–>Data Source–>Result的次序來描述的。apache

當執行SparkSQL語句的順序編程

對讀入的SQL語句進行解析(Parse),分辨出SQL語句中哪些詞是關鍵詞(如SELECT、FROM、WHERE),哪些是表達式、哪些是Projection、哪些是Data Source等,從而判斷SQL語句是否規範; 
Projection:簡單說就是select選擇的列的集合,參考:SQL Projection
將SQL語句和數據庫的數據字典(列、表、視圖等等)進行綁定(Bind),若是相關的Projection、Data Source等都是存在的話,就表示這個SQL語句是能夠執行的;
通常的數據庫會提供幾個執行計劃,這些計劃通常都有運行統計數據,數據庫會在這些計劃中選擇一個最優計劃(Optimize);
計劃執行(Execute),按Operation–>Data Source–>Result的次序來進行的,在執行過程有時候甚至不須要讀取物理表就能夠返回結果,好比從新運行剛運行過的SQL語句,可能直接從數據庫的緩衝池中獲取返回結果。
Hive on Spark
​ hive on Spark是由Cloudera發起,由Intel、MapR等公司共同參與的開源項目,其目的是把Spark做爲Hive的一個計算引擎,將Hive的查詢做爲Spark的任務提交到Spark集羣上進行計算。經過該項目,能夠提升Hive查詢的性能,同時爲已經部署了Hive或者Spark的用戶提供了更加靈活的選擇,從而進一步提升Hive和Spark的普及率。json

Hive on Spark與SparkSql的區別
​ hive on spark大致與SparkSQL結構相似,只是SQL引擎不一樣,可是計算引擎都是spark!敲黑板!這纔是重點!

咱們來看下,在pyspark中使用Hive on Spark是中怎麼樣的體驗

#初始化Spark SQL
#導入Spark SQL
from pyspark.sql import HiveContext,Row
# 當不能引入Hive依賴時
# from pyspark.sql import SQLContext,Row
# 注意,上面那一點纔是關鍵的,他兩來自於同一個包,大家區別能有多大


hiveCtx = HiveContext(sc)   #建立SQL上下文環境
input = hiveCtx.jsonFile(inputFile)   #基本查詢示例
input.registerTempTable("tweets")   #註冊輸入的SchemaRDD(SchemaRDD在Spark 1.3版本後已經改成DataFrame)
#依據retweetCount(轉發計數)選出推文
topTweets = hiveCtx.sql("SELECT text,retweetCount FROM tweets ORDER BY retweetCount LIMIT 10")

咱們能夠看到,sqlcontext和hivecontext都是出自於pyspark.sql包,能夠從這裏理解的話,其實hive on spark和sparksql並無太大差異

結構上Hive On Spark和SparkSQL都是一個翻譯層,把一個SQL翻譯成分佈式可執行的Spark程序。並且你們的引擎都是spark

SparkSQL和Hive On Spark都是在Spark上實現SQL的解決方案。Spark早先有Shark項目用來實現SQL層,不事後來推翻重作了,就變成了SparkSQL。這是Spark官方Databricks的項目,Spark項目自己主推的SQL實現。Hive On Spark比SparkSQL稍晚。Hive本來是沒有很好支持MapReduce以外的引擎的,而Hive On Tez項目讓Hive得以支持和Spark近似的Planning結構(非MapReduce的DAG)。因此在此基礎上,Cloudera主導啓動了Hive On Spark。這個項目獲得了IBM,Intel和MapR的支持(可是沒有Databricks)。—From SparkSQL與Hive on Spark的比較

Hive on Mapreduce和SparkSQL使用場景
Hive on Mapreduce場景
Hive的出現可讓那些精通SQL技能、可是不熟悉MapReduce 、編程能力較弱與不擅長Java語言的用戶可以在HDFS大規模數據集上很方便地利用SQL 語言查詢、彙總、分析數據,畢竟精通SQL語言的人要比精通Java語言的多得多
Hive適合處理離線非實時數據
SparkSQL場景
Spark既能夠運行本地local模式,也能夠以Standalone、cluster等多種模式運行在Yarn、Mesos上,還能夠運行在雲端例如EC2。此外,Spark的數據來源很是普遍,能夠處理來自HDFS、HBase、 Hive、Cassandra、Tachyon上的各類類型的數據。
實時性要求或者速度要求較高的場所
Hive on Mapreduce和SparkSQL性能對比
具體實驗參見:Spark SQL & Spark Hive編程開發, 並和Hive執行效率對比

結論:sparksql和hive on spark時間差很少,但都比hive on mapreduce快不少,官方數據認爲spark會被傳統mapreduce快10-100倍

更新
2017.8.4 第一次更新,收集和整理
致謝
Spark入門實戰系列–6.SparkSQL(上)–SparkSQL簡介
SparkSQL與Hive on Spark的比較
Spark SQL和Hive使用場景?
Hive和SparkSQL: 基於 Hadoop 的數據倉庫工具

SparkSQL操做Hive Table(enableHiveSupport())

Spark SQL支持對Hive的讀寫操做。然而由於Hive有不少依賴包,因此這些依賴包沒有包含在默認的Spark包裏面。若是Hive依賴的包能在classpath找到,Spark將會自動加載它們。須要注意的是,這些Hive依賴包必須複製到全部的工做節點上,由於它們爲了可以訪問存儲在Hive的數據,會調用Hive的序列化和反序列化(SerDes)包。Hive的配置文件hive-site.xmlcore-site.xml(security配置)和hdfs-site.xml(HDFS配置)是保存在conf目錄下面。 
當使用Hive時,必須初始化一個支持Hive的SparkSession,用戶即便沒有部署一個Hive的環境仍然可使用Hive。當沒有配置hive-site.xml時,Spark會自動在當前應用目錄建立metastore_db和建立由spark.sql.warehouse.dir配置的目錄,若是沒有配置,默認是當前應用目錄下的spark-warehouse目錄。 
注意:從Spark 2.0.0版本開始,hive-site.xml裏面的hive.metastore.warehouse.dir屬性已經被spark.sql.warehouse.dir替代,用於指定warehouse的默認數據路徑(必須有寫權限)。

import java.io.Serializable;  
import java.util.ArrayList;  
import java.util.List;  

import org.apache.spark.api.java.function.MapFunction;  
import org.apache.spark.sql.Dataset;  
import org.apache.spark.sql.Encoders;  
import org.apache.spark.sql.Row;  
import org.apache.spark.sql.SparkSession;  

public static class Record implements Serializable {  
  private int key;  
  private String value;  

  public int getKey() {  
    return key;  
  }  

  public void setKey(int key) {  
    this.key = key;  
  }  

  public String getValue() {  
    return value;  
  }  

  public void setValue(String value) {  
    this.value = value;  
  }  
}  

// warehouseLocation points to the default location for managed databases and tables  
String warehouseLocation = "/spark-warehouse";  
// init spark session with hive support  
SparkSession spark = SparkSession  
  .builder()  
  .appName("Java Spark Hive Example")  
  .master("local[*]")  
  .config("spark.sql.warehouse.dir", warehouseLocation)  
  .enableHiveSupport()  
  .getOrCreate();  

spark.sql("CREATE TABLE IF NOT EXISTS src (key INT, value STRING)");  
spark.sql("LOAD DATA LOCAL INPATH 'examples/src/main/resources/kv1.txt' INTO TABLE src");  

// Queries are expressed in HiveQL  
spark.sql("SELECT * FROM src").show();  
// +---+-------+  
// |key|  value|  
// +---+-------+  
// |238|val_238|  
// | 86| val_86|  
// |311|val_311|  
// ...  
// only showing top 20 rows  

// Aggregation queries are also supported.  
spark.sql("SELECT COUNT(*) FROM src").show();  
// +--------+  
// |count(1)|  
// +--------+  
// |    500 |  
// +--------+  

// The results of SQL queries are themselves DataFrames and support all normal functions.  
Dataset<Row> sqlDF = spark.sql("SELECT key, value FROM src WHERE key < 10 ORDER BY key");  

// The items in DaraFrames are of type Row, which lets you to access each column by ordinal.  
Dataset<String> stringsDS = sqlDF.map(row -> "Key: " + row.get(0) + ", Value: " + row.get(1), Encoders.STRING());  
stringsDS.show();  
// +--------------------+  
// |               value|  
// +--------------------+  
// |Key: 0, Value: val_0|  
// |Key: 0, Value: val_0|  
// |Key: 0, Value: val_0|  
// ...  

// You can also use DataFrames to create temporary views within a SparkSession.  
List<Record> records = new ArrayList<Record>();  
for (int key = 1; key < 100; key++) {  
  Record record = new Record();  
  record.setKey(key);  
  record.setValue("val_" + key);  
  records.add(record);  
}  
Dataset<Row> recordsDF = spark.createDataFrame(records, Record.class);  
recordsDF.createOrReplaceTempView("records");  

// Queries can then join DataFrames data with data stored in Hive.  
spark.sql("SELECT * FROM records r JOIN src s ON r.key = s.key").show();  
// +---+------+---+------+  
// |key| value|key| value|  
// +---+------+---+------+  
// |  2| val_2|  2| val_2|  
// |  2| val_2|  2| val_2|  
// |  4| val_4|  4| val_4|  
// ...  
// only showing top 20 rows

若是使用eclipse運行上述代碼的話須要添加spark-hive的jars,下面是maven的配置:

<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-hive_2.11 -->  
<dependency>  
    <groupId>org.apache.spark</groupId>  
    <artifactId>spark-hive_2.11</artifactId>  
    <version>2.1.0</version>  
</dependency>
  •  

不然的話會遇到下面錯誤:

Exception in thread "main" java.lang.IllegalArgumentException: Unable to instantiate SparkSession with Hive support because Hive classes are not found.  
    at org.apache.spark.sql.SparkSession$Builder.enableHiveSupport(SparkSession.scala:815)  
    at JavaSparkHiveExample.main(JavaSparkHiveExample.java:17)
  •  

與不一樣版本Hive Metastore的交互

Spark SQL對Hive的支持其中一個最重要的部分是與Hive metastore的交互,使得Spark SQL能夠訪問Hive表的元數據。從Spark 1.4.0版本開始,Spark SQL使用下面的配置能夠用於查詢不一樣版本的Hive metastores。須要注意的是,本質上Spark SQL會使用編譯後的Hive 1.2.1版本的那些類來用於內部操做(serdes、UDFs、UDAFs等等)。

這裏寫圖片描述

Spark之HiveSupport鏈接(spark-shell和IDEA)

1.spark-shell

1.1.拷貝配置文件

  1. 拷貝hive/conf/hdfs-site.xml 到 spark/conf/ 下
  2. 拷貝hive/lib/mysql 到 spark/jars/下
    這裏能夠經過以下參數來實現指定jar-path
--driver-class-path path/mysql-connector-java-5.1.13-bin.jar

1.2.啓動spark-shell

spark.sql("show databases").show()
spark.sql("use test")
spark.sql("select * from student").show()

執行結果:

[hadoop@hadoop1 spark-2.3.0-bin-hadoop2.7]$ ./bin/spark-shell
2018-09-04 11:43:10 WARN  NativeCodeLoader:62 - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
Spark context Web UI available at http://hadoop1:4040
Spark context available as 'sc' (master = local[*], app id = local-1536032600945).
Spark session available as 'spark'.
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.3.0
      /_/

Using Scala version 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_91)
Type in expressions to have them evaluated.
Type :help for more information.

scala> spark.sql("show databases").show()
2018-09-04 11:43:54 WARN  ObjectStore:568 - Failed to get database global_temp, returning NoSuchObjectException
+------------+
|databaseName|
+------------+
|     default|
|        test|
+------------+


scala> spark.sql("use test")
res1: org.apache.spark.sql.DataFrame = []

scala> spark.sql("select * from student").show()
+----+-----+---+----+-----+
| sno|sname|sex|sage|sdept|
+----+-----+---+----+-----+
|1001|   張三|  男|  22|   高一|
|1002|   李四|  女|  25|   高二|
+----+-----+---+----+-----+

2.IDEA鏈接Hive

這裏是鏈接遠程的Hive,若是尚未部署Hive,請參考Hive之環境安裝,前提是必須先啓動hdfs。

2.1.引入依賴

<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-core -->
<dependency>
  <groupId>org.apache.spark</groupId>
  <artifactId>spark-core_2.11</artifactId>
  <version>2.3.0</version>
  <!--<scope>provided</scope>-->
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-sql_2.11 -->
<dependency>
  <groupId>org.apache.spark</groupId>
  <artifactId>spark-sql_2.11</artifactId>
  <version>2.3.0</version>
  <!--<scope>provided</scope>-->
</dependency>
<dependency>
  <groupId>org.apache.spark</groupId>
  <artifactId>spark-hive_2.11</artifactId>
  <version>2.3.0</version>
</dependency>
<dependency><!--數據庫驅動:Mysql-->
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.40</version>
</dependency>

2.2.拷貝配置文件

拷貝hive-site.xml到項目的resources目錄下便可

 

hive-site.xml

<configuration>
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://hadoop1:3306/hive?createDatabaseIfNotExist=true</value>
    <description>JDBC connect string for a JDBC metastore</description>
  </property>
  
  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
    <description>Driver class name for a JDBC metastore</description>
  </property>
  
  <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>root</value>
    <description>username to use against metastore database</description>
  </property>
  
  <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>root</value>
    <description>password to use against metastore database</description>
  </property>
</configuration>

2.3.編寫代碼

object HiveSupport {
  def main(args: Array[String]): Unit = {
    //val warehouseLocation = "D:\\workspaces\\idea\\hadoop"

    val spark =
      SparkSession.builder()
        .appName("HiveSupport")
        .master("local[2]")
        //拷貝hdfs-site.xml不用設置,若是使用本地hive,可經過該參數設置metastore_db的位置
        //.config("spark.sql.warehouse.dir", warehouseLocation)
        .enableHiveSupport() //開啓支持hive
        .getOrCreate()

    //spark.sparkContext.setLogLevel("WARN") //設置日誌輸出級別
    import spark.implicits._
    import spark.sql

    sql("show databases")
    sql("use test")
    sql("select * from student").show()

    Thread.sleep(150 * 1000)
    spark.stop()
  }
}

執行結果:

+----+-----+---+----+-----+
| sno|sname|sex|sage|sdept|
+----+-----+---+----+-----+
|1001|   張三|  男|  22|   高一|
|1002|   李四|  女|  25|   高二|
+----+-----+---+----+-----+

參考:

  1. Spark的spark.sql.warehouse.dir相關
  2. Spark 2.2.1 + Hive
  3. spark鏈接hive(spark-shell和eclipse兩種方式)
  4. 官方文檔

Spark1.6訪問Hive表

知識點1:Spark訪問HIVE上面的數據

  配置注意點:.

    1.拷貝mysql-connector-java-5.1.38-bin.jar等相關的jar包到你${spark_home}/lib中(spark2.0以後是${spark_home}/jars下),不清楚就所有拷貝過去

    2.將Hive的配置文件hive-site.xml拷貝到${spark_home}/conf目錄下

    3.由於使用ThriftJDBC/ODBC Server訪問spark SQL,因此要修改hive-site.xml文件 

        <property>

          <name>hive.metastore.uris</name>

          <value>thrift://hadoop1:9083</value>

          <description>Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore.</description>

        </property>

         4.啓動hivede metastroe後臺進程。執行${hive_home}/bin/hive --service metastore啓動hive的service metastore後臺進程。

     5.啓動spark-shell訪問hive上數據。在${spark_home}/bin下執行./spark-shell --master spark://master:7077 (可添加其餘參數rg:--jars等參數)    

    

 

知識點2:Spark訪問與HBase關聯的Hive表

  建立關聯HBase的Hive外表:

複製代碼

DROP TABLE IF EXISTS table_name;
CREATE EXTERNAL TABLE  table_name (ROWKEY STRING,Name STRING,ADDRESS STRING )
ROW FORMAT DELIMITED
COLLECTION ITEMS TERMINATED BY ','
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES("hbase.columns.mapping"=":key,A:Name,A:ADDRESS")
TBLPROPERTIES("hbase.table.name" = "table_name");

複製代碼

  若是建立的是內部表,刪除了hive表,hbase上對應的表也會被刪除,不建議使用這種方式。

  若是建立的是外部表,使用drop只是刪除了hive的元數據,hbase表不會受影響。

  擴展:使用drop刪除hive的外表後,若是從新建立該表並load數據到該表中,將會出現部分數據是上次插入的數據,致使總數據量大於第二次插入的數據量,出現這種狀況的緣由是由於drop刪除表,只是刪除了表的元數據,不會刪除表中的數據,表中的數據存儲在建立語句location指定的hdfs路徑下,只要刪除該文件便可。

  配置注意點:

    1.Hive的配置部署與知識點1同樣

    2.拷貝以下jar包到你${spark_home}/lib中(spark2.0以後是${spark_home}/jars下),缺乏這些jarj將會報錯,本人是將hbase下全部jar都複製到了${spark_home}/lib中

      • hbase-protocol-1.1.2.jar
      • hbase-client-1.1.2.jar
      • hbase-common-1.1.2.jar
      • hbase-server-1.1.2.jar
      • hive-hbase-handler-1.2.1.jar
      • metrics-core-2.2.0.jar

    3.將HBase的配置文件hbase-site.xml拷貝到${spark_home}/conf目錄下

    4.啓動spark-shell訪問與hbase關聯的hive上數據。在${spark_home}/bin下執行./spark-shell --master spark://master:7077 (可添加其餘參數rg:--jars等參數,eg:

./bin/spark-shell --master spark://Master36:7077 --jars /usr/local/spark/lib/hive-hbase-handler-1.2.1.jar,/usr/local/spark/lib/hbase-common-1.1.2.jar,/usr/local/spark/lib/hbase-client-1.1.2.jar,/usr/local/spark/lib/hbase-protocol-1.1.2.jar,/usr/local/spark/lib/hbase-server-1.1.2.jar,/usr/local/spark/lib/metrics-core-2.2.0.jar,/usr/local/spark/lib/guava-12.0.1.jar,/usr/local/spark/lib/htrace-core-3.1.0-incubating.jar

代碼:

複製代碼

/**
      *下面是spark1.6.2讀取hive的簡單代碼
      */
    val sqlContext=new org.apache.spark.sql.hive.HiveContext(sc)

    import sqlContext.implicites._

    val df=sqlContext.sql("select xxx from table_name").collect().foreach(println)


    /**
      *下面是spark2.11讀取hive的簡單代碼
       *spark2.0版本訪問hive配置部分將會簡單一點
      */
    import org.apache.spark.sql.SparkSession
    val warehouseLocation="hdfs://master:9000/user/hive/warehouse"

    val spark =SparkSession.builder().appName("spark-hive").config("spark.sql.warehouse.dir",warehouseLocation).enableHiveSupport().getOrCreate()

    import spark.implicits._
    import spark.sql

    spark.sql("selectxxx from xx").show
    //將數據框保存到到指定路徑中,可經過format來指定要保存的文件格式,repartition(n)設置輸出文件的個數
   dataFrame.repartition(1).write.format("csv").save("hdfs://master:9000/xxx")

複製代碼

 

出現的錯誤總結(解決方法僅供參考):

 1.error: Error creating transactional connection factory

  解決方法:在hive和spark集羣都能正常使用狀況下,檢查一下hive的service metastore後臺進程是否已經啓動了

 2.Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient

  解決方法:有多是hive鏈接數據庫部分出現了問題,在hive-site.xml文件中添加<property><name>hive.metastore.uris</name><value>thrift://hadoop1:9083</value></property>,若是配置後執行出現了新的錯誤:ERROR ObjectStore: Version information not found in metastore,這個新錯誤可能使用hive的jar包和存儲元數據信息版本不一致而拋出的異常,能夠在hive-site.xml文件中添加參數跳過版本的問題,<name>hive.metastore.schema.verification</name><value>false</value>,重啓hive服務,若是仍是繼續報ERROR ObjectStore: Version information not found in metastore這個錯誤,說明剛剛配置的參數沒有生效,接着要把hdfs-site.xml文件拷貝到${spark_home}/conf文件下,這多是由於環境變量的問題引發的

 3.java.io.IOException: java.lang.reflect.InvocationTargetException

  解決方法:因爲缺乏htrace-core-3.1.0-incubating.jar包,引入該包便可。

 4.java.lang.ClassNotFoundException Class org.apache.hadoop.hive.hbase.HBaseSerDe not found

  解決方法:因爲缺乏相關的hbase的jar包(hbase-protocol-1.1.2.jar,hbase-client-1.1.2.jar,hbase-common-1.1.2.jar,hbase-server-1.1.2.jar等),能夠在啓動spark-shell經過--jars來添加。

 5.java.lang.NoClassDefFoundError: org/apache/hadoop/hbase/util/Bytes

  解決方法:因爲缺乏guava-12.0.1.jar包,引入該包便可。

相關文章
相關標籤/搜索