2013-03-07 32 views
10

我有以HDFS文本形式存儲的日誌文件。當我將日誌文件加載到Hive表中時,所有文件都被複制。是否可以在不復制數據的情況下將數據導入Hive表中

我可以避免將所有文本數據存儲兩次嗎?

編輯:我通過以下命令加載它

LOAD DATA INPATH '/user/logs/mylogfile' INTO TABLE `sandbox.test` PARTITION (day='20130221') 

然後,我能找到完全相同的文件中:

/user/hive/warehouse/sandbox.db/test/day=20130220 

我以爲它被複制。

+0

How do you say,它的複製?你如何將它們加載到配置單元表中? – 2013-03-07 12:26:12

+0

我通過'LOAD DATA INPATH'xxx'INTO TABLE yyy'(見文章編輯)加載它,然後在'/ user/hive/warehouse'中找到該文件。我想知道它是否可以離開它(我想我將不得不在我的目錄中強制執行分區結構,但這很好) – 2013-03-07 13:11:39

+0

它如何存儲在HDFS中? – 2013-03-07 13:12:08

回答

14

使用外部表:

CREATE EXTERNAL TABLE sandbox.test(id BIGINT, name STRING) ROW FORMAT 
       DELIMITED FIELDS TERMINATED BY ',' 
       LINES TERMINATED BY '\n' 
       STORED AS TEXTFILE 
       LOCATION '/user/logs/'; 

,如果你想使用分區與外部表,你將負責管理該分區的目錄。 指定的位置必須是hdfs目錄..

如果刪除外部表格配置單元不會刪除源數據。 如果想要管理你的原始文件,請使用外部表格。如果您希望配置單元執行此操作,請將倉庫路徑中的配置單元存儲。

+0

正是我在找的東西!謝謝 – 2013-03-08 09:25:12

3

我可以說,不是將你的Java應用程序直接將數據複製到HDFS,而是將這些文件放在本地文件系統中,然後使用以下命令通過配置單元將它們導入HDFS。

LOAD DATA LOCAL INPATH '/your/local/filesystem/file.csv' INTO TABLE `sandbox.test` PARTITION (day='20130221') 

通知的LOCAL

+0

謝謝,這確實會起作用。另一個(效率較低)選項是刪除原始文件。那麼我想答案是:不,你不能告訴配置單元將數據保留在原來的位置,只是假設它是一個表格。由於這些文件非常大,因此Java應用程序通過Hadoop庫直接寫入HDFS。我可以用Java to Hive連接器做同樣的事情嗎?或者,如果我通過HDFS API寫入適當的hive目錄,Hive會認爲它是數據文件嗎? – 2013-03-07 13:44:16

+1

關於最後一部分。是的,如果你將文件直接放在HIVE倉庫中,日期將在HIVE中可用,請記住從表格的定義中適合文件夾結構(http://stackoverflow.com/questions/15077046/using-multiple-levels-of- partition-in-hive/15102064#15102064) – www 2013-03-07 14:33:58

0

您可以使用alter table分區語句來避免數據重複。

create External table if not exists TestTable (testcol string) PARTITIONED BY (year INT,month INT,day INT) row format delimited fields terminated by ','; 

ALTER table TestTable partition (year='2014',month='2',day='17') location 'hdfs://localhost:8020/data/2014/2/17/'; 
0

Hive(至少當以真正集羣模式運行時)不能引用本地文件系統中的外部文件。 Hive可以在表創建或加載操作期間自動導入文件。這背後的原因可能是Hive在內部運行MapReduce作業來提取數據。 MapReduce從HDFS中讀取並寫回到HDFS,甚至在分佈式模式下運行。因此,如果文件存儲在本地文件系統中,則分佈式基礎架構不能使用它。

相關問題