Spark每日半小時(25)——數據源:ORC文件、JSON數據集、Hive表

ORC文件

從Spark2.3開始,Spark支持帶有ORC文件的新ORC文件格式的矢量化ORC閱讀器。爲此,新添加了以下配置。矢量化讀取器用於本機ORC表(例如:使用USING ORC子句創建的)當spark.sql.orc.impl被設置爲native並且spark.sql.orc.enableVectorizedReader被設置成true。對於Hive ORC serde表(例如,使用該子句創建的表USING HIVE OPTIONS(fileFormat 'ORC')),當spark.sql.hive.convertMetastoreOrc也設置爲true時,使用向量化讀取器。

Property Name Default Meaning
spark.sql.orc.impl hive ORC實現的名稱。它可以是native和hive.native表示在Apache ORC 1.4.1上構建的本機支持。'hive'表示Hive 1.2.1中的ORC庫
spark.sql.orc.enableVectorizedReader true 在native實現中啓用矢量化orc解碼。如果false,在native實現中使用新的非矢量化ORC閱讀器。爲了hive實現,這將被忽略。

JSON數據集

Spark SQL可以自動推斷JSON數據集的模式並將其加載爲Dataset<Row>。可以在Dataset<String>或JSON文件上使用SparkSession.read().json()完成此轉換。

對於常規多行JSON文件,請將multiLine選項設置爲true。

    private static void runJsonDatasetExample(SparkSession spark) {
        // $example on:json_dataset$
        // A JSON dataset is pointed to by path.
        // The path can be either a single text file or a directory storing text files
        Dataset<Row> people = spark.read().json("examples/src/main/resources/people.json");

        // The inferred schema can be visualized using the printSchema() method
        people.printSchema();
        // root
        //  |-- age: long (nullable = true)
        //  |-- name: string (nullable = true)

        // Creates a temporary view using the DataFrame
        people.createOrReplaceTempView("people");

        // SQL statements can be run by using the sql methods provided by spark
        Dataset<Row> namesDF = spark.sql("SELECT name FROM people WHERE age BETWEEN 13 AND 19");
        namesDF.show();
        // +------+
        // |  name|
        // +------+
        // |Justin|
        // +------+

        // Alternatively, a DataFrame can be created for a JSON dataset represented by
        // a Dataset<String> storing one JSON object per string.
        List<String> jsonData = Arrays.asList(
                "{\"name\":\"Yin\",\"address\":{\"city\":\"Columbus\",\"state\":\"Ohio\"}}");
        Dataset<String> anotherPeopleDataset = spark.createDataset(jsonData, Encoders.STRING());
        Dataset<Row> anotherPeople = spark.read().json(anotherPeopleDataset);
        anotherPeople.show();
        // +---------------+----+
        // |        address|name|
        // +---------------+----+
        // |[Columbus,Ohio]| Yin|
        // +---------------+----+
        // $example off:json_dataset$
    }

Hive表

Spark SQL還支持讀取和寫入存儲Apache Hive中的數據。但是,由於Hive具有大量依賴項,因此這些依賴項不包含在默認的Spark分發中。如果可以在類路徑上找到Hive依賴項,Spark將自動加載它們。請注意,這些Hive依賴項也必須存在於所有工作節點上,因爲它們需要訪問Hive序列化和反序列化庫(SerDes)才能訪問存儲在Hive中的數據。

蜂巢的結構是通過將您做hive-site.xml,core-site.xml(安全性配置),以及hdfs-site.xml(對於HDFS配置)文件中conf/。

