外部配置单元表刷新表与msck修复

r1zhe5dt  于 2021-06-26  发布在  Hive
关注(0)|答案(2)|浏览(672)

我有外部Hive表存储为Parquet,分区在一列说 as_of_dt 数据通过spark流被插入。现在每天都有新的分区被添加。我在做什么 msck repair table 这样配置单元元存储就可以获得新添加的分区信息。这是唯一的办法还是有更好的办法?我担心如果下游用户查询表,会不会 msck repair 导致数据不可用或过时的问题?我正在经历 HiveContext api和see refreshTable 选项。你知道用这个有意义吗 refreshTable 相反呢?

db2dz4w8

db2dz4w81#

看起来refreshtable会刷新缓存的元数据,而不会影响配置单元元数据。
医生说:
使给定表的所有缓存元数据失效并刷新。出于性能原因,sparksql或它使用的外部数据源库可能会缓存表的某些元数据,例如块的位置。当这些在sparksql之外发生更改时,用户应该调用此函数使缓存失效。
方法不更新配置单元元数据,因此需要修复。

6qfn3psc

6qfn3psc2#

要直接回答您的问题,msck repair table将检查表的分区是否处于活动状态。这意味着如果删除了一些分区,并且不希望它们显示在表的show partitions命令中,msck repair table应该删除它们。msck修复可能比invalidate或refresh语句花费更多的时间,但是invalidate metadata只在配置单元中运行,只更新配置单元元存储。刷新仅在spark sql中运行,并更新spark元数据存储。
如果您正在处理过程中的某个地方完成添加分区步骤,那么配置单元元存储应该可以,但是如果您想要通过sparksql访问配置单元表,则需要通过spark(或impala或其他更新spark元数据的进程)更新元数据。
无论何时更新或更改配置单元表的内容,spark metastore都可能不同步,从而导致无法通过spark.sql命令集查询数据。这意味着,如果要查询该数据,则需要保持spark元存储同步。
如果您有一个spark版本允许它,那么您应该刷新spark中的配置单元表并将其添加到配置单元表中,这样所有的元存储都是同步的。下面是我的做法:

//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)

相关问题