Nifi- 使用ExecuteStreamCommand实现并行和并发执行

5

目前,我在一台有4个核心的边缘节点上运行Nifi。如果我有20个传入的流文件,并给ExecuteStreamCommand处理器设置并发任务为10,这意味着我只能获得并发执行还是同时获得并行执行?

1个回答

11
在这种情况下,正如Apache NiFi用户指南(强调添加)中所指出的那样,您可以同时获得并发性和并行性:
下一个是调度选项卡,它提供了一个名为“Concurrent tasks”的配置选项。 这控制处理器将使用多少线程。 换句话说,这控制此处理器应同时处理多少个FlowFile。 增加此值通常会使处理器在相同的时间内处理更多数据。但是,它通过使用其他处理器无法使用的系统资源来实现这一点。这基本上提供了处理器的相对加权 - 它控制应该将系统资源分配给该处理器而不是其他处理器的数量。大多数处理器都可以使用此字段。 但是,有些类型的处理器只能使用单个并发任务调度。
如果您调用的命令存在锁定问题或竞争条件,则可能会出现问题,但如果它们是独立的,则仅受JVM调度和硬件性能的限制。
评论中的问题的回答太长了,无法作为评论:当有4个核心时,我可以假设将有4个并行执行,其中它们将运行多个线程以处理10个并发任务吗? 在最好的情况下,我提到的场景中这20个FlowFiles是如何执行的。

回复:

John,JVM线程处理是一个相当复杂的话题,但一般情况下会有n+C个JVM线程,其中C是某个常数(main线程、VM线程、GC线程),而n由流程控制器创建以执行处理器任务的“个体”线程数量。JVM线程与本机操作系统线程1:1映射,因此在运行10个处理器线程的4核系统上,您将拥有“4个并行执行”。我认为,在高层次上,您的操作系统将使用时间分片来循环处理这10个线程中的4个,并且每个线程将处理~2个流文件。

再次强调,这只是一个非常粗略的想法(假设1个流文件=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)

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

Flowfiles A - T

Cores α, β, γ, δ

Threads 1 - 10

Time/thread 1 s

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

在5秒钟内,所有10个线程都执行了两次,每个线程完成了2个flowfile。
然而,假设线程调度程序每次迭代只分配每个线程0.5秒的周期(再次强调,这不是实际数字,仅用于演示)。执行模式如下:
Flowfiles A - T
核心α、β、γ、δ
线程1-10
时间/线程0.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

在这种情况下,总执行时间是相同的(*有一些线程切换的开销),但特定的流文件需要更长的时间(从0开始计算的总时间,而不是活动执行时间)才能完成。例如,在第二个场景中,流文件C和D直到time=2才完成,但在第一个场景中在time=1就完成了。
老实说,操作系统和JVM有比我聪明得多的人在处理这个问题,我们的项目也是如此(幸运的是),因此这里存在着很大的简化,通常我建议您让系统自己担心超级优化线程。我认为,在这种情况下,将并发任务设置为10并不会比将其设置为4产生巨大的改善。您可以在这里这里阅读更多关于JVM线程的信息。

我刚在本地的1.5.0开发分支上进行了一个快速测试 -- 我连接了一个简单的GenerateFlowFile,使用0秒计划运行到一个LogAttribute处理器。 GenerateFlowFile立即生成了很多流文件,队列启用了反向压力功能(暂停输入处理器,直到队列可以排放一些等待的10,000个流文件)。我停止了两个并重新运行了此操作,给LogAttribute处理器更多的并发任务。通过将LogAttribute并发任务设置为GenerateFlowFile的2:1,队列从未积累超过大约50个排队的流文件。

Status history of <code>LogAttribute</code> processor

tl;dr 将并发任务设置为您拥有的核心数应该足够。

更新2:

与我们的一位JVM专家进行了核实,他提到了两件事情:

  1. 该命令不仅仅受CPU限制;如果I/O很重,更多并发任务可能会有益。
  2. 整个流程控制器的最大并发任务数默认设置为10

谢谢Andy。当有4个核心时,我可以假设会有4个并行执行,其中它们将运行多个线程来处理10个并发任务吗?在最好的情况下,这20个流文件在我提到的场景中如何执行。 - John
@John,我添加了更多细节到答案中,因为它太长了无法适应这里。希望这可以帮助到你。 - Andy
1
Andy,非常感谢你的帮助。感谢你花费时间和精力用简单易懂的语言来解释。通过你提供的样本统计数据和解释,我学到了很多。 - John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接