并发与并行
Scrapeless Scraping Browser 为 JavaScript 渲染的公共页面提供托管的浏览器会话,而您的应用程序控制调度多少作业和多少作业可以同时执行。
简而言之
- 并发组织重叠的工作。 即使一个处理器交错它们,任务也可以在同一时间段内取得进展。
- 并行同时执行工作。 多个核心、处理器或工作者在同一时刻进行计算。
- I/O 等待通常受益于并发。 调度器可以在网络或存储操作待定时推进另一个任务。
- CPU 密集型工作需要真正的计算并行性。 更多调度的任务不会自己创造更多的算术容量。
- 这两种模型都需要边界和所有权。 队列、取消、共享状态和服务限制决定吞吐量是否保持稳定。
并发和并行的定义
并发是一种结构多个生命周期重叠的任务的方式,而并行意味着两个或多个计算正在同一时刻执行。一个并发程序可以通过交错任务在一个核心上运行。一个并行程序需要可以同时操作的执行资源。
区分涉及结构与执行。并发将工作负载分解为独立推进的活动,并定义它们如何协调。并行将工作映射到多个执行单元,以减少经过的计算时间或提高吞吐量。这里使用的主要术语遵循 Go 语言对并发和并行的解释,它为概念提供了一个具体的技术边界,而不是将其视为市场营销标签。
一个有用的比较问题是每种模型组织什么工作,哪些资源可以在同一时刻执行,以及在哪些地方发生等待、协调或模式决策。并发并不是线程的同义词,并行并不会在程序创建多个工作者时自动保证。事件循环、进程、加速器、向量指令和分布式节点都可以参与不同的组合。保持该边界可见可以防止架构图将保证分配给属于另一层的组件。
重叠如何变成同时工作
工作负载通过调度、等待、执行和协调从请求移动到结果。同一程序可以在任务级别上并发,在选定阶段上并行。
- 应用程序将工作负载拆分为具有显式输入、输出和取消规则的任务。
- 调度程序决定哪个准备好的任务在线程、进程、事件循环或远程工作者上获得时间。
- 当一个任务等待 I/O 时,并发设计允许另一个准备好的任务推进,而不是让执行资源闲置。
- 当多个执行资源同时运行准备好的任务时,工作负载的那部分是并行的。
- 系统会合并结果、传播失败,并在暴露最终输出之前应用排序或一致性规则。
事件循环可以协调成千上万的等待操作,而无需使它们的 CPU 指令同时进行。进程池可以在核心之间执行独立的 CPU 工作,但序列化和协调仍然增加了成本。混合服务通常在有界池周围使用异步 I/O 进行计算密集型转换。该行为在 Python asyncio 任务文档中得到了更全面的记录。该来源很有用,因为它描述了实际的执行或数据模型,而不是依赖于松散的类比。
并发与并行一览
| 维度 | 并发 | 并行 |
|---|---|---|
| 主要目标 | 协调重叠活动 | 在同一时刻进行工作 |
| 单核可能性 | 是,通过交错 | 不适用于同时的 CPU 执行 |
| 典型优势 | I/O 等待和响应服务 | 独立的 CPU 密集型计算 |
| 常见成本 | 协调、取消、共享状态错误 | 分区、传输、同步 |
| 测量的证明 | 重叠的任务生命周期 | 同时使用资源 |
该表将目标和机制分开。线程可以支持任一列,进程通常支持两者,而异步函数通常强调并发。正确的标签跟随观察到的执行,而不是用于启动工作的 API 名称。
偏向每种模型的工作负载
许多网络请求
并发使进展持续,尽管套接字在等待,前提是客户端遵守每个主机的限制和内存约束。
交互式服务器
并发任务处理防止一个慢请求阻塞不相关的客户端,并将取消范围限制在调用者。
图像或数值转换
并行工作者可以在传输和设置成本小于节省的计算时间时,划分独立的 CPU 密集型单元。
网页数据管道
收集通常是 I/O 密集型的,而解析、压缩、连接和模型准备可能需要一个单独的并行阶段。
这些用例共享一个选择规则:选择并发和并行,因为它的执行和所有权模型与工作负载相匹配,而不是因为名称听起来更高级。小型工作负载可能在简单的顺序循环中速度最快,因为协调是有成本的。测量排队时间、服务时间和端到端延迟,然后再添加工作者。
选择并发和并行模型
选择从主导等待开始。网络绑定工作、存储绑定工作、内存压力和 CPU 饱和需要不同的响应,即使用户面临的症状是相同的慢完成时间。
- 分类瓶颈。 记录任务在等待、运行、传输数据和协调中花费的时间。
- 限制接纳。 保持队列有限,以便流量突发不会将临时压力转化为进程范围的内存耗尽。
- 最小化共享突变。 不可变输入和隔离输出减少竞争,并使失败的任务更容易作为新作业重放。
- 保持取消。 不再需要结果的调用者应该能够停止排队的工作并释放下游容量。
- 基准测试整个路径。 包括序列化、启动、收集、解析和结果组装,而不仅仅是单独计时一个函数。
对于受 CPU 约束的 Python 程序,进程或隔离解释器可以提供真正的多核执行,而普通线程可能无法。对于网络密集型程序,异步任务或线程可以提高利用率,而不将每个步骤转变为并行计算。相关的主要参考是 Python 多进程文档,它阐明了该选择背后的存储、执行或互操作性假设。
扭曲比较的错误
最昂贵的错误来自将工作者数量视为普遍性能控制。每增加一个任务都会消耗描述符、内存、队列空间、远程容量和在故障处理期间的注意力。
- 调用所有重叠的并行ism。 在一个执行资源上的交替工作是并发的,但不是同时的。
- 在测量之前增加工作者。 更多的工作者可能会加剧竞争或下游节流,而不会改善完成时间。
- 在事件循环中阻塞。 一个长时间的同步操作可能会冻结不相关的协程,这些协程共享同一个循环。
- 随意共享可变状态。 锁只在每次访问遵循相同的所有权协议时保护不变性。
- 忽略结果顺序。 完成顺序、输入顺序和业务顺序是必须定义的独立合同。
失败应该追溯到最小的负责层。如果 CPU 在请求等待时空闲,请检查 I/O 并发;如果 CPU 饱和,请检查计算和分区;如果队列在下游延迟上升时增长,请减少接纳或添加反压。这种做法会产生有用的纠正措施,而不是模糊的指示来增加更多容量。
公共网络数据管道中的并发
公共网络管道通常结合了这两种模型。URL 发现和页面收集重叠,因为它们的生命周期大部分时间都在网络等待中。当记录独立时,解析和标准化可以同时进行。存储提交可能需要再次序列化,以保护排序或事务保证。
对于公共网络输入,获取层应记录请求的 URL、最终 URL、收集时间、响应模式以及在下游处理开始之前的内容检查。每个收集的记录应携带一个稳定的标识符,以便完成顺序不会悄然变为数据顺序。该交接使分析师拥有可重现的源记录,并使收集行为与解释分开。
Scrapeless处理在开头句子中描述的管理网页收集步骤。应用程序仍然拥有源批准、字段定义、工作负载边界、保留、访问控制和验证。收集服务可以提供渲染的页面内容,但调度层决定接纳率、最大活动会话、每个主机的公平性、时间预算和取消。两个层之间的清晰合同使后续更改更易于测试。
当用例需要审计能力时,管道应保留原始证据和整理输出。原材料支持在解析器或模式更改后重新处理;整理表支持稳定分析。收集和转换之间的有限队列吸收短期变化,同时在内存增长成为控制机制之前发出可持续过载的信号。这两种表示回答不同的操作问题,不应该被误认为是重复项。
架构审查检查清单
在设计审查期间使用以下问题。书面回答比假定默认更有价值,因为它暴露了团队在并发和并行性方面的分歧。
- 哪些任务可以重叠而不违反顺序或一致性规则?
- 哪些阶段在等待 I/O,哪些在消耗 CPU?
- 每个边界上排队和活动作业的最大数量是多少?
- 取消是如何从调用者传递到排队工作和下游操作的?
- 哪些数据是共享的,哪个组件拥有每个可变值?
- 工作负载是否要求输入顺序、完成顺序,还是无序?
- 哪些指标证明有益的重叠或同时执行?
- 当下游服务变得比生产者慢时会发生什么?
当并发被限制、并行阶段有足够的独立工作来偿还协调成本,而过载产生有意的响应时,设计就准备好了。在工作负载形状、数据量、服务限制或消费者期望变化后,请重新审视这些答案。对于一个探索性批处理而言合理的架构,可能不适合连续生产路径。
结论
并发和并行性解决相关但不同的问题。并发结构重叠活动,并在等待期间保持系统响应。并行性通过同时执行来加速适当的工作。许多生产管道都需要两者,通过有限队列和明确所有权连接在一起。实际决策来自测量时间的花费,并为每个阶段分配与其实际瓶颈相匹配的执行模型。
准备构建受控集合管道吗?
将渲染的公共网络输入连接到具有明确任务限制、证据检查和下游交接的编排层。
今天注册并获得 $5 的免费积分 — 不需要信用卡.
领取您的 $5 积分 →常见问题解答
并发可以在没有并行性的情况存在吗?
是的。单个处理器可以交错多个任务,使它们的生命周期重叠,即使在某一时刻只有一个任务执行指令。事件循环常常使用这种模型处理 I/O 密集型工作。应用程序获得响应能力,并更好地利用等待时间,而不是获得同时的 CPU 执行。
并行性可以在没有并发设计的情况下存在吗?
在某种有限意义上是可以的。运行时或处理器可以对单个计算进行内部并行化,即使应用程序呈现了简单的顺序接口。向量指令和并行数据库操作就是例子。当几个独立活动必须在时间上进行协调时,应用级并发仍然很有用。
线程是并发还是并行?
线程可以支持并发、并行或两者。答案取决于运行时、处理器、工作负载和调度程序。几个线程可能在一个核心上交错,或者独立线程可能同时在不同核心上执行。单独创建线程并不能证明有有用的并行工作发生。
哪个模型更适合网络请求?
并发通常是网络请求的第一工具,因为网络操作花费大量时间等待。设计应受到每个主机策略、内存、文件描述符和下游处理能力的限制。并行CPU工作者可能在后期对解析、压缩或分析转换仍然有帮助。
一个团队应该如何测试并发更改?
使用代表性工作负载进行测试,并记录吞吐量、排队时间、服务时间、错误类别、内存、CPU 使用情况和下游延迟。将整个管道与相同的输入进行比较。更改只有在改善目标指标而不违反顺序、公平或资源限制时才有用。