将 Spark 数据帧保存到 Hive:table 不可读,因为 "parquet not a SequenceFile"
save Spark dataframe to Hive: table not readable because "parquet not a SequenceFile"
我想使用 PySpark 将 Spark (v 1.3.0) 数据帧中的数据保存到 Hive table。
documentation 状态:
"spark.sql.hive.convertMetastoreParquet: When set to false, Spark SQL will use the Hive SerDe for parquet tables instead of the built in support."
看Spark tutorial,好像这个属性可以设置:
from pyspark.sql import HiveContext
sqlContext = HiveContext(sc)
sqlContext.sql("SET spark.sql.hive.convertMetastoreParquet=false")
# code to create dataframe
my_dataframe.saveAsTable("my_dataframe")
但是,当我尝试在 Hive it 中查询保存的 table 时 returns:
hive> select * from my_dataframe;
OK
Failed with exception java.io.IOException:java.io.IOException:
hdfs://hadoop01.woolford.io:8020/user/hive/warehouse/my_dataframe/part-r-00001.parquet
not a SequenceFile
如何保存 table 以便在 Hive 中立即可读?
我去过那里...
API 在这方面有点误导。
DataFrame.saveAsTable
不 创建一个 Hive table,而是一个内部 Spark table 源。
它还将某些内容存储到 Hive Metastore 中,但不是您想要的内容。
这个 remark 是由关于 Spark 1.3 的 spark 用户邮件列表制作的。
如果您希望从 Spark 创建一个 Hive table,您可以使用这种方法:
1. 通过 SparkSQL 使用 Create Table ...
用于 Hive 元存储。
2. 对实际数据使用 DataFrame.insertInto(tableName, overwriteMode)
(Spark 1.3)
我上周遇到了这个问题并找到了解决方法
故事是这样的:
如果我在没有 partitionBy:
的情况下创建 table,我可以在 Hive 中看到 table
spark-shell>someDF.write.mode(SaveMode.Overwrite)
.format("parquet")
.saveAsTable("TBL_HIVE_IS_HAPPY")
hive> desc TBL_HIVE_IS_HAPPY;
OK
user_id string
email string
ts string
但是 Hive 无法理解 table 模式(模式为空...)如果我这样做:
spark-shell>someDF.write.mode(SaveMode.Overwrite)
.format("parquet")
.saveAsTable("TBL_HIVE_IS_NOT_HAPPY")
hive> desc TBL_HIVE_IS_NOT_HAPPY;
# col_name data_type from_deserializer
[解决方法]:
spark-shell>sqlContext.sql("SET spark.sql.hive.convertMetastoreParquet=false")
spark-shell>df.write
.partitionBy("ts")
.mode(SaveMode.Overwrite)
.saveAsTable("Happy_HIVE")//Suppose this table is saved at /apps/hive/warehouse/Happy_HIVE
hive> DROP TABLE IF EXISTS Happy_HIVE;
hive> CREATE EXTERNAL TABLE Happy_HIVE (user_id string,email string,ts string)
PARTITIONED BY(day STRING)
STORED AS PARQUET
LOCATION '/apps/hive/warehouse/Happy_HIVE';
hive> MSCK REPAIR TABLE Happy_HIVE;
问题是通过DataframeAPI(partitionBy+saveAsTable)创建的数据源table与Hive不兼容。(看这个link). By setting spark.sql.hive.convertMetastoreParquet to false as suggested in the doc,Spark只把数据放到HDFS上,但不会在 Hive 上创建 table。然后您可以手动进入配置单元 shell 以创建外部 table,并使用指向数据位置的正确架构和分区定义。
我已经在 Spark 1.6.1 中对此进行了测试,它对我有用。希望对您有所帮助!
我在pyspark做过,spark版本2.3.0:
在我们需要 save/overwrite 数据的地方创建空 table,例如:
create table databaseName.NewTableName like databaseName.OldTableName;
然后 运行 下面的命令:
df1.write.mode("overwrite").partitionBy("year","month","day").format("parquet").saveAsTable("databaseName.NewTableName");
问题是您无法使用 hive 阅读此 table 但可以使用 spark 阅读。
元数据尚不存在。换句话说,它会将存在于 HDFS 但不存在于 Metastore 中的任何分区添加到 Hive Metastore。
我想使用 PySpark 将 Spark (v 1.3.0) 数据帧中的数据保存到 Hive table。
documentation 状态:
"spark.sql.hive.convertMetastoreParquet: When set to false, Spark SQL will use the Hive SerDe for parquet tables instead of the built in support."
看Spark tutorial,好像这个属性可以设置:
from pyspark.sql import HiveContext
sqlContext = HiveContext(sc)
sqlContext.sql("SET spark.sql.hive.convertMetastoreParquet=false")
# code to create dataframe
my_dataframe.saveAsTable("my_dataframe")
但是,当我尝试在 Hive it 中查询保存的 table 时 returns:
hive> select * from my_dataframe;
OK
Failed with exception java.io.IOException:java.io.IOException:
hdfs://hadoop01.woolford.io:8020/user/hive/warehouse/my_dataframe/part-r-00001.parquet
not a SequenceFile
如何保存 table 以便在 Hive 中立即可读?
我去过那里...
API 在这方面有点误导。
DataFrame.saveAsTable
不 创建一个 Hive table,而是一个内部 Spark table 源。
它还将某些内容存储到 Hive Metastore 中,但不是您想要的内容。
这个 remark 是由关于 Spark 1.3 的 spark 用户邮件列表制作的。
如果您希望从 Spark 创建一个 Hive table,您可以使用这种方法:
1. 通过 SparkSQL 使用 Create Table ...
用于 Hive 元存储。
2. 对实际数据使用 DataFrame.insertInto(tableName, overwriteMode)
(Spark 1.3)
我上周遇到了这个问题并找到了解决方法
故事是这样的: 如果我在没有 partitionBy:
的情况下创建 table,我可以在 Hive 中看到 tablespark-shell>someDF.write.mode(SaveMode.Overwrite)
.format("parquet")
.saveAsTable("TBL_HIVE_IS_HAPPY")
hive> desc TBL_HIVE_IS_HAPPY;
OK
user_id string
email string
ts string
但是 Hive 无法理解 table 模式(模式为空...)如果我这样做:
spark-shell>someDF.write.mode(SaveMode.Overwrite)
.format("parquet")
.saveAsTable("TBL_HIVE_IS_NOT_HAPPY")
hive> desc TBL_HIVE_IS_NOT_HAPPY;
# col_name data_type from_deserializer
[解决方法]:
spark-shell>sqlContext.sql("SET spark.sql.hive.convertMetastoreParquet=false")
spark-shell>df.write
.partitionBy("ts")
.mode(SaveMode.Overwrite)
.saveAsTable("Happy_HIVE")//Suppose this table is saved at /apps/hive/warehouse/Happy_HIVE
hive> DROP TABLE IF EXISTS Happy_HIVE;
hive> CREATE EXTERNAL TABLE Happy_HIVE (user_id string,email string,ts string)
PARTITIONED BY(day STRING)
STORED AS PARQUET
LOCATION '/apps/hive/warehouse/Happy_HIVE';
hive> MSCK REPAIR TABLE Happy_HIVE;
问题是通过DataframeAPI(partitionBy+saveAsTable)创建的数据源table与Hive不兼容。(看这个link). By setting spark.sql.hive.convertMetastoreParquet to false as suggested in the doc,Spark只把数据放到HDFS上,但不会在 Hive 上创建 table。然后您可以手动进入配置单元 shell 以创建外部 table,并使用指向数据位置的正确架构和分区定义。 我已经在 Spark 1.6.1 中对此进行了测试,它对我有用。希望对您有所帮助!
我在pyspark做过,spark版本2.3.0:
在我们需要 save/overwrite 数据的地方创建空 table,例如:
create table databaseName.NewTableName like databaseName.OldTableName;
然后 运行 下面的命令:
df1.write.mode("overwrite").partitionBy("year","month","day").format("parquet").saveAsTable("databaseName.NewTableName");
问题是您无法使用 hive 阅读此 table 但可以使用 spark 阅读。
元数据尚不存在。换句话说,它会将存在于 HDFS 但不存在于 Metastore 中的任何分区添加到 Hive Metastore。