1. 程式人生 > >ansible之非同步和併發

ansible之非同步和併發

 

 

    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、你的這個任務能很快的完成