我将外部配置单元表存储为Parquet,并在列as_of_dt
上进行了分区,并通过Spark Streaming插入了数据。
现在每天都会添加新分区。我正在做msck repair table
,以便配置单元metastore获取新添加的分区信息。这是唯一的方法还是有更好的方法?我担心下游用户查询表时,msck repair
会导致数据不可用或陈旧数据出现任何问题吗?我正在通过HiveContext
API并查看refreshTable
选项。知道使用refreshTable
代替是否有意义?
答案 0 :(得分:3)
要直接回答您的问题msck修复表,将检查表的分区是否处于活动状态。这意味着,如果您删除了一些分区,并且不想在表的show partitions命令中显示它们,则msck repair table应该删除它们。与无效或刷新语句相比,Msck修复可能花费更多时间,但是无效元数据仅在Hive中运行,仅更新Hive Metastore。刷新仅在Spark SQL中运行,并更新Spark元数据存储。
如果在处理过程中的某个位置完成添加分区步骤,则配置单元metastore应该很好,但是,如果您想通过Spark SQL访问配置单元表,则需要通过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)
答案 1 :(得分:0)
refreshTable似乎刷新了缓存的元数据,而不会影响Hive元数据。
Doc说:
使给定表的所有缓存的元数据无效并刷新。 出于性能原因,请使用Spark SQL或外部数据库 它可能会缓存有关表的某些元数据,例如 块的位置。当这些更改在Spark SQL之外时,用户 应该调用此函数来使缓存无效。
该方法不会更新Hive元数据,因此必须进行修复。