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。

 

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