如何在Nifi中从单个CSV文件路由/提取不同的列?

时间:2019-01-25 05:13:58

标签: apache csv apache-nifi

我有一个GetFile处理器,该处理器可提取具有约100列的大型CSV文件。我的目标是从此CSV文件中提取列的特定子集,并将其发送到MySQL中的各种不同表中。

当前方法使用 GetFile ->多个 ConvertRecord 处理器,其中有不同的 CSVReader CSVRecordSetWriters >已定义,将根据SQL表的架构遵守AVRO架构。

是否有一种方法只有一个GetFile并将子集路由到不同的处理器,而不是跨多个流复制较大的CSV文件,然后由不同的ConvertRecord处理器拾取该文件?

这是我现在的流程, Multiple Queues of Large Files

可以看出,CSV文件跨多个路径复制,这使效率非常低下。对于此示例,大小为57字节,但通常我会在60-70之间获得〜6 GB的文件,例如 ConvertRecord 路径

如果我知道需要从CSV文件中提取哪些列子集并将其发送到不同的表,该如何有效地路由数据?示例:

A,B 转到一个表

A,C 转到第二个表

A,D,E 转到第三张表

A,D,F,G 转到第三张表 ....

1 个答案:

答案 0 :(得分:2)

如果使用PutDatabaseRecord,则可以有多个PutDatabaseRecord处理器,每个处理器都使用不同的读取架构来选择适当的列,这与您对ConvertRecord处理器所做的类似,但是实际上您实际上不需要写出转换后的数据。

此外,将同一个流文件分叉到6个不同的位置并没有什么真正的低效之处。在上面的示例中,如果GetFile拾取6GB的文件,则内容存储库中只有1GB的6GB内容副本,并且将有3个流文件指向相同的内容,因此每个ConvertRecord都将读取相同的6GB内容。然后,他们将各自写出一条新的内容,它将是数据的子集,并且在某个时间点,如果没有流文件引用原始的6GB,则将从内容存储库中删除该内容。因此,与GetFile的每个其他连接都不一样,它会复制6GB。