ansible的同步模式与异步模式执行区别:
同步模式: 如果节点数太多,ansible无法一次在所有远程节点上执行任务,那么将先在一部分节点上执行一个任务(每一批节点的数量取决于fork进程数量,默认为5个,可设置),直到这一批所有节点上该任务完全执行完毕才会接入下一个批节点,直到所有节点将该任务都执行完毕,然后重新回到第一批节点开始执行第二个任务。依次类推,直到所有节点执行完所有任务,ansible端才会释放shell。这是默认的同步模式,也就是说在未执行完毕的时候,ansible是占用当前shell的,任务执行完毕后,释放shell了才可以输入其他命令做其他动作。
异步模式:假如fork控制的并发进程数为5,远程控制节点为24个,则ansible一开始会将5个节点的任务扔在后台,并每隔一段时间去检查这些节点的任务完成情况,当某节点完成不会立即返回,而是继续等待直到5个进程都空闲了,才会将这5个节点的结果返回给ansible端,ansible会继续将下一批5个节点的任务扔在后台并每隔一段时间进行检查,依次类推,直到完成所有任务。
在异步模式下,如果设置的检查时间间隔为0,在将每一批节点的任务丢到后台后都会立即返回ansible,并立即将下一批节点的任务丢到后台,直到所有任务都丢到后台完成后,会返回ansible端,ansible会立即释放占用的shell。也就是说,此时ansible是不会管各个节点的任务执行情况的,不管执行成功还是失败。因此,在轮训检查时间内,ansible仍然正在运行(尽管某批任务已经被放到后台执行了),当前shell进程仍被占用处于睡眠状态,只有指定的检查时间间隔为0,才会尽快将所有任务放到后台并释放shell。
ansible并发和异步:
ansible默认只会创建5个进程,所以一次任务只能同时控制5台机器执行。那如果你有大量的机器需要控制,或者你希望减少进程数,那你可以采取异步执行。
使用async和poll这两个关键字便可以并行运行一个任务。 async这个关键字触发ansible并行运作任务,而async的值是ansible等待运行这个任务的最大超时值(如果执行超时任务会强制中断导致失败),而poll就是ansible检查这个任务是否完成的频率时间。
首先来看看async与poll这两个参数使用实例:
倒1:
---
- name: Test
hosts: localhost
tasks:
- name: wair for
shell: sleep 16
async: 10
poll: 2
结果:
TASK: [wair for] **************************************************************
ok: [localhost]
<job 207388424975.101038> polling, 8s remaining
ok: [localhost]
<job 207388424975.101038> polling, 6s remaining
ok: [localhost]
<job 207388424975.101038> polling, 4s remaining
ok: [localhost]
<job 207388424975.101038> polling, 2s remaining
ok: [localhost]
<job 207388424975.101038> polling, 0s remaining
<job 207388424975.101038> FAILED on localhost
这个step失败, 因为操作时间超过了最大等待时长
---
- name: Test
hosts: localhost
tasks:
- name: wair for
shell: sleep 16
async: 10
poll: 0
结果:
TASK: [wair for] **************************************************************
<job 621720484791.102116> finished on localhost
PLAY RECAP ********************************************************************
poll 设置为0, 表示不用等待执行结果, 该step执行成功
例3:
---
- name: Test
hosts: localhost
tasks:
- name: wair for
shell: sleep 16
async: 10
poll: 0
结果:
TASK: [wair for] **************************************************************
<job 621720484791.102116> finished on localhost
PLAY RECAP ********************************************************************
poll 设置为0, 表示不用等待执行结果, 该step执行成功
如果你希望在整个集群里面平行的执行一下updatedb这个命令,使用下面的配置:
---
- hosts: all
serial: 6
tasks:
- name: Install mlocate
yum: name=mlocate state=installed
- name: Run updatedb
command: /usr/bin/updatedb
async: 300
poll: 10
你会发现当你使用上面的例子控制超过5台机器的时候(serial参数设置并发数),yum模块会先在5台机器上跑,完成后再继续下面的机器(同步模式)。command模块的任务会一次性在所有机器上都执行了,然后监听它的回调结果(异步并发模式)。
如果你的command是控制机器开启一个进程放到后台,那就不需要检查这个任务是否完成了。你只需要继续其他的动作,最后再使用wait_for这个模块去检查之前的进程是否按预期中开启了便可。只需要把poll这个值设置为0,便可以按上面的要求配置ansible不等待job的完成。或者你还有一种需求是有一个task它是需要运行很长的时间,那你需要设置一直等待这个job完成,这个时候你把async的值设成0便可。
总结来说,大概有以下的一些场景你是需要使用到ansible的polling特性的
1、你有一个task需要运行很长的时间,这个task很可能会达到timeout
2、你有一个任务需要在大量的机器上面运行
3、你有一个任务是不需要等待它完成的
当然也有一些场景是不适合使用polling特性的
1、你的这个任务是需要运行完后才能继续另外的任务的
2、你的这个任务能很快的完成