HIVE ARCHIVE

由于HDFS的设计,文件系统中的文件数量直接影响namenode中的内存消耗。虽然对于小型集群来说通常不是问题,但是当大于500万到1000万个文件时,内存使用量可能会在单台机器上达到可访问内存的限制。在这种情况下,拥有尽可能少的文件是有利的。
hive中的Archive实际上就是使用Hadoop Archive (HAR),下边先介绍Hadoop Archive (HAR)

Hadoop Archive

Hadoop Archive是一种特殊的归档格式,Hadoop Archive映射到文件系统目录,一个HAR以扩展名.har结尾,一个HAR目录包含元数据(以_index和_masterindex的形式)和data(part- *)文件。 _index文件包含文件名称,这些文件时归档的一部分,并且包含这些文件在归档中的位置。

hadoop archive -archiveName name -p <parent> <src>* <dest>

-archiveName用来指定你想创建的归档名称,parent用来指定需要归档文件的相对路径的父参数。需要注意的是归档是一个map/reduce。如下使用例子:

hadoop archive -archiveName zoo.har -p /foo/bar a/b/c e/f/g /outputdir

在以上例子中/foo/bar是a/b/c, e/f/g的父目录。如果你想直接对一个目录进行归档,可以直接使用如下命令:

hadoop archive -archiveName zoo.har -p /foo/bar /outputdir

档案(archive)属于文件系统层,使用不同的URI,在档案中可以使用所有的fs shell命令,需要注意的是档案是不可变的,不能够被删除,重命名和创建。HAR的URI格式如下所示:

har://scheme-hostname:port/archivepath/fileinarchive

若是没有提供scheme-hostname,它会使用默认的文件系统。这种情况下URI是这种形式:

har:///archivepath/fileinarchive

若是使用如下命令创建档案:

hadoop archive -archiveName foo.har -p /user/hadoop dir1 dir2 /user/zoo

则使用hadoop dfs -ls har:///user/zoo/foo.har命令查看是会显示:

har:///user/zoo/foo.har/dir1
har:///user/zoo/foo.har/dir2

若是使用另外一种方式来创建档案:

hadoop archive -archiveName foo.har -p /user/ hadoop/dir1 hadoop/dir2 /user/zoo

则使用hadoop dfs -ls har:///user/zoo/foo.har命令查看是会显示:

har:///user/zoo/foo.har/hadoop/dir1
har:///user/zoo/foo.har/hadoop/dir2

这就是我们指定-p参数对结果产生的影响。

在mapreduce中使用har是非常容易的,只需要指定不同的输入文件系统而不是默认的文件系统,如果你有一个har存储在hdfs上/user/zoo/foo.har,若是想使用这个档案作为mr的输入,只需要指定输入路径为 har:///user/zoo/foo.har。

要注意到

  • 归档后源文件依然存在,需要手动删除
  • 创建archive文件要消耗和原文件一样多的硬盘空间
  • archive文件一旦创建就无法改变,这就意味这你要改一些东西的话,你需要创新创建archive文件
  • 虽然解决了namenode的内存空间问题,但是在执行mapreduce时,把大量归档的文件交给一个map来处理,这样有时是低效的。

HIVE ARCHIVE

Hadoop Archive是减小分区下文件数据的一种方法,hive支持把已存在的分区转换为HAR,是分区下的文件数目大大减少,但是因为从HAR读数据需要额外的开销,因此查询归档下的数据可能会变慢。
若是使用了归档,以下三个配置文件需要使用。

hive> set hive.archive.enabled=true;
hive> set hive.archive.har.parentdir.settable=true;
hive> set har.partfile.size=1099511627776;

hive.archive.enabled用来控制归档是否可用,hive.archive.har.parentdir.settable通知Hive在创建归档时是否可以设置父目录,这个配置主要是因为在比较老的hadoop版本(2011之前),-p选项是不可用的,因此这个选项需要设置为false。har.partfile.size 控制需要归档文件的大小,使用了这个参数后这个归档将会包含 size_of_partition/har.partfile.size(四舍五入)个文件,这个值越大以为值文件数越小,结果文件数越小以为值归档时的reduce数目越小,需要更多的归档时间。

在配置项设置完之后,就可以使用以下命令进行归档。

ALTER TABLE table_name ARCHIVE PARTITION (partition_col = partition_col_value, partition_col = partiton_col_value, ...)

ALTER TABLE srcpart ARCHIVE PARTITION(ds='2008-04-08', hr='12')

也可以对已归档的分区恢复为原文件。

ALTER TABLE srcpart UNARCHIVE PARTITION(ds='2008-04-08', hr='12')

在一些hadoop版本中,HAR有少量的bug存在,这可能导致数据丢失或者其他错误,具体可参考文献2,
hive中使用归档时需要注意,归档的分区不能够INSERT OVERWRITE,必须先unarchive,若是同时有两个操作尝试归档同样的分区,可能会发生异常(需要实现并发支持)。

参考文献

1.Hadoop Archives Guide
2.LanguageManual Archiving