如何在不删除源文件的情况下将数据从 HDFS 加载到配置单元?

Posted

技术标签:

【中文标题】如何在不删除源文件的情况下将数据从 HDFS 加载到配置单元?【英文标题】:How to load data to hive from HDFS without removing the source file? 【发布时间】:2011-11-25 22:13:13 【问题描述】:

当从 HDFS 加载数据到 Hive 时,使用

LOAD DATA INPATH 'hdfs_file' INTO TABLE tablename;

命令,看起来它正在将 hdfs_file 移动到 hive/warehouse 目录。 是否可以(如何?)复制它而不是移动它,以便文件被另一个进程使用。

【问题讨论】:

【参考方案1】:

根据您的问题,我假设您已经将数据保存在 hdfs 中。 所以你不需要LOAD DATA,它将文件移动到默认的配置单元位置/user/hive/warehouse。您可以使用externalkeyword 简单地定义表,它将文件留在原处,但在 hive 元存储中创建表定义。看这里: Create Table DDL 例如:

create external table table_name (
  id int,
  myfields string
)
location '/my/location/in/hdfs';

请注意,您使用的格式可能与默认格式不同(正如 jigneshRawal 在 cmets 中提到的那样)。您可以使用自己的分隔符,例如在使用 Sqoop 时:

row format delimited fields terminated by ','

【讨论】:

DAG,我对此有疑问。当使用“创建表”注释创建 Hive 表时,文件将从 HDFS 位置移动到 '/User/Hive/warehouse/Table/' 。这个新位置是否也位于 HDFS 上?或者它只是一个本地目录。我假设它也应该是一个 HDFS 位置?我说的对吗? 当你执行一个简单的create table 时没有数据被移动,并且在仓库目录中的HDFS中创建了表。 AFAIK 给出 LOCATION 时,数据在 HDFS 内移动,但未使用 external 关键字。 (但我可能错了,请自己重新检查) @Dag 我尝试了上述使用关键字“EXTERNAL”创建表的方法,但它第一次创建了所有值都为 NULL 的表。创建表模式时需要添加以下行。以“,”结尾的行格式分隔字段。如果我错了,请纠正我。 @JigneshRawal 这是一个非常特殊的情况,不应该应用于 Dag 的解决方案。您也不应该在架构创建中使用该语句,而是在外部或托管的表创建中使用 @Dag,我会考虑添加Jignesh 提到的内容,因为这似乎是许多Sqoop 教程中使用的默认存储格式。您可以将其添加为额外的警告。【参考方案2】:

我发现,当您同时使用 EXTERNAL TABLE 和 LOCATION 时,Hive 会创建表并且最初不会显示任何数据(假设您的数据位置与 Hive 的“LOCATION”不同)。

当您使用“LOAD DATA INPATH”命令时,数据会从数据位置移动(而不是复制)到您在创建 Hive 表时指定的位置。

如果在创建 Hive 表时未指定位置,则它使用内部 Hive 仓库位置,数据将从您的源数据位置移动到内部 Hive 数据仓库位置(即 /user/hive/warehouse/)。

【讨论】:

【参考方案3】:

可以使用“加载数据”的替代方法,其中数据不会从现有源位置移动到 Hive 数据仓库位置。

您可以使用带有“LOCATION”选项的 ALTER TABLE 命令。下面是所需的命令

ALTER TABLE table_name ADD PARTITION (date_col='2017-02-07') LOCATION 'hdfs/path/to/location/'

这里唯一的条件是,位置应该是目录而不是文件。

希望这能解决问题。

【讨论】:

只有当创建的表是EXTERNAL表时才有效。

以上是关于如何在不删除源文件的情况下将数据从 HDFS 加载到配置单元?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ROOM 库在不阻塞 UI 的情况下将数千条记录从本地数据库加载到 recyclerview

在不使用 S3 存储桶的情况下将数据从远程服务器的 .gz 文件加载到 redshift 的 postgresql 实例?

如何在不先加载到 RAM 的情况下将文件加载到 blob 中?

如何在不创建架构的情况下将 CSV 文件加载到 BigQuery

在不知道类型的情况下将程序集从文件加载到自定义 AppDomain

如何在不使用 .get() 或 .load() 的情况下将 ajax 数据加载到 DIV?