并行执行¶
1.3 新版功能.
默认情况下,Fabric执行所有指定的任务 连续 (有关详细信息,请参阅 执行策略)。本文描述了Fabric通过每个任务装饰器和/或全局命令行开关在 平行 中的多个主机上运行任务的选项。
它能做什么¶
因为Fabric 1.x不是完全线程安全的(并且因为在一般使用中,任务功能通常不会彼此交互),所以该功能通过Python 多处理 模块实现。它为每个主机和任务组合创建一个新进程,可选地使用(可配置)滑动窗口来防止太多进程同时运行。
例如,假设您想要在多个Web服务器上更新Web应用程序代码,然后在代码分布到任何地方后重新加载服务器(以便在代码更新失败时更容易回滚)。可以实现这一点以下fabfile:
from fabric.api import *
def update():
with cd("/srv/django/myapp"):
run("git pull")
def reload():
sudo("service apache2 reload")
并在一组3个服务器上以串行方式执行它,就像这样:
$ fab -H web1,web2,web3 update reload
通常,如果没有激活任何并行执行选项,Fabric将按顺序运行:
update
在web1
上update
在web2
上update
在web3
上reload
在web1
上reload
在web2
上reload
在web3
上
启用并行执行(通过 -P
- 详见下文),它变成:
update
对web1
,web2
和web3
reload
对web1
,web2
和web3
希望这样做的好处是显而易见的 - 如果 update
花费5秒运行,reload
花费2秒,串行执行需要(5 + 2)* 3 = 21秒运行,而并行执行只需要三分之一的时间, 5 + 2)= 7秒。
如何使用它¶
装饰¶
由于并行执行影响的最小“单位”是任务,所以可以使用 parallel
和 serial
装饰器在逐任务的基础上启用或禁用功能。例如,这个fabfile:
from fabric.api import *
@parallel
def runs_in_parallel():
pass
def runs_serially():
pass
当以这种方式运行时:
$ fab -H host1,host2,host3 runs_in_parallel runs_serially
将导致以下执行顺序:
runs_in_parallel
对host1
,host2
和host3
runs_serially
在host1
上runs_serially
在host2
上runs_serially
在host3
上
命令行标志¶
还可以通过使用命令行标志 -P
或env变量 env.parallel 强制所有任务并行运行。但是,任何用 serial
特别包装的任务将忽略此设置,并继续连续运行。
例如,以下fabfile将产生与上述相同的执行序列:
from fabric.api import *
def runs_in_parallel():
pass
@serial
def runs_serially():
pass
当调用像这样:
$ fab -H host1,host2,host3 -P runs_in_parallel runs_serially
如前所述,runs_in_parallel
将并行运行,runs_serially
按顺序运行。
气泡大小¶
使用大型主机列表,用户的本地计算机可能由于运行太多并发结构进程而淹没。因此,您可以选择使用移动气泡方法,将织物限制为特定数量的并发活动进程。
默认情况下,不使用气泡,并且所有主机都在一个并发池中运行。您可以通过为 parallel
指定 pool_size
关键字参数,或者通过 -z
全局地在每个任务级别上覆盖此操作。
例如,一次运行5个主机:
from fabric.api import *
@parallel(pool_size=5)
def heavy_task():
# lots of heavy local lifting or lots of IO here
或跳过 pool_size
kwarg:
$ fab -P -z 5 heavy_task