jdbc—批量插入impala占用了太多时间

jutyujz0  于 2021-06-26  发布在  Impala
关注(0)|答案(1)|浏览(505)

我使用impalajdbc驱动程序将数据批量插入impala。我目前的批处理大小为1000,并使用insert into values子句by preparedstatement执行批处理查询。impala守护进程在3台机器上运行,impala目录服务器、状态存储在第4台机器上运行。
impala上的批插入查询计划如下所示:

Query Timeline: 35s398ms
   - Query submitted: 0.000ns (0.000ns)
   - Planning finished: 34s822ms (34s822ms)
   - Submit for admission: 34s886ms (63.997ms)
   - Completed admission: 34s886ms (0.000ns)
   - Ready to start 1 fragment instances: 34s886ms (0.000ns)
   - All 1 fragment instances started: 34s958ms (71.997ms)
   - DML data written: 35s082ms (123.996ms)
   - DML Metastore update finished: 35s286ms (203.993ms)
   - Request finished: 35s298ms (11.999ms)
   - Unregister query: 35s374ms (75.997ms)
 - ComputeScanRangeAssignmentTimer: 0.000ns

正如我们所看到的,计划的完成需要花费所有的时间。我们已经尝试了两种格式,Parquet以及正常创建。但是每次计划完成的部分都太高了。
我需要更改配置吗?还是我做错了什么?

dauxcl2d

dauxcl2d1#

首先要注意的是,即使您使用的是单个 PreparedStatement 在批处理中,每一行仍将获得自己的insert语句。例如,准备好的语句

INSERT INTO t VALUES (?, ?);

将插入两行作为

INSERT INTO t VALUES ('a', 1);
INSERT INTO t VALUES ('b', 2);

而不是

INSERT INTO t VALUES ('a', 1), ('b', 2);

接下来要考虑的是,在hadoop中插入一行是非常低效的,因为必须为每一行创建一个新的hdfs文件。
摘自 Impala 文献:
这个 INSERT ... VALUES 这种技术不适合将大量数据加载到基于hdfs的表中,因为insert操作无法并行化,并且每个操作都会生成一个单独的数据文件。使用它来设置小维度表或少量数据,以试验sql语法或hbase表。不要将它用于大型etl作业或负载操作的基准测试。不要用成千上万的代码运行脚本 INSERT ... VALUES 每次插入一行的语句。如果你真的跑了 INSERT ... VALUES 将数据作为etl管道中的一个阶段加载到暂存表中的操作,如果可能,在每个阶段中包含多个行值 VALUES 子句,并使用一个单独的数据库,以便在该操作确实生成许多小文件时更轻松地进行清理。

相关问题