Pentaho Data Integration (PDI) 如何使用postgresql bulk loader?我的蜕变运行永远

Pentaho Data Integration (PDI) How to use postgresql bulk loader? My transformation running forever

我是 PDI 的新手,我使用的是 PDI 7,我有 excel 6 行输入,想将其插入到 postgresDB 中。我的转换是:EXCEL INPUT --> Postgres Bulk Loader(仅 2 步)。

条件 1:当我 运行 转换时,Postgres Bulk Load 不会停止并且不会向我的 postgresDB 中插入任何内容。

条件 2:因此,我在 Postgres Bulk Loader 之后添加 "Insert/Update" 步骤,并且所有数据都插入到 postgresDB 中,这意味着成功,但是 bulk loader 仍然 运行。

My transformation

从我能得到的所有来源来看,他们只需要输入和Bulk Loader步骤,完成转换后,bulk loader是"finished"(我的"running")。所以,我想问一下如何为 Postgres 正确地做到这一点?我是否跳过了重要的事情?谢谢

PostgreSQL 批量加载器过去只是实验性的。有段时间没试过了。你确定你需要它吗?如果您从 Excel 加载,您不太可能有足够的行来保证使用批量加载程序。

只尝试常规 Table Output 步骤。如果你只是插入,你也不应该需要 Insert/Update 步骤。

要仅插入 7 行,您不需要批量加载程序。 批量加载器旨在加载大量数据。它使用本机 psql 客户端。 PSQL 客户端传输数据的速度要快得多,因为它使用二进制协议的所有功能而不受 jdbc 规范的任何限制。 JDBC 用于其他步骤,如 Table 输出。大部分时间Table输出够用

Postgres Bulk Loader 步骤只是从传入的步骤中以 csv 格式构建内存数据,并将它们传递给 psql 客户端。

我确实做了一些实验。

环境:

  • 数据库:Postgresv9.5x64
  • PDI 水壶 v5.2.0
  • PDI KETTLE 默认 jvm 设置 512mb
  • 数据源:DBF FILE 2_215_000 行
  • PDI 和 Kettle 都在同一个本地主机上
  • Table t运行每个 运行
  • PDI Kettle 在每个 运行 上重新启动(以避免大量 CPU 负载 gc 运行 由于大量行)

下面的结果可以帮助您做出决定

  1. 批量加载器:平均每秒 150_000 行大约 13-15 秒

  2. Table 输出(sql 插入):平均每秒 11_500 行。总时长约为 3 分 18 秒

  3. Table 输出(批量插入,批量大小 10_000):平均每秒 28_000 行。总时长约为 1 分 30 秒

  4. Table 输出(批量插入 5 个线程批量大小 3_000):每个线程平均每秒 7_600 行。意味着每秒大约 37_000 行。总时间约为59秒。

Buld 加载器的优点是不会填满 jmv 的内存,所有数据都会立即流入 psql 进程。

Table 输出用数据填充 jvm 内存。实际上,在大约 1_600_000 行内存已满后,gc 开始了。 CPU 那个时候加载到 100%,速度明显变慢。这就是为什么值得尝试批处理大小,以找到能够提供最佳性能(越大越好)但在某种程度上会导致 GC 开销的值。

上次实验。提供给 jvm 的内存足以容纳数据。这可以在变量 PENTAHO_DI_JAVA_OPTIONS 中进行调整。我将 jvm heap size 的值设置为 1024mb 并增加了 batch size 的值。

  1. Table 输出(批量插入 5 个线程批量大小 10_000):每个线程平均每秒 12_500 行。意味着每秒总计 60_000 行。总时间约为35秒。

现在更容易做出决定。但是你必须注意到一个事实,kettle pdi 和数据库位于同一台主机上。如果主机不同,网络带宽可以对性能起到一定的作用。

慢insert/update步 为什么要避免使用insert/update(以防处理大量数据或时间有限)?

让我们看看文档

The Insert/Update step first looks up a row in a table using one or more lookup keys. If the row can't be found, it inserts the row. If it can be found and the fields to update are the same, nothing is done. If they are not all the same, the row in the table is updated.

在声明之前,流步骤中的每一行将执行 2 个查询。它是先查找,然后更新或插入。 PDI Kettle 的来源声明 PreparedStatement 用于所有查询:插入、更新和查找。

因此,如果这一步是瓶颈,请尝试找出到底是什么慢了。

  • 查找速度慢吗? (运行 根据示例数据在数据库中手动查找查询。检查速度慢吗?查找字段是否在那些用于在数据库中查找对应行的列上有索引)
  • 更新慢吗? (运行 手动查询样本数据的数据库。检查速度很慢?更新 where 子句是否在查找字段上使用索引)

反正这一步很慢,因为它需要大量的网络通信,以及kettle中的数据处理。

让它更快的唯一方法是将数据库中的所有数据加载到 "temp" table 并调用将更新数据的函数。或者只是在工作中使用简单的 sql 步骤来做同样的事情。