Hive导入数据的四种方法

本文介绍了Hive中四种常见的数据导入方式,包括从本地文件系统、HDFS导入数据,从其他表查询导入数据,以及在创建表时通过查询导入数据。

Hive的几种常见的数据导入方式
这里介绍四种:
1)、从本地文件系统中导入数据到Hive表;
2)、从HDFS上导入数据到Hive表;
3)、从别的表中查询出相应的数据并导入到Hive表中;
4)、在创建表的时候通过从别的表中查询出相应的记录并插入到所创建的表中。


一、从本地文件系统中导入数据到Hive



先在Hive里面创建好表,如下:

1. hive> create table wyp

2.     > (id int, name string,

3.     > age int, tel string)

4.     > ROW FORMAT DELIMITED

5.     > FIELDS TERMINATED BY '\t'

6.     > STORED AS TEXTFILE;

7. OK

8. Time taken: 2.832 seconds


这个表很简单,只有四个字段,具体含义我就不解释了。本地文件系统里面有个/home/wyp/wyp.txt文件,内容如下:

1. [wyp@master ~]$ cat wyp.txt

2. 1       wyp    25      13188888888888

3. 2       test    30     13888888888888

4. 3       zs     34      899314121


wyp.txt
文件中的数据列之间是使用\t分割的,可以通过下面的语句将这个文件里面的数据导入到wyp表里面,操作如下:

1. hive> load data local inpath 'wyp.txt' into table wyp;

2. Copying data from file:/home/wyp/wyp.txt

3. Copying file: file:/home/wyp/wyp.txt

4. Loading data to table default.wyp

5. Table default.wyp stats:

6. [num_partitions: 0, num_files: 1, num_rows: 0,total_size: 67]

7. OK

8. Time taken: 5.967 seconds


这样就将wyp.txt里面的内容导入到wyp表里面去了,可以到wyp表的数据目录下查看,如下命令:

1. hive> dfs -ls /user/hive/warehouse/wyp ;

2. Found 1 items

3. -rw-r--r--3 wyp supergroup 67 2014-02-19 18:23/hive/warehouse/wyp/wyp.txt


需要注意的是:

和我们熟悉的关系型数据库不一样,Hive现在还不支持在insert语句里面直接给出一组记录的文字形式,也就是说,Hive并不支持INSERT INTO …. VALUES形式的语句。

二、HDFS上导入数据到Hive



  从本地文件系统中将数据导入到Hive表的过程中,其实是先将数据临时复制到HDFS的一个目录下(典型的情况是复制到上传用户的HDFS home目录下,比如/home/wyp/),然后再将数据从那个临时目录下移动(注意,这里说的是移动,不是复制!)到对应的Hive表的数据目录里面。既然如此,那么Hive肯定支持将数据直接从HDFS上的一个目录移动到相应Hive表的数据目录下,假设有下面这个文件/home/wyp/add.txt,具体的操作如下:

1. [wyp@master /home/q/hadoop-2.2.0]$bin/hadoop fs -cat /home/wyp/add.txt

2. 5       wyp1    23     131212121212

3. 6       wyp2    24     134535353535

4. 7       wyp3    25     132453535353

5. 8       wyp4    26     154243434355


上面是需要插入数据的内容,这个文件是存放在HDFS/home/wyp目录(和一中提到的不同,一中提到的文件是存放在本地文件系统上)里面,我们可以通过下面的命令将这个文件里面的内容导入到Hive表中,具体操作如下:

1. hive> load data inpath '/home/wyp/add.txt' into tablewyp;

2. Loading data to table default.wyp

3. Table default.wyp stats:

4. [num_partitions: 0, num_files: 2, num_rows: 0,total_size: 215]

5. OK

6. Time taken: 0.47 seconds

7.  

8. hive> select * from wyp;

9. OK

10.5       wyp1    23     131212121212

11.6       wyp2    24     134535353535

12.7       wyp3    25     132453535353

13.8       wyp4    26     154243434355

14.1       wyp    25      13188888888888

15.2       test    30     13888888888888

16.3       zs     34      899314121

17.Time taken: 0.096 seconds, Fetched: 7 row(s)


从上面的执行结果我们可以看到,数据的确导入到wyp表中了!请注意load data inpath ‘/home/wyp/add.txt’ intotable wyp;里面是没有local这个单词的,这个是和一中的区别。

三、从别的表中查询出相应的数据并导入到Hive表中



假设Hive中有test表,其建表语句如下所示:

