Hive/Impala批量插入数据

摘要:
问题描述包含数千个数据,需要将这些数据插入到相应的Hive/Inpala表中。它比在MySQL中批量插入数据要慢得多,所以我抱怨Impala不容易用于问题分析。首先,必须清楚的是,无论是在MySQL还是在分布式组件Hive和Impala中,将每个数据处理成insert语句的方式都是最低效的。步骤2:要上传数据文件,首先清除测试。再次测试批插入然后,上传文件:hdfsdfs-putst。txt/user/hhive/warehouse/test-db/test_batch_insert此时,您应该能够直接查询配置单元表中的数据。下表需要在impala shell命令行窗口中进行刷新测试:刷新测试批处理插入;然后,我们得到了……事实上,hive/impa与MySQL相似,具有相应的loaddata语句

问题描述

现有几千条数据,需要插入到对应的Hive/Impala表中。安排给了一个同事做,但是等了好久,反馈还没有插入完成……看到他的做法是:对每条数据进行处理转换为对应的insert语句,但是,实际执行起来,速度很慢,每条数据都要耗时1s左右。比在MySQL中批量插入数据慢多了,因而抱怨Impala不太好用

问题分析

首先,必须明确的是,把每条数据处理成insert语句的方式,肯定是最低效的,不管是在MySQL中,还是在分布式组件Hive、Impala中。

这种方式的资源消耗,更多的花在了连接、SQL语句的解析、执行计划生成上,实际插入数据的开销还是相对较少的。

所以,要提高批量数据的插入,关键是减少无谓的资源开销,提高一条SQL的吞吐率,即通过尽量少的SQL条数,插入更多的数据。

解决方案

测试数据:

aaa
bbb
ccc
ddd
eee
fff
ggg
hhh
iii
jjj

测试表:

create table if not exists test.test_batch_insert(
    f1 string
) comment 'test for batch insert'
row format delimited fields terminated by '	' lines terminated by '
'
stored as textfile;

方案1(最慢的):数据转换为insert语句

step1:处理成sql语句

vim中:
%s/^/insert into test.test_batch_insert select '/g
%s/$/';/g
 
 
或者使用awk:
awk '{printf "insert into test.test_batch_insert select "%s";
", $0}' test.txt > test.sql

生成的SQL脚本:

insert into test.test_batch_insert select "aaa";
insert into test.test_batch_insert select "bbb";
insert into test.test_batch_insert select "ccc";
insert into test.test_batch_insert select "ddd";
insert into test.test_batch_insert select "eee";
insert into test.test_batch_insert select "fff";
insert into test.test_batch_insert select "ggg";
insert into test.test_batch_insert select "hhh";
insert into test.test_batch_insert select "iii";
insert into test.test_batch_insert select "jjj";

step2:执行生成的SQL脚本

impala-shell -i data1 -f test.sql

一条条执行,比较慢……

方案2(相对快点):一条SQL尽量插入多条数据

step1:转换成SQL

awk 'BEGIN{print "insert into test.test_batch_insert"; i=1; n=10} {if(i<n){ printf "select "%s" union
", $0; i++} else {printf "select "%s";", $0}}' test.txt > test2.sql
 
 
vim %s 或者 sed也行

生成的SQL脚本:

insert into test.test_batch_insert
select "aaa" union
select "bbb" union
select "ccc" union
select "ddd" union
select "eee" union
select "fff" union
select "ggg" union
select "hhh" union
select "iii" union
select "jjj";

step2:执行生成的SQL

执行前,先清空表;

impala-shell -i data1 -f test2.sql

执行之后,会发现,不止快了一点点……

但是,这种方式有局限……

因为,一条SQL的长度是有限制的,数据量大了,只生成一条SQL,会导致超长,无法执行。此时,可以考虑分割文件:

split -l 500 test.txt test_split_

然后,编写脚本遍历每个文件分片,重复上述操作即可。

方案3(最快的,如果你没有更好的)

step1:首先查看下test.test_batch_insert的建表语句:

impala-shell -i data1 -B -q "show create table test.test_batch_insert"

建表语句如下:

Query: show create table test.test_batch_insert
"CREATE TABLE test.test_batch_insert (
  f1 STRING
)
 COMMENT 'test for batch insert'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '	' LINES TERMINATED BY '
