目录
(2)输入单线程,两个输出,一个单线程、另一个两线程(图6)
Kettle转换中,各步骤之间行集(row set)的发送有分发和复制两种方式,本文讨论这两种方式的区别,以及它们与Kettle多线程的关系。我们用一个简单的例子辅助说明,Kettle版本为8.3。定义一个转换,以t1表作为输入,输出到表t2和t3。t1表中有1-10十个整数。当创建第二个跳(hop)时,会弹出一个警告窗口,如图1所示。

表输入步骤将向两个表输出步骤发送数据行,此时可以选择采用分发或复制两种方式之一,缺省为复制方式。分发方式执行后,t2、t3表的数据如图2所示。

复制方式执行后,t2、t3表的数据如图3所示。

区别一目了然,分发是将数据行依次发给每个输出跳,而复制是将全部数据行发送给所有输出跳。目前这个转换中的所有步骤都以单线程执行。下面看一下多线程的情况。
1. 分发方式
(1)输入两线程,输出单线程

执行后,t2、t3表的数据如图5所示。

可以看到,每个输入线程都以分发方式将数据行依次发给每个输出跳,结果t2表数据为两倍的单数、而t2表数据为两倍的双数。
(2)输入单线程,两个输出,一个单线程、另一个两线程

执行后,t2、t3表的数据如图7所示。

输入线程轮询分发,单线程输出每次写一行,两线程输出每次写两行。
(3)输入单线程、两个输出均为两线程

执行后,t2、t3表的数据如图9所示。

输入线程向两个输出步骤轮询分发数据行,两个输出步骤每次写两行。
(4)所有步骤均为两线程

执行后,t2、t3表的数据如图11所示。

从最后结果看,和图5的相同,这个我们后面分析。
(5)输入步骤为两线程,输出步骤为四线程

执行后,t2、t3表的数据如图13所示。

输出为四线程,因此输入的第一个线程将前四行发送到输出1,然后将接着的四行发送到输出2,然后再将接着的四行(此时只剩两行)发送到输出1。输入的第二个线程也同样执行这样的过程。最终t2表两个1、2、3、4、9、10,t3表有两个5、6、7、8。
由前面这些例子可以总结出分发方式下执行规律:每个输入步骤线程执行相同的工作,即轮流向每个输出步骤发送数据行,每次发送的行数等于相应输出步骤的线程数。但是,图10-图11并不符合这个规律。
我理解图10应该这样执行:
输入线程1:t2:12 56 910 t3: 34 78
输入线程2:t2:12 56 910 t3: 34 78
但实际执行的效果却与图4相同。从现象看貌似输入输出线程数相等时,就会忽略输出的多线程,而当做单线程处理。再做一个2-2-4线程的试试:

执行后,t2、t3表的数据如图15所示。

按一般的规律应该这样执行:
输入线程1:t2:12 78 t3:3456 910
输入线程2:t2:12 78 t3:3456 910
但因为输入和第一个输出线程数相同了,于是第一个输出就按单线程处理:
输入线程1:t2:1 6 t3:2345 78910
输入线程2:t2:1 6 t3:2345 78910
斗胆猜想,这很可能是Kettle 8.3版本的一个bug。不用则以,要使用多线程一定得注意输入输出线程数相等的情况,别等数据乱套了再追悔莫及。
2. 复制方式
(1)输入两线程,输出单线程(图4)
执行后,t2、t3表的数据相同,如图16所示。

不出所料,两个线程分别向两个表发送了全部数据。
(2)输入单线程,两个输出,一个单线程、另一个两线程(图6)
执行后,t2、t3表的数据分别如图17、18所示。


单线程输出写了一遍数据,两线程输出写了两遍数据。
(3)输入单线程、两个输出均为两线程(图8)
执行后,t2、t3表的数据相同,如图19所示。

两个输出都写了两遍数据。
(4)所有步骤均为两线程(图10)
执行后,t2、t3表的数据相同,如图20所示。

因为输入与输出均为两线程,转为输出单线程处理。
(5)输入步骤为两线程,输出步骤为四线程(图12)
执行后,t2、t3表的数据相同,都有80条数据。数据条数为输入表t1的行数 * 输入线程数 * 输出线程数。
同样再做一个2-2-4线程的测试(图14),执行后t2表20条数据,按单线程输出处理,t3表80条数据,按四线程输出处理,符合预期。
由这些例子可以总结出复制方式下执行规律:分发的数据行数 = 原始行数 * 输入线程数 * 输出线程数。当输入输出线程数相等时,输出按照单线程处理。
注意,数据分发方式只影响输入步骤,可从步骤的右键菜单中设置,如图21所示。

对于输出步骤,设置成哪种都不影响转换执行的结果。如图22所示的转换,无论中间表输出的线程数是几,它的分发方式如何,最终t2和t3表的数据都和t1相同。
