我使用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以及正常创建。但是每次计划完成的部分都太高了。
我需要更改配置吗?还是我做错了什么?
1条答案
按热度按时间dauxcl2d1#
首先要注意的是,即使您使用的是单个
PreparedStatement
在批处理中,每一行仍将获得自己的insert语句。例如,准备好的语句将插入两行作为
而不是
接下来要考虑的是,在hadoop中插入一行是非常低效的,因为必须为每一行创建一个新的hdfs文件。
摘自 Impala 文献:
这个
INSERT ... VALUES
这种技术不适合将大量数据加载到基于hdfs的表中,因为insert操作无法并行化,并且每个操作都会生成一个单独的数据文件。使用它来设置小维度表或少量数据,以试验sql语法或hbase表。不要将它用于大型etl作业或负载操作的基准测试。不要用成千上万的代码运行脚本INSERT ... VALUES
每次插入一行的语句。如果你真的跑了INSERT ... VALUES
将数据作为etl管道中的一个阶段加载到暂存表中的操作,如果可能,在每个阶段中包含多个行值VALUES
子句,并使用一个单独的数据库,以便在该操作确实生成许多小文件时更轻松地进行清理。