'
WITH SERDEPROPERTIES ('field.delim'='	', 'line.delim'='
', 'serialization.format'='	')
STORED AS TEXTFILE
LOCATION 'hdfs://xxxxxx:8020/user/hive/warehouse/test.db/test_batch_insert'
"

关注一下LOCATION属性,在HDFS上查看下该路径:

hdfs dfs -ls /user/hive/warehouse/test.db/test_batch_insert

然后,看下文件内容:

hdfs dfs -cat /user/hive/warehouse/test.db/test_batch_insert/*data.0.

发现了吧,就是可读的纯文本文件,每行都是一条数据。因为前面建表的时候,就指定了用 作为记录分隔符。

看到这里,聪明的你,应该知道我接下来要做什么了……

step2:上传数据文件

首先,再次清空test.test_batch_insert;

然后,上传文件:

hdfs dfs -put test.txt /user/hive/warehouse/test.db/test_batch_insert

此时,在hive表中,应该能直接查询到数据了,impala中还需要刷新下表:

impala-shell命令行窗口中执行:
refresh test.test_batch_insert;

然后,搞定了……

其实,hive/impla类似于MySQL,有对应的load data的语句……这里只是把load data语句实际干的事展示了一下……

免责声明:文章转载自《Hive/Impala批量插入数据》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇element table显示滚动条如何用myeclipse和eclipse搭建安卓开发环境下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

从.dat文件向Sql Server中批量导入数据

从TXT文本文档向Sql Server中批量导入数据       因为工作的需要,近期在做数据的分析和数据的迁移。在做数据迁移的时候需要将原有的数据导入到新建的数据库中。本来这个单纯的数据导入导出是没有什么问题的,但是客户原有的数据全部都是存在.dat文件中的。所以解决方案如下     一、首先用数据库查看工具Database System Utility...

JSON.stringify 后数据丢失

最近遇到了JSON.stringify 序列化对象后,数据丢失问题,之前用这个函数一直没出过问题,这次出问题了,而且卡了很久,所以记录下 情景如下: var a =[]; a.push(42); a.foo = 'bar'; console.log(a)     console.log(JSON.stringify(a)); 会发现a 对象明明有个 43...

分布式架构数据常见问题阅读总结

域是一个虚拟的分类,几个系统属于某一个域,例如网上银行和手机银行都属于电子渠道领域; 传统的单体应用,指的就是系统,在微服务架构下,单体应用采用前后端分离模式,前端一般使用 Nginx,Ngnix 进程间采用主备模式,系统的后端可以分为多个应用,每个应用有一组对等的应用进程(也称为应用实例)提供服务,每个应用对应一个数据库,实际上在分库的情况下,有可能一个...

TDengine在数益工联工业物联采集平台建设中的初步实践

作者:易永耀 夏杭泰 邓炜兴 公司介绍 数益工联致力于打造基于数据流+价值流的离散制造业数字化软件;应用新一代的物联网技术与丰富的现场交互手段,融合工业工程精益思想,为离散制造业客户的数字化升级提供从规划到实施落地的端到端工厂级解决方案;打造行业与客户的工业数据平台,持续提供数据智能服务。核心团队来自清华大学等知名院校,同时拥有深厚的制造业精益运营管理能力...

从excel表中生成批量SQL,将数据录入到数据库中

excel表格中有许多数据,需要将数据导入数据库中,又不能一个一个手工录入,可以生成SQL,来批量操作。      1.首先在第二行的H列,插入函数:=CONCATENATE("INSERT INTO `book` (`bookid`, `title`,  `volume`, `author`, `urlpdf` ) VALUES ('",A2,"'...

Mysql数据表字段设置了默认值,插入数据后默认字段的值却为null,不是默认值

我将mysql的数据表的某个字段设置了默认值为1,当向该表插入数据的时候该字段的值不是默认值,而是null。 我的错误原因: 对数据库的操作我使用了持久化工具mybatis,插入数据的时候插入的是整个实体,直接使用的是持久层的insert(实体对象)方法插入的数据 这样就会出现一个问题,当实体对象中某个属性值为空时,对应的数据库的字段就会插入null值,而...