Nifi-使用ExecuteStreamCommand进行并行和并发执行

Joh*_*ohn 5 parallel-processing apache-nifi

目前,我在具有4个核心的边缘节点上运行Nifi.假设我有20个传入的流文件,并且我为ExecuteStreamCommand处理器提供10个并发任务,这是否意味着我只获得并发执行或并发和并行执行?

And*_*ndy 9

在这种情况下,您将获得并发性并行性,如Apache NiFi用户指南中所述(重点已添加):

接下来,Scheduling选项卡提供名为Concurrent tasks的配置选项.这可以控制处理器将使用的线程数.换句话说,它控制此处理器应同时处理多少个FlowFiles.增加此值通常会使处理器在相同的时间内处理更多数据.但是,它通过使用其他处理器无法使用的系统资源来实现此目的.这基本上提供了处理器的相对权重 - 它控制应该将多少系统资源分配给此处理器而不是其他处理器.该字段适用于大多数处理器.但是,某些类型的处理器只能使用单个"并发"任务进行调度.

如果您正在调用的命令存在锁定问题或竞争条件,则可能会出现问题,但如果它们是独立的,则仅受JVM调度和硬件性能的限制.

对评论中的问题的回答太长,无法发表评论:

题:

谢谢安迪.当有4个核心时,我可以假设它们将有4个并行执行,在这些执行中它们将运行多个线程来处理10个并发任务吗?以最好的方式,在我提到的场景中如何执行这20个流程文件. - 约翰30分钟前

响应:

John,JVM线程处理是一个相当复杂的主题,但是,通常会有n + C JVM线程,其中C是一些常量(线程,VM线程,GC线程),n一些"单独"线程由流控制器创建以执行处理器任务.JVM线程将1:1映射到本机OS线程,因此在运行10个处理器线程的4核系统上,您将进行"4个并行执行".我的信念是,在高级别,您的操作系统将使用时间切片一次循环10个线程4,每个线程将处理~2个流文件.

同样,非常粗略的想法(假设1个flowfile = 1个工作单元= 1秒):

Cores | Threads | Flowfiles/thread | Relative time
  1   |    1    |         20       |      20 s      (normal)
  4   |    1    |         20       |      20 s      (wasting 3 cores)
  1   |    4    |          5       |      20 s      (time slicing 1 core for 4 threads)
  4   |    4    |          5       |       5 s      (1:1 thread to core ratio)
  4   |   10    |          2       |       5+x s    (see execution table below)
Run Code Online (Sandbox Code Playgroud)

如果我们假设每个核心可以处理一个线程,并且每个线程每秒可以处理1个流文件,并且每个线程获得1秒的不间断操作(显然不是真实的),则执行序列可能如下所示:

Flowfiles A - T.

核心α,β,γ,δ

线程1 - 10

时间/线程1秒

Time | Core ? | Core ? | Core ? | Core ?
  0  |   1/A  |   2/B  |   3/C  |   4/D
  1  |   5/E  |   6/F  |   7/G  |   8/H
  2  |   9/I  |  10/J  |   1/K  |   2/L
  3  |   3/M  |   4/N  |   5/O  |   6/P
  4  |   7/Q  |   8/R  |   9/S  |  10/T
Run Code Online (Sandbox Code Playgroud)

在5秒内,所有10个线程都执行了两次,每次完成2个流文件.

但是,假设线程调度程序仅为每个线程分配每次迭代0.5秒的循环(同样,不是一个真实的数字,只是为了演示).那么执行模式将是:

Flowfiles A - T.

核心α,β,γ,δ

线程1 - 10

时间/线程.5秒

Time | Core ? | Core ? | Core ? | Core ?
  0  |   1/A  |   2/B  |   3/C  |   4/D
 .5  |   5/E  |   6/F  |   7/G  |   8/H
  1  |   9/I  |  10/J  |   1/A  |   2/B
1.5  |   3/C  |   4/D  |   5/E  |   6/F
  2  |   7/G  |   8/H  |   9/I  |  10/J
2.5  |   1/K  |   2/L  |   3/M  |   4/N
  3  |   5/O  |   6/P  |   7/Q  |   8/R
3.5  |   9/S  |  10/T  |   1/K  |   2/L
  4  |   3/M  |   4/N  |   5/O  |   6/P
4.5  |   7/Q  |   8/R  |   9/S  |  10/T
Run Code Online (Sandbox Code Playgroud)

在这种情况下,总执行时间是相同的(*线程切换有一些开销),但特定的流文件需要"更长"(从0开始的总时间,不是活动执行时间)才能完成.例如,流程文件C和D 在第二种情况下直到时间= 2才完成,但在第一种情况下在时间= 1时完成.

老实说,操作系统和JVM让人们比我更聪明,就像我们的项目一样(幸运的是),因此这里存在严重的过度简化,一般情况下我会建议你让系统担心超优化穿线.在这种情况下,我不认为将并发任务设置为10会产生很大的改进而不是将其设置为4.您可以在此处此处阅读有关JVM线程的更多信息.

我刚刚在我的本地1.5.0开发分支中进行了快速测试 - 我将一个简单的GenerateFlowFile运行与0 sec计划连接到LogAttribute处理器.该GenerateFlowFile立即生成那么多flowfiles队列使背压特征(暂停输入处理器,直到队列可以排出一些10000个等待flowfiles的).我停了两个并重新运行了这个,给LogAttribute处理器带来了更多的并发任务.通过将LogAttribute并发任务设置为2:1 GenerateFlowFile,队列永远不会累积超过约50个排队的流文件.

<code>10</code>默认情况下,整个流控制器的最大并发任务数设置为.</li>
</ol></p>
        <ul class=