1

我不能再使用 Metastore 将表保存到配置单元数据库。我在使用 spark 中看到表,spark.sql但在 hive 数据库中看不到相同的表。我试过了,但它没有将表存储到蜂巢中。如何配置 hive 元存储?火花版本是 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 使用独立目录

将表保存到 spark 目录:

df.createOrReplaceTempView("my_temp_table");
spark.sql("create table my_table as select * from my_temp_table");

VS

将表保存到 hive 目录:

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 仓库连接器对于具有数百列的数据框非常不切实际。有没有办法将大型数据帧保存到 Hive?

4

2 回答 2

0

来自Hortonworks 文档:在 HDP 3.0 及更高版本中,Spark 和 Hive 使用独立的目录来访问相同或不同平台上的 SparkSQL 或 Hive 表。Spark 创建的表位于 Spark 目录中。Hive 创建的表位于 Hive 目录中。数据库属于目录命名空间,类似于表属于数据库命名空间。虽然独立,但这些表可以互操作,您可以在 Hive 目录中看到 Spark 表,但仅在使用 Hive Warehouse Connector 时。

使用HWC API 的Write 操作将 DataFrame 写入 Hive。

更新:您现在可以(通过使用 HDP 3.1)创建一个 DataFrame,如果代表 DataFrame 的 Hive 表不存在,Hive 仓库连接器会创建它,如HDP 3.1 文档中所示:

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()
于 2018-11-15T17:30:45.833 回答
0

正如@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()
}
于 2018-11-21T21:40:59.563 回答