外部Hive表刷新表与MSCK修复

Aji*_*nan 6 hive apache-spark hivecontext

我将外部配置单元表存储为Parquet,在列上进行了分区,as_of_dt并通过Spark Streaming插入了数据。现在每天都会添加新分区。我这样做是为了 msck repair table使配置单元metastore获取新添加的分区信息。这是唯一的方法还是有更好的方法?我担心下游用户查询表是否会msck repair导致数据不可用或陈旧数据出现任何问题?我正在浏览 HiveContextAPI并查看refreshTable选项。知道使用它是否有意义refreshTable

小智 8

若要直接回答您的问题msck修复表,将检查表的分区是否处于活动状态。这意味着,如果您删除了一些分区,并且不想在表的show partitions命令中显示它们,则msck repair table应该删除它们。与无效或刷新语句相比,Msck修复可能花费更多时间,但是无效元数据仅在Hive中运行,仅更新Hive Metastore。刷新仅在Spark SQL中运行,并更新Spark元数据存储。

如果在处理过程中的某个位置完成添加分区步骤,则Hive Metastore应该很好,但是,如果您想通过Spark SQL访问Hive表,则需要通过Spark(或Impala或其他更新Spark的进程)来更新元数据。元数据)。

每当您更新或更改配置单元表的内容时,Spark Metastore都可能不同步,从而使您无法通过spark.sql命令集查询数据。这意味着,如果要查询该数据,则需要使Spark Metastore保持同步。

如果您有允许使用的Spark版本,则应刷新并在Spark中将分区添加到Hive表中,以便所有元存储都处于同步状态。以下是我的操作方法:

//Non-Partitioned Table
outputDF.write.format("parquet").mode("overwrite").load(fileLocation)
spark.sql("refresh table " + tableName)

//Partitioned Table
outputDF.write.format("parquet").mode("overwrite").load(fileLocation + "/" + partition)
val addPartitionsStatement = "alter table" + tableName = " add if not exists partition(partitionKey='" + partition + "') location '" + fileLocation + "/" + partition + "'"
spark.sql(addPartitionsStatement)
spark.sql("refresh table " + tableName)
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢阿菲尔德曼。目前我有一个包含一些列和 as_of_dt 作为分区的表。因此,每天都会添加新记录,并且由于分区值发生变化,因此它会转到新分区。我正在执行 dataframe.write.mode("append").partitionBy(partitionKeys).parquet(baseDirectory) ,然后执行 MSCK REPAIR TABLE 。那么,如果我更改表添加(如果不存在分区)并刷新表而不是 msck 修复,我会得到任何好处吗? (2认同)

lef*_*oin 5

看起来 refreshTable 确实刷新了缓存的元数据,而不影响 Hive 元数据。

Doc说:

使给定表的所有缓存元数据无效并刷新。出于性能原因,Spark SQL 或其使用的外部数据源库可能会缓存有关表的某些元数据,例如块的位置。当这些在 Spark SQL 之外发生变化时,用户应该调用这个函数来使缓存失效。

方法不更新 Hive 元数据,因此需要修复。