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的位置。此屬性可以是以下三個選項之一:
|
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。 |