1. hive> create table test(

2.     > id int, name string

3.     > ,tel string)

4.     > partitioned by

5.     > (age int)

6.     > ROW FORMAT DELIMITED

7.     > FIELDS TERMINATED BY '\t'

8.     > STORED AS TEXTFILE;

9. OK

10.Time taken: 0.261 second


大体和wyp表的建表语句类似,只不过test表里面用age作为了分区字段。对于分区,这里在做解释一下:

分区:在Hive中,表的每一个分区对应表下的相应目录,所有分区的数据都是存储在对应的目录中。比如wyp表有dtcity两个分区,则对应dt=20131218,city=BJ对应表的目录为/user/hive/warehouse/dt=20131218/city=BJ,所有属于这个分区的数据都存放在这个目录中。


下面语句就是将wyp表中的查询结果并插入到test表中:

1. hive> insert into table test

2.     > partition (age='25')

3.     > select id, name, tel

4.     > from wyp;

5. #####################################################################

6.            这里输出了一堆Mapreduce任务信息,这里省略

7. #####################################################################

8. Total MapReduce CPU Time Spent: 1 seconds 310 msec

9. OK

10.Time taken: 19.125 seconds

11. 

12.hive> select * from test;

13.OK

14.5       wyp1   131212121212    25

15.6       wyp2   134535353535    25

16.7       wyp3   132453535353    25

17.8       wyp4   154243434355    25

18.1       wyp    13188888888888  25

19.2       test   13888888888888  25

20.3       zs     899314121       25

21.Time taken: 0.126 seconds, Fetched: 7 row(s)

这里做一下说明:
我们知道我们传统数据块的形式insertinto table values(字段1,字段2),这种形式hive是不支持的。


通过上面的输出,我们可以看到从wyp表中查询出来的东西已经成功插入到test表中去了!如果目标表(test)中不存在分区字段,可以去掉partition(age=’25′)语句。当然,我们也可以在select语句里面通过使用分区值来动态指明分区:

1. hive> set hive.exec.dynamic.partition.mode=nonstrict;

2. hive> insert into table test

3.     > partition (age)

4.     > select id, name,

5.     > tel, age

6.     > from wyp;

7. #####################################################################

8.            这里输出了一堆Mapreduce任务信息,这里省略

9. #####################################################################

10.Total MapReduce CPU Time Spent: 1 seconds 510 msec

11.OK

12.Time taken: 17.712 seconds

13. 

14. 

15.hive> select * from test;

16.OK

17.5       wyp1   131212121212    23

18.6       wyp2   134535353535    24

19.7       wyp3   132453535353    25

20.1       wyp    13188888888888  25

21.8       wyp4   154243434355    26

22.2       test   13888888888888  30

23.3       zs     899314121       34

24.Time taken: 0.399 seconds, Fetched: 7 row(s)


这种方法叫做动态分区插入,但是Hive中默认是关闭的,所以在使用前需要先把hive.exec.dynamic.partition.mode设置为nonstrict。当然,Hive也支持insertoverwrite方式来插入数据,从字面我们就可以看出,overwrite是覆盖的意思,是的,执行完这条语句的时候,相应数据目录下的数据将会被覆盖!而insert into则不会,注意两者之间的区别。例子如下:

1. hive> insert overwrite table test

2.     > PARTITION (age)

3.     > select id, name, tel, age

4.     > from wyp;


更可喜的是,Hive还支持多表插入,什么意思呢?在Hive中,我们可以把insert语句倒过来,把from放在最前面,它的执行效果和放在后面是一样的,如下:

1. hive> show create table test3;

2. OK

3. CREATE  TABLE test3(

4.   id int,

5.   name string)

6. Time taken: 0.277 seconds, Fetched: 18 row(s)

7.  

8. hive> from wyp

9.     > insert into table test

10.    > partition(age)

11.    > select id, name, tel, age

12.    > insert into table test3

13.    > select id, name

14.    > where age>25;

15. 

16.hive> select * from test3;

17.OK

18.8       wyp4

19.2       test

20.3       zs

21.Time taken: 4.308 seconds, Fetched: 3 row(s)


可以在同一个查询中使用多个insert子句,这样的好处是我们只需要扫描一遍源表就可以生成多个不相交的输出。这个很酷吧!

四、在创建表的时候通过从别的表中查询出相应的记录并插入到所创建的表中



在实际情况中,表的输出结果可能太多,不适于显示在控制台上,这时候,将Hive的查询输出结果直接存在一个新的表中是非常方便的,我们称这种情况为CTAScreate table .. as select)如下:

1. hive> create table test4

2.     > as

3.     > select id, name, tel

4.     > from wyp;

5.  

6. hive> select * from test4;

7. OK

8. 5       wyp1   131212121212

9. 6       wyp2   134535353535

10.7       wyp3   132453535353

11.8       wyp4   154243434355

12.1       wyp    13188888888888

13.2       test   13888888888888

14.3       zs     899314121

15.Time taken: 0.089 seconds, Fetched: 7 row(s) 

数据就插入到test4表中去了,CTAS操作是原子的,因此如果select查询由于某种原因而失败,新表是不会创建的!

 

<think> 首先,用户的问题是:“解决hive导入数据卡住问题的方法”。用户提到参考了站内引用,这些引用提供了有关Hive导入数据问题的信息。 回顾引用: - 引用[1]:讨论Sqoop导入数据Hive时的错误,具体是FAILED: Execution Error, return code 2。 - 引用[2]:Sqoop从MySQL导入数据Hive报错Hive exited with status 64,涉及SessionHiveMetaStoreClient无法实例化。 - 引用[3]:Hive删除表或导入数据卡死,涉及锁机制(共享锁和互斥锁),并提到解锁表的命令。 - 引用[4]:Java程序向Hive导入数据方法,使用HDFS复制。 用户特别说:“我想查找解决hive导入数据卡住问题的方法”,并引用了这些内容。因此,我的回答应该聚焦在解决Hive导入数据卡顿或卡死的问题。 系统级指令: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,如[^1]。 - 回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 所以,我需要构建一个结构清晰的回答,解决Hive导入数据卡住的问题,基于提供的引用。 关键点从引用中提取: - 引用[3]直接提到“Hive删除表或导入数据卡死”,并讨论了锁机制。建议解锁表或关闭锁机制。 - 其他引用涉及Sqoop导入错误,但用户的问题是导入数据卡住,可能与锁相关。 可能的解决方法: 1. **检查锁机制**:Hive的锁可能导致操作卡死。使用`show locks`命令查看是否有锁,然后`unlock table table_name`解锁[^3]。 2. **关闭锁机制**:如果锁是问题,可以临时关闭锁机制[^3]。 3. **检查MetaStore问题**:引用[2]提到SessionHiveMetaStoreClient无法实例化,这可能与Hive服务或配置相关。确保Hive Metastore服务运行正常。 4. **资源或配置问题**:导入卡住可能由于资源不足(如内存、CPU)、网络问题或配置错误。 5. **Sqoop相关问题**:如果使用Sqoop,错误如return code 2或status 64可能需要检查Sqoop作业日志、连接问题等。 6. **其他方法**:引用[4]展示了Java程序导入数据到HDFS,然后加载到Hive,这可以是替代方法。 结构化回答: - 逐步解决问题:从简单到复杂。 1. **初步检查**:确保Hive服务正常运行,网络连接良好。 2. **检查锁状态**:使用Hive命令检查并解锁。 3. **查看日志**:分析Hive导入工具的日志以定位错误。 4. **优化配置**:调整Hive配置以减少锁或资源争用。 5. **替代导入方法**:如直接加载数据到HDFS然后到Hive。 生成相关问题: - 基于主题,生成2-3个相关问题,放在最后。 添加引用标识: - 在回答中,当引用特定内容时,添加[^n],如[^3] for lock mechanism. 确保回答真实可靠:基于提供的引用和一般知识。既然引用是给定的,我应该主要依赖它们。 最终回答结构: 1. **介绍问题**:简述Hive导入数据卡住的常见原因。 2. **逐步解决方法**: - 步骤1: 检查并处理锁机制。 - 步骤2: 检查Hive Metastore服务。 - 步骤3: 查看日志文件。 - 步骤4: 优化配置或资源。 - 步骤5: 尝试替代导入方法。 3. **总结**。 4. **相关问题**。 使用中文。 </think>以下是针对Hive导入数据卡住问题的逐步解决方法Hive导入数据卡顿或卡死通常由锁机制冲突、元数据服务异常、资源不足或配置错误引起。基于您提供的引用(特别是引用[3]关于锁机制的关键信息),我将从最常见原因入手,逐步指导您排查和解决。解决过程需结合Hive命令行、日志分析和配置调整,确保操作真实可靠。 ### 步骤1: 检查并处理Hive锁机制(最常见原因) Hive的锁机制(共享锁和互斥锁)可能导致导入操作卡死,尤其在并发访问时。如果其他进程持有表的互斥锁(Exclusive Lock),导入任务会被阻塞。 - **检查锁状态**: 在Hive命令行中执行: ```sql SHOW LOCKS table_name; -- 替换table_name为您的表名 ``` 如果输出显示`Exclusive`锁状态,说明有锁冲突[^3]。 - **解锁表**: ```sql UNLOCK TABLE table_name; -- 解锁指定表 ``` 如果问题持续,尝试临时关闭锁机制(生产环境慎用): ```bash set hive.support.concurrency=false; -- 在Hive会话中关闭锁机制 ``` 引用[3]指出,关闭锁机制可避免并发问题,但可能影响数据一致性,建议测试后使用[^3]。 - **预防锁冲突**: - 避免在导入期间执行`DROP TABLE`或`ALTER TABLE`等触发互斥锁的操作。 - 优化查询并发度,例如通过`set hive.lock.numretries=10;`增加锁重试次数。 ### 步骤2: 验证Hive Metastore服务 如果锁无冲突,但导入卡死,可能因Hive Metastore服务异常(如SessionHiveMetaStoreClient无法实例化)。引用[2]显示这会导致导入失败(如Hive exited with status 64)[^2]。 - **检查Metastore服务**: 在Hive服务器上运行: ```bash hive --service metastore status # 检查服务状态 ``` 如果服务未运行,启动它: ```bash hive --service metastore start # 启动Metastore服务 ``` - **修复元数据**: - 确保`hive-site.xml`配置正确,特别是`hive.metastore.uris`。 - 运行元数据检查工具: ```bash schematool -dbType derby -validate # 如使用Derby数据库 ``` 如果元数据损坏,考虑备份后重新初始化。 ### 步骤3: 分析日志定位错误 导入卡住时,日志是诊断关键。查看Hive和底层工具(如Sqoop或MapReduce)的日志。 - **查找Hive日志**: 默认路径为`/tmp/<username>/hive.log`或`$HIVE_HOME/logs`。重点检查: - 错误关键字如`org.apache.hadoop.hive.ql.metadata.HiveException`(引用[2]中提到)或`MapRedTask failure`(引用[1]中的return code 2)[^1][^2]。 - 锁相关信息,如`Waiting for lock...`。 - **检查导入工具日志**: - 如果使用Sqoop(如引用[1][^2]),查看Sqoop作业日志: ```bash sqoop import --connect ... --verbose # 添加verbose参数输出详细日志 ``` - 如果使用Java程序(如引用[4]),检查程序日志中的异常堆栈[^4]。 ### 步骤4: 优化资源与配置 资源不足(内存、CPU)或配置错误可能导致卡顿。尤其在高负载集群中。 - **调整资源设置**: - 在Hive中增加执行资源: ```sql set mapreduce.map.memory.mb=4096; -- 增加Map任务内存 set mapreduce.reduce.memory.mb=8192; -- 增加Reduce任务内存 ``` - 限制并发任务数: ```sql set hive.exec.parallel.thread.number=4; -- 减少并行度,避免资源争用 ``` - **检查HDFS健康**: - 确保HDFS有足够空间:`hdfs dfs -df -h`。 - 如果导入涉及HDFS(如引用[4]的Java方法),验证网络和权限: ```bash hdfs dfs -ls /target_path # 检查目标路径可写性 ``` 引用[4]显示,HDFS复制失败可能导致卡顿,确保配置正确[^4]。 ### 步骤5: 尝试替代导入方法 如果上述步骤无效,改用更稳定的数据导入方式: - **直接加载数据到HDFS后导入Hive**: 1. 先将数据上传到HDFS(如引用[4]的Java方法或使用`hdfs dfs -put`)[^4]。 2. 在Hive中加载数据: ```sql LOAD DATA INPATH '/hdfs/path/data.csv' INTO TABLE table_name; ``` 这避免中间工具(如Sqoop)的潜在问题。 - **使用其他工具**: - 如果Sqoop报错(如引用[1][^2]),尝试更新驱动包或切换工具,如Apache NiFi。 ### 总结 解决Hive导入数据卡住需系统性排查:先处理锁冲突(步骤1),再检查Metastore服务(步骤2),通过日志分析(步骤3)定位根源,最后优化资源(步骤4)或换用方法(步骤5)。多数情况下,锁机制是主因(引用[3])。如果问题持续,提供详细日志片段以进一步诊断。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值