使用Hive時,必須SparkSession使用Hive支持進行實例化,包括連接到持久性Hive Metastore,支持Hive serdes和Hive用戶定義函數。沒有現有Hive部署的用戶仍可以啓用Hive支持。如果未配置hive-site.xml,則上下文會自動前目錄中啓動Spark應用程序的目錄。請注意,自Spark 2.0.0起hive.metastore.warehouse.dir,hive-site.xml不推薦使用該屬性。而是spark.sql.warehouse.dir用於指定倉庫中數據庫的默認位置。您可能需要向啓動Spark應用程序的用戶授予寫入權限。

  // $example on:spark_hive$
  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;
    }
  }
  // $example off:spark_hive$

  public static void main(String[] args) {
    // $example on:spark_hive$
    // warehouseLocation points to the default location for managed databases and tables
    String warehouseLocation = new File("spark-warehouse").getAbsolutePath();
    SparkSession spark = SparkSession
      .builder()
      .appName("Java Spark Hive Example")
      .config("spark.sql.warehouse.dir", warehouseLocation)
      .enableHiveSupport()
      .getOrCreate();

    spark.sql("CREATE TABLE IF NOT EXISTS src (key INT, value STRING) USING hive");
    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|
    // ...

    // 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 DataFrames are of type Row, which lets you to access each column by ordinal.
    Dataset<String> stringsDS = sqlDF.map(
        (MapFunction<Row, String>) 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<>();
    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|
    // ...
    // $example off:spark_hive$

    spark.stop();
  }

指定Hive表的存儲格式

創建Hive表時,需要定義此表應from/to文件系統讀取/寫入數據,即“輸入格式”和"輸出格式“。我們還需要定義此表如何將數據反序列化爲行,或將行蓄力阿華爲數據,即”serde“。以下選項可以用於指定存儲格式(”serde“,”輸入格式“,”輸出格式“),例如CREATE TABLE src(id int) USING hive OPTIONS(fileFormat 'parquet')。默認情況下,我們將表文件作爲純文本讀取。請注意,創建表時尚不支持Hive存儲處理程序,我們可以使用Hive端的存儲處理程序創建表,並使用Spark SQL讀取它。

屬性名 含義
fileFormat fileFormat是一種存儲格式規範包,包括”serde“,”input format“和“output format“。目前支持6中fileFormats:'sequencefile','rcfile','orc','parquet','textfile'和'avro'。
inputFormat, outputFormat 這兩個選項將相應的`InputFormat`和`OutputFormat`類的名稱指定爲字符串文字,例如`org.apache.hadoop.hive.ql.io.orc.OrcInputFormat`。這兩個選項必須出現在pair中,如果已經指定了`fileFormat`選項,則無法指定它們。
serde 此選項指定serde類的名稱。當指定`fileFormat`選項時,如果給定的`fileFormat`已經包含serde的信息,則不要指定此選項。目前“sequencefile”,“textfile”和“rcfile”不包含serde信息,您可以將此選項與這3個fileFormats一起使用。
fieldDelim, escapeDelim, collectionDelim, mapkeyDelim, lineDelim 這些選項只能與“textfile”fileFormat一起使用。它們定義瞭如何將分隔文件讀入行。

定義的所有其他屬性OPTIONS將被是爲Hive serde屬性。

與不同版本的Hive Metastore交互

Spark SQL的Hive支持最重要的部分之一是與Hive Metastore的交互,這使得Spark SQL能夠訪問Hive表的元數據。從Spark 1.4.0開始,可以使用單個二進制構建的Spark SQL來查詢不同版本的Hive Metastores,使用下面描述的配置。請注意,獨立於用於與Metastore通信的Hive版本,內部Spark SQL將針對Hive 1.2.1進行編譯,並使用這些類進行內部執行(serdes,UDF,UDAF等)。

以下選項可用於配置用於檢索元數據的Hive版本:

屬性名稱 默認 含義
spark.sql.hive.metastore.version 1.2.1 Hive Metastore的版本。可用選項0.12.0通過1.2.1。
spark.sql.hive.metastore.jars builtin 應該用於實例化HiveMetastoreClient的jar的位置。此屬性可以是以下三個選項之一:
  1. builtin
  2. 使用Hive 1.2.1,它在-Phive啓用時與Spark程序集捆綁在一起。選擇此選項時,spark.sql.hive.metastore.version必須1.2.1定義或不定義。
  3. maven
  4. 使用從Maven存儲庫下載的指定版本的Hive jar。通常不建議將此配置用於生產部署。
  5. JVM標準格式的類路徑。此類路徑必須包含所有Hive及其依賴項,包括正確版本的Hadoop。這些罐子只需要存在於驅動程序中,但如果您在紗線羣集模式下運行,則必須確保它們與您的應用程序一起打包。
spark.sql.hive.metastore.sharedPrefixes com.mysql.jdbc,
org.postgresql,
com.microsoft.sqlserver,
oracle.jdbc
以逗號分隔的類前綴列表,應使用在Spark SQL和特定版本的Hive之間共享的類加載器加載。應共享的類的示例是與Metastore進行通信所需的JDBC驅動程序。需要共享的其他類是與已共享的類交互的類。例如,log4j使用的自定義appender。
spark.sql.hive.metastore.barrierPrefixes (empty) 以逗號分隔的類前綴列表,應爲Spark SQL正在與之通信的每個Hive版本顯式重新加載。例如,在通常將被共享(即org.apache.spark.*)的前綴中聲明的Hive UDF。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章