相信使用过Hive的同学,一定会知道msck repair的用途(元数据修复)。那么不知道大家有没有好奇过Hive底层是怎么实现该机制的呢?这里带大家简单了解一下。
一、基本解释
在HMS(Hive MetaStore)中存储着每个表的分区列表,但如果一个新的分区通过HDFS直接添加或者删除的话,那么元数据是不会感知到这些分区信息的变化,这个时候可以通过Alter table table_name add/drop partition命令来手动增加或者删除分区。除了alter命令之外呢,还可以通过msck [repair] table table_name [add/drop/sync partitions]来修复,来看下该命令支持以下几种场景:
1、MSC 命令的默认选项是 ADD PARTITIONS。使用此选项,它会将 HDFS 上存在但不在 Metastore 中的任何分区添加到 Metastore(数据存在,但元数据信息不存在的场景)
2、DROP PARTITIONS 选项将从 Metastore 中删除分区信息,该数据已从 HDFS 中删除(即数据不存在,但元数据信息仍保留的场景)。
3、SYNC PARTITIONS 选项相当于同时调用 ADD 和 DROP PARTITIONS
当有大量未跟踪的分区时,可以提供批量运行 MSCK REPAIR TABLE 以避免 OOME(内存不足错误),可以配置hive.msck.repair.batch.size参数来调节批处理大小,该属性的默认值为零,这意味着它将一次执行所有分区。不带 REPAIR 选项的 MSCK 命令可用于查找有关元数据不匹配元存储的详细信息。
注意:从 Hive 1.3 开始,如果在 HDFS 上找到分区值中包含不允许字符的目录,MSCK 命令将抛出异常,可以在客户端使用hive.msck.path.validation来避免该错误,其参数值"skip"将跳过这些非法目录,其参数值"ignore"会尝试创建分区,这个值可能不会生效。
二、底层实现
其实Msck是属于DDL任务,那么在对该命令解析的时候会转化为DDLTask任务并调用响应的msck方法来进行元数据修复。
在Hive2.4,3.0+之后,hive不仅仅支持添加丢失的分区,如果有任何分区存在于 Metastore 但不在 FileSystem 上,Hive还会删除它们,以便真正修复表元数据。
三、扩展点
3.1、分区发现 Discover Partitions(Hive.4.0)
自动发现并同步 Hive Metastore 中分区的元数据。创建外部分区表时,会自动添加“discover.partitions”=“true” 表属性。对于托管分区表,可以手动添加“discover.partitions”表属性。当 Hive Metastore 服务 (HMS) 在远程服务模式下启动时,后台线程 (PartitionManagementTask) 会每 300 秒定期安排一次(可通过 metastore.partition.management.task.frequency配置进行配置),以查找带有“discover.partitions”表的表属性设置为 true 并在同步模式下执行 msck 修复。如果该表是事务表,则在执行 msck 修复之前为该表获取排他锁。使用此表属性,不再需要手动运行“MSCK REPAIR TABLE table_name SYNC PARTITIONS”。
3.2、分区保留 Partition Retention(Hive.4.0)
现在可以为具有保留间隔的分区表指定表属性“partition.retention.period”。当指定了保留时间间隔时,在 HMS 中运行的后台线程将检查分区的年龄(创建时间),如果分区的年龄比保留期早,它将被删除。在保留期之后删除分区也会删除该分区中的数据。例如,如果使用表属性“discover.partitions”=“true”和“partition.retention.period”=“7d”创建具有“date”分区的外部分区表,则仅保留过去 7 天内创建的分区.