无法将 table 保存到 Hive Metastore,HDP 3.0
Cant save table to hive metastore, HDP 3.0
我无法再使用 Metastore 将 table 保存到 Hive 数据库。我在使用 spark.sql
的 spark 中看到 tables,但在配置单元数据库中看不到相同的 tables。我试过了,但它没有将 table 存储到配置单元。如何配置配置单元 Metastore?火花版本是2.3.1。
如果您想了解更多详情,请发表评论。
%spark
import org.apache.spark.sql.SparkSession
val spark = (SparkSession
.builder
.appName("interfacing spark sql to hive metastore without configuration file")
.config("hive.metastore.uris", "thrift://xxxxxx.xxx:9083") // replace with your hivemetastore service's thrift url
.enableHiveSupport() // don't forget to enable hive support
.getOrCreate())
spark.conf.get("spark.sql.warehouse.dir")// Output: res2: String = /apps/spark/warehouse
spark.conf.get("hive.metastore.warehouse.dir")// NotSuchElement Exception
spark.conf.get("spark.hadoop.hive.metastore.uris")// NotSuchElement Exception
var df = (spark
.read
.format("parquet")
.load(dataPath)
df.createOrReplaceTempView("my_temp_table");
spark.sql("drop table if exists my_table");
spark.sql("create table my_table using hive as select * from my_temp_table");
spark.sql("show tables").show(false)// I see my_table in default database
@catpaws回答后更新:HDP 3.0及以后,Hive和Spark使用独立目录
保存table到spark目录:
df.createOrReplaceTempView("my_temp_table");
spark.sql("create table my_table as select * from my_temp_table");
VS
保存table到配置单元目录:
val hive = com.hortonworks.spark.sql.hive.llap.HiveWarehouseBuilder.session(spark).build()
hive.createTable("newTable")
.ifNotExists()
.column("ws_sold_time_sk", "bigint")
...// x 200 columns
.column("ws_ship_date_sk", "bigint")
.create()
df.write.format(HIVE_WAREHOUSE_CONNECTOR)
.option("table", "newTable")
.save()
正如您以这种方式看到的,Hive Warehouse Connector 对于具有百列的数据帧非常不切实际。有什么方法可以将大型数据帧保存到 Hive 吗?
来自Hortonworks docs:
在 HDP 3.0 及更高版本中,Spark 和 Hive 使用独立的目录来访问相同或不同平台上的 SparkSQL 或 Hive table。由 Spark 创建的 table 驻留在 Spark 目录中。 Hive 创建的 table 驻留在 Hive 目录中。数据库属于目录命名空间,类似于 tables 属于数据库命名空间的方式。虽然独立,但这些 table 可以互操作,您可以在 Hive 目录中看到 Spark table,但只有在使用 Hive Warehouse Connector 时才会如此。
使用 HWC API 的 Write operations 将 DataFrame 写入 Hive。
更新:您现在可以(通过使用 HDP 3.1)创建一个 DataFrame,如果代表该 DataFrame 的 Hive table 不存在,Hive Warehouse Connector 会创建它,如 [=13] 所示=]:
df = //Create DataFrame from any source
val hive = com.hortonworks.spark.sql.hive.llap.HiveWarehouseBuilder.session(spark).build()
df.write.format(HIVE_WAREHOUSE_CONNECTOR)
.option("table", "my_Table")
.save()
正如@catpaws 所说,Spark 和 Hive 使用独立的目录。要使用 Hive Warehouse Connector 保存多列数据框,您可以使用我的函数:
save_table_hwc(df1, "default", "table_test1")
def save_table_hwc(df: DataFrame, database: String, tableName: String) : Unit = {
hive.setDatabase(database)
hive.dropTable(tableName, true, false)
hive.createTable(tableName)
var table_builder = hive.createTable(tableName)
for( i <- 0 to df.schema.length-1){
var name = df.schema.toList(i).name.replaceAll("[^\p{L}\p{Nd}]+", "")
var data_type = df.schema.toList(i).dataType.sql
table_builder = table_builder.column(name, data_type)
}
table_builder.create()
df.write.format(HIVE_WAREHOUSE_CONNECTOR).option("table", tableName).save()
}
我无法再使用 Metastore 将 table 保存到 Hive 数据库。我在使用 spark.sql
的 spark 中看到 tables,但在配置单元数据库中看不到相同的 tables。我试过了,但它没有将 table 存储到配置单元。如何配置配置单元 Metastore?火花版本是2.3.1。
如果您想了解更多详情,请发表评论。
%spark
import org.apache.spark.sql.SparkSession
val spark = (SparkSession
.builder
.appName("interfacing spark sql to hive metastore without configuration file")
.config("hive.metastore.uris", "thrift://xxxxxx.xxx:9083") // replace with your hivemetastore service's thrift url
.enableHiveSupport() // don't forget to enable hive support
.getOrCreate())
spark.conf.get("spark.sql.warehouse.dir")// Output: res2: String = /apps/spark/warehouse
spark.conf.get("hive.metastore.warehouse.dir")// NotSuchElement Exception
spark.conf.get("spark.hadoop.hive.metastore.uris")// NotSuchElement Exception
var df = (spark
.read
.format("parquet")
.load(dataPath)
df.createOrReplaceTempView("my_temp_table");
spark.sql("drop table if exists my_table");
spark.sql("create table my_table using hive as select * from my_temp_table");
spark.sql("show tables").show(false)// I see my_table in default database
@catpaws回答后更新:HDP 3.0及以后,Hive和Spark使用独立目录
保存table到spark目录:
df.createOrReplaceTempView("my_temp_table");
spark.sql("create table my_table as select * from my_temp_table");
VS
保存table到配置单元目录:
val hive = com.hortonworks.spark.sql.hive.llap.HiveWarehouseBuilder.session(spark).build()
hive.createTable("newTable")
.ifNotExists()
.column("ws_sold_time_sk", "bigint")
...// x 200 columns
.column("ws_ship_date_sk", "bigint")
.create()
df.write.format(HIVE_WAREHOUSE_CONNECTOR)
.option("table", "newTable")
.save()
正如您以这种方式看到的,Hive Warehouse Connector 对于具有百列的数据帧非常不切实际。有什么方法可以将大型数据帧保存到 Hive 吗?
来自Hortonworks docs: 在 HDP 3.0 及更高版本中,Spark 和 Hive 使用独立的目录来访问相同或不同平台上的 SparkSQL 或 Hive table。由 Spark 创建的 table 驻留在 Spark 目录中。 Hive 创建的 table 驻留在 Hive 目录中。数据库属于目录命名空间,类似于 tables 属于数据库命名空间的方式。虽然独立,但这些 table 可以互操作,您可以在 Hive 目录中看到 Spark table,但只有在使用 Hive Warehouse Connector 时才会如此。
使用 HWC API 的 Write operations 将 DataFrame 写入 Hive。
更新:您现在可以(通过使用 HDP 3.1)创建一个 DataFrame,如果代表该 DataFrame 的 Hive table 不存在,Hive Warehouse Connector 会创建它,如 [=13] 所示=]:
df = //Create DataFrame from any source
val hive = com.hortonworks.spark.sql.hive.llap.HiveWarehouseBuilder.session(spark).build()
df.write.format(HIVE_WAREHOUSE_CONNECTOR)
.option("table", "my_Table")
.save()
正如@catpaws 所说,Spark 和 Hive 使用独立的目录。要使用 Hive Warehouse Connector 保存多列数据框,您可以使用我的函数:
save_table_hwc(df1, "default", "table_test1")
def save_table_hwc(df: DataFrame, database: String, tableName: String) : Unit = {
hive.setDatabase(database)
hive.dropTable(tableName, true, false)
hive.createTable(tableName)
var table_builder = hive.createTable(tableName)
for( i <- 0 to df.schema.length-1){
var name = df.schema.toList(i).name.replaceAll("[^\p{L}\p{Nd}]+", "")
var data_type = df.schema.toList(i).dataType.sql
table_builder = table_builder.column(name, data_type)
}
table_builder.create()
df.write.format(HIVE_WAREHOUSE_CONNECTOR).option("table", tableName).save()
}