TPL数据流管道的吞吐量

4
我们有一个 TPL 数据流管道,其中包含以下块:
- 转换块 A:Http post 请求 - 转换块 B: 数据库 IO - 转换块 C: 一些单位转换数据(基本上是 CPU 密集型任务) - 转换块 D: 发布到 Google PubSub - 操作块 E: Http post 请求
我们试图以最大吞吐量(100% CPU 利用率)运行此管道。我们采取的措施如下:
- 将每个块的 MaxDegreeOfParallelism 设置为 1000。 - 使用Semaphore 限制最大管道数(目前为 500)。 - 第一个块中的消息通过 Google PubSub 订阅传递(使用 100 作为 maxOutstandingElementCount 的 Flow Control 设置)。
我们的结果如下:
- 在 2.5 小时内处理了 13000 条消息(即每分钟处理 ~87 条消息)。 - 100% CPU 利用率。 - 线程计数 450。
问题来了,这种性能可以提高吗?我们需要在 10 分钟内处理 50,000 条消息(假设在块 B 中不获取任何数据)。或者建议我们应该尝试优化代码的哪些地方。
使用的机器信息如下:
- 处理器: Intel ® Xeon(R) CPU E3-1505M v5 @2.80GHz - 内存: 32 GB - 系统类型: 64 位操作系统

1
你尝试过减少并行度来消除由于太多同时执行的任务导致的线程饥饿问题吗? - VMAtm
1
没有设置度量意味着它们是顺序的,这不是你想要的。尝试使用等于核心数量的数字,这是经典解决方案。 - VMAtm
1
你可以尝试这两个值,但是500对于那个来说太多了。 - VMAtm
好的,根据我的研究,最佳值应该是 Environment.ProcessCount 乘以 4。 - Savaratkar
不同的研究会得出不同的结果。根据我的实践,您应该从以下选项中选择:{ Environment.ProcessCount +- 1, Environment.ProcessCount, Environment.ProcessCount * 2, Environment.ProcessCount * 4, Environment.ProcessCount / 2 },并进行测量! - VMAtm
显示剩余2条评论
1个回答

4
无论 CPU 负载如何,你都应该优化最大吞吐量,特别是当你大部分的工作与 IO 相关(如 http 调用、文件访问等)时,在这种情况下 CPU 的使用率并不高。
并行度应该是可用 CPU 核心数的因数。服务器无法在同一时间内处理比核心数更多的任务,所以使用很多线程并不能帮助解决问题。这只会为相同的计算带来更多开销,实际上会减慢速度。
对于基于 CPU 的工作,应该将并行度限制在核心数范围内,以便让每个核心都能充分发挥作用但不超载。IO-based work 是异步的,等待 IO 完成后才能使用更大的并行度以同时分派更多任务。
一个良好的开始是 (# of cores) x 4 用于 IO 块,(# of cores) 用于 CPU 密集型块。这意味着如果你有 4 个 CPU 核心可用,就使用 4 个用于 CPU 块,16 个用于 IO 块。尝试这样做,并在 IO 块上增加并行度,直到达到最大吞吐量。
还要注意,数据流管道中的各种设置,如确保严格排序,可以根据你的要求进行调整以获得更好的性能。如果正确配置, TPL Dataflow 可以轻松处理超过 100k 个项目/秒。

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