Optimizing Ansible Playbooks: Parallelism
Ansible ကိုလေ့လာနေသူတွေအနေနဲ့ Playbook တွေ၊ Ad-hoc command တွေနဲ့ Task တွေကို Host အများကြီးမှာ တစ်ပြိုင်တည်း (Parallel) လုပ်ဆောင် (run) ခိုင်းလို့ရတယ်ဆိုတာတော့ သိကြပြီးဖြစ်မှာပါ။ ဒါပေမဲ့ တစ်ပြိုင်းတည်းဆိုတိုင်း delegate လုပ်လိုက်တဲ့ Host အကုန်လုံးမှာ တန်းပြီး run တာတော့ မဟုတ်ပါဘူး။ ကနဦးသတ်မှတ်ထားတဲ့ (Default) အရေအတွက်က Host ၅လုံးကိုပဲ တပြိုင်တည်းလုပ်ဆောင်ပေးတာပါ။ Host ၁၀လုံးမှာ Task တွေ run ခိုင်းတယ်ဆိုရင် ၅လုံးတစ်ဖြတ်ဖြတ်ပြီးပဲ run မှာပါ။ ပိုရှင်းအောင်ပြောရမယ်ဆိုရင် ဥပမာ - Linux Server ၁၀ လုံးမှာ ၅လုံးကို အရင် SSH နဲ့လှမ်းချိပ်မယ်၊ ပြီးရင် Playbook ထဲရေးထားတဲ့ Task တွေကို အဲ့ဒီ ၅လုံးမှာအရင် run မယ်၊ Task အားလုံးပြီးသွားတော့မှ နောက်ကျန်တဲ့ ၅လုံးကို ထပ်ချိပ်ပြီး ထပ် run တာဖြစ်ပါတယ်။ ဒီလို run ပေးခြင်းက Host တွေရဲ့ လုပ်ဆောင်နိုင်စွမ်း (Performance) ကို မထိခိုင်အောင်ကာကွယ်ပေးနိုင်လို့ပါပဲ။ အလွယ် ဥပမာပေးရမယ်ဆိုရင် Server အလုံး ၅၀ လောက်ကို Update လုပ်မယ်ဆိုပါစို့။ ၅လုံးတစ်ဖြတ်စီသာခွဲမ run ပေးရင် အလုံး ၅၀ လုံးက တစ်ပြိုင်တည်း Update တွေလှမ်းဆွဲပြီး Network traffic မှာ အလုပ် အရမ်း များသွားပါလိမ့်မယ်။ Server တွေမှာလည်း Update ပမာဏ (Size) များရင်များသလို မြန်မြန်ဆန်ဆန် ရသင့်သလောက်မရတော့ပဲ ပိုကြာသွားတာမျိုးဖြစ်သွားပါလိမ့်မယ်။ နောက်တစ်ခုက VM Environment အနေနဲ့ Hypervisor Host တစ်လုံးတည်းပေါ်မှာရှိနေတဲ့ VM တွေအကုန်လုံးမှာ CPU အသုံးပြုမှုများနိုင်တဲ့ Task တစ်ခုခုကို run တဲ့အခါ ၅လုံးစီခွဲ run ခြင်းက Hypervisor Host ရဲ့ Performance ထိခိုက်မှုကို ကာကွယ် လျှော့ချပြီးသားဖြစ်သွားပါလိမ့်မယ်။ မဟုတ်ရင် VM တွေအကုန်လုံးက တပြိုင်တည်း အလုပ်တွေလုပ်ပြီး Hypervisor Host ရဲ့ CPU မှာ Load အရမ်းများသွားပါလိမ့်မယ်။ ဒါပေမဲ့ မေးခွန်းထုတ်စရာရှိတာက Resource အရမ်းမလိုတဲ့ Task မျိုးတွေကို run တဲ့အခါကျ ၅လုံးစီမဟုတ်ပဲ အလုံး ၅၀၊ ၁၀၀ တစ်ပြိုင်တည်း run ပေးလိုက်ရင်ပိုမမြန်နိုင်ဘူးလားဆိုတာပါပဲ။ Control Node အနေနဲ့ အဲဒီလောက်များတဲ့ session တွေကို ထိန်းသိမ်းပေးနိုင်တဲ့ Resource Capacity (CPU, Memory) လုံလုံလောက်လောက် ရှိတယ်ဆိုရင်ရပါတယ်။ ဥပမာ Ansible Tower အသုံးပြုတယ်ဆိုရင် သူ့ရဲ့ Memory Requirement က Host အလုံး ၁၀၀ ကို manage လုပ်နိုင်ဖို့အတွက် အနည်းဆုံး 4GB ရှိသင့်ပါတယ်။ Ansible Engine မှာလည်း ဒီအတိုင်းပါပဲ။ Capacity တွက်ချက်မှုအတွက် ထည့်သွင်းစဉ်းစားရမယ့် အချက် (Factor) တွေရှိပါတယ်။ ဒီအပိုင်းကိုတော့ နောက်မှသီးသန့်ထပ်ရေးပေးပါမယ်။
အထက်မှာပြောခဲ့သလို Ansible Control Node အနေနဲ့ Host ဘယ်နှလုံးမှာ တပြိုင်တည်း Task တွေ run ခိုင်းမယ်ဆိုတာကို သတ်မှတ်ပေးဖို့ ansible.cfg
ဖိုင်ရဲ့ [Defaults]
Section အောက်မှာ forks
keyword နဲ့ကြေငြာပေးရပါတယ်။ မပေးထားရင် Default အနေနဲ့ forks=5
လို့ Ansible ကသတ်မှတ်ပါတယ်။ /etc/ansible/ansible.cfg
ထဲမှာ forks=10
လို့ထည့်ပေးလိုက်ရင် Host 10လုံးတစ်ပြိုင်တည်း run ပေးပါလိမ့်မယ်။ ansible.cfg
ဖိုင်ရဲ့ အဆင့် (Precedence) ကိုတော့ သတိထားဖို့လိုပါတယ်။ /etc/ansible/ansible.cfg
ထဲ forks=10
ပေးထားပေမဲ့ Home Directory အောက်က .ansible.cfg
ဒါမှမဟုတ် Playbook Directory ထဲက ansible.cfg
မှာကျ forks=5
လို့ပြန်ပေးထားမိရင်တော့ Host ၅လုံးစီပဲခွဲ run ပေးပါလိမ့်မယ်။ forks
value ကိုတော့ အလွန်ဆုံး 25
ကနေ 100
ကြားလောက်ပဲထားတာ ပိုသင့်တော်ပါတယ်။ forks=25
ပေးထားတိုင်း connection ၂၅ခုဖွင့်ပြီး run ဖို့ကြိုးစားတာတော့ မဟုတ်ပါဘူး။ Playbook မှာသတ်မှတ်ပေးလိုက်တဲ့ Host အရေအတွက်ပေါ်မူတည်ပြီးပဲ run ပေးမှာဖြစ်ပါတယ်။ Host အရေအတွက် ၅လုံးပဲရှိရင် ၅လုံး တပြိုင်တည်း run ပြီး အလုံး ၃၀ ရှိရင်တော့ ၂၅လုံးတစ်ခါ၊ ကျန်တဲ့ ၅လုံးကိုတစ်ခါ၊ ခွဲ run ပေးပါလိမ့်မယ်။
ဒီနည်းလမ်းနဲ့ တပြိုင်တည်း run စေချင်တဲ့ Host အရေအတွက်ကို သတ်မှတ်တာက အမြဲတမ်းအဆင်မပြေပါဘူး။ ဥပမာ Play နှစ်ခုပါဝင်တဲ့ Playbook အနေနဲ့ ပထမ Play မှာ Host ၂လုံးစီပဲခွဲ run ချင်ပြီး ဒုတိယ Play မှာတော့ Host ၅လုံးစီခွဲ run ချင်တယ်ဆိုရင် ansible.cfg
ရဲ့ forks
နဲ့မရတော့ပါဘူး။ ansible.cfg
က Playbook ထဲက Play တိုင်းနဲ့သတ်ဆိုင်တဲ့ configuration ပါ။ ဒါကြောင့် သူ့ထဲမှာပါတဲ forks
value ပေါ်ပဲ အခြေခံပြီး Play တွေက run ပါလိမ့်မယ်။ forks=2
လို့ပြောထားရင် Play နှစ်ခုလုံးမှာ Host ၂လုံးစီခွဲ run မှာဖြစ်တဲ့အတွက် ပထမ Play အတွက်ပဲအဆင်ပြေမှာဖြစ်ပါတယ်။ ဒီပြဿနာကို ဖြေရှင်းဖို့အတွက်ကတော့ Play တွေမှာ serial
ဆိုတဲ့ Keyword ရှိပါတယ်။
ပထမ Play ဖြစ်တဲ့ play one
မှာ serial: 2
လို့ပြောထားတဲ့အတွက် srvgroup01
ဆိုတဲ့ Host Group ထဲမှာရှိတဲ့ Host တွေကို ၂လုံးစီခွဲပြီး update လုပ်ပေးသွားမှာဖြစ်ပြီး ဒုတိယ Play play two
ကတော့ srvgroup02
ထဲက Host တွေကို ၅လုံးစီခွဲပြီး update လုပ်ပေးမှာဖြစ်ပါတယ်။
Serial ကို value တစ်ခုတည်းတင်မဟုတ်ပဲ list အနေနဲ့ပေးပြီး Host အရေအတွက်ကို တဆင့်ခြင်းအတိုးအလျော့လုပ်လို့ရသလို၊ ရာခိုင်နှုန်း(%
) နဲ့လည်း ပေးလို့ရပါသေးတယ်။ %
ကတော့ စုစုပေါင်း Host အရေအတွက်ပေါ်မူတည်ပြီး တွက်ယူသွားမှာဖြစ်ပါတယ်။ ပိုနားလည်လွယ်အောင် Host ၁၀လုံးပါတဲ့ webservers
Host Group နဲ့ နှိုင်းယှဉ်ကြည့်ပါမယ်။
# Using Percentage
- name: test play
hosts: webservers
serial: "30%"
30%
လို့ပြောထားတဲ့အတွက် Host ၁၀လုံးကို ၃လုံးစီခွဲပြီး လေးကြိမ် run ပါတယ်။ နောက်ဆုံးအကြိမ်မှာတော့ ကျန်နေတဲ့ Host ၁လုံးထဲကိုပဲ run သွားတာတွေ့ရပါလိမ့်မယ်။
# Using List
- name: test play
hosts: webservers
serial:
- 1
- 5
- 10
ဒီ list မှာတော့ Host ၁လုံး၊ ၅လုံးနဲ့ ၁၀လုံးဆိုပြီး သုံးကြိမ်ခွဲ run ပါတယ်။ နောက်ဆုံးအကြိမ်မှာ ၁၀လုံး run ခိုင်းထားပေမဲ့ task မ run ရသေးတာ ၄လုံးပဲကျန်တော့တာကြောင့် ၃ကြိမ်နဲ့ပဲအဆုံးသတ်သွားတာဖြစ်ပါတယ်။
# Mixed
- name: test play
hosts: webservers
serial:
- 1
- 2
- 40%
- 20%
list နဲ့ Percentage နှစ်မျိုးရောတဲ့အခြေအနေမှာလည်း အတူတူပါပဲ။ ဒီနမူနာမှာတော့ ၅ကြိမ်ခွဲ run တာတွေ့ရပါလိမ့်မယ်။ ၁လုံး၊ ၂လုံး နဲ့ Host ၁၀လုံးရဲ့ 40%
ဖြစ်တဲ့ ၄လုံး ရယ်ကို run အပြီးမှာ Host ၃လုံး ကျန်ပါတယ်။ နောက်ဆုံးမှာ 20%
လို့ပေထားတဲ့အတွက် ကျန်သမျှကို Host တွေကို ၂လုံးစီခွဲ run ပေးမှာဖြစ်ပါတယ်။ ဒါကြောင့် ၄ကြိမ်မြောက်မှာတော့ Host ၂လုံး run သွားပြီး နောက်ဆုံးအကြိမ်မှာတော့ Host ၁လုံးတည်းနဲ့အဆုံးသတ်သွားတာကို မြင်တွေ့ရမှာပဲဖြစ်ပါတယ်။
ကိုယ်တိုင် စမ်းသပ်ကြည့်နိုင်ဖို့ Demo Video လေးပါ ဖော်ပြပေးလိုက်ပါတယ်။
ဒီ Video လေးမှာတော့ Host ၂လုံးနဲ့ စမ်းသပ်ပြထားတာဖြစ်ပါတယ်။ ပထမဆုံး ansible.cfg
ထဲ forks = 10
ပေးထားတဲ့အနေအထားနဲ့ run ပါတယ်။ sleep 10
ဆိုတဲ့ command ကို run ပြီး Task ကို ၁၀ စက္ကန့်စာ ခဏရပ်ထားပေးတာပါ။ forks = 10
ပေးထားတာဖြစ်တဲ့အတွက် Host ၂လုံးစလုံးမှာ တပြိုင်တည်း run သွားတာကိုတွေ့ရပါလိမ့်မယ်။ ဒါကြောင့် ဒီ Task ကို Host ၂လုံးစလုံးမှာ run ပြီးဖို့ ၁၀စက္ကန့်ပဲကြာပါတယ်။ နောက်တစ်ကြိမ် run တဲ့အခါမှာတော့ Playbook ထဲ serial: 1
လေးထည့်ပေးလိုက်တဲ့အတွက် Host ၁လုံးကို တစ်ကြိမ်စီခွဲ run ပြီး စက္ကန့် ၂၀လောက်ကြာသွားတာကို တွေ့ရမှာပဲဖြစ်ပါတယ်။
ဒီလောက်ဆို Forks နဲ့ Serial ကိုသုံးပြီး Playbook တွေရဲ့ Performance ကို ချိန်ညှိနိုင်ဖို့ရာ အထောက်အကူပြုလိမ့်မယ် ထင်ပါတယ်။ Performance impact က Managed Host တွေတင်မဟုတ်ပဲ Control Node မှာပါ ရှိနိုင်တယ်ဆိုတာကိုတော့ သတိထားစေချင်ပါတယ်။
Reference: Rolling Update Batch Size