眾所周知,Ansible是基於ssh(當然還有telnet,winrm等連接插件)的自動化配置管理工具,其簡單易用,無agent式的工作方式在很多場景中都有不少優勢,不過也是由於這種工作方式導致了它沒有其他c/s類的工具執行效率高,飽受其他C/S類工具使用者的譏諷,對此,Ansible官方也對Ansible的速度效率做了不少優化手段:
參數名/優化類別 | 說明 |
fact cache: | 將facts信息第一次收集后緩存到memory 或者redis 或者文件中。 |
gather_subset | 可選擇性的收集network ,hardware 等信息,而不是全部 |
control_path | 開啟ssh socket 持久化,復用ssh連接 |
pipelinling | 開啟ssh pipelining ,客戶端從管道中讀取執行渲染后的腳本,而不是在客戶端創建臨時文件 |
fork | 提高並行執行主機的數量 |
serial | 將play_hosts ① 中主機再分批執行 |
strategy | 默認linear ,每個主機的單個task執行完成會等待其他都完成后再執行下個任務,設置free 可不等待其他主機,繼續往下執行(看起來會比較亂),還有一個選項host_pinned ,我也不知道干嘛的 |
閑逛中無意發現了一個Mitogen的Ansible plugin(strategy plugin)
,當前已迭代到0.28版本,看介紹說能提升1.2x ~ 7x
以上的執行效率,着實驚人!
它通過高效的遠程過程調用來取代ansible默認的嵌入式與純python shell調用,它不會優化模塊本身的執行效率,只會盡可能快的
②去執行模塊獲取返回(執行模塊前也是有一系列連接,發送數據,傳輸渲染腳本等操作的)來提高整體的效率,特性如下(摘自原文,自行翻譯吧,英語渣,怕誤導人):
Expect a 1.25x - 7x speedup and a CPU usage reduction of at least 2x, depending on network conditions, modules executed, and time already spent by targets on useful work. Mitogen cannot improve a module once it is executing, it can only ensure the module executes as quickly as possible.
- One connection is used per target, in addition to one sudo invocation per user account. This is much better than SSH multiplexing combined with pipelining, as significant state can be maintained in RAM between steps, and system logs aren’t spammed with repeat authentication events.
- A single network roundtrip is used to execute a step whose code already exists in RAM on the target. Eliminating multiplexed SSH channel creation saves 4 ms runtime per 1 ms of network latency for every playbook step.
- Processes are aggressively reused, avoiding the cost of invoking Python and recompiling imports, saving 300-800 ms for every playbook step.
- Code is ephemerally cached in RAM, reducing bandwidth usage by an order of magnitudecompared to SSH pipelining, with around 5x fewer frames traversing the network in a typical run.
- Fewer writes to the target filesystem occur. In typical configurations, Ansible repeatedly rewrites and extracts ZIP files to multiple temporary directories on the target. Security issues relating to temporary files in cross-account scenarios are entirely avoided.
The effect is most potent on playbooks that execute many short-lived actions, where Ansible’s overhead dominates the cost of the operation, for example when executing large with_items
loops to run simple commands or write files.
大體就是執行過程中主機使用一個連接(默認每執行一個task
或者loop
循環都會重新打開一次連接的);渲染的執行代碼暫存於內存中;減少多路復用ssh
隧道的時間消耗;減少臨時文件傳輸的帶寬;代碼重用,避免代碼的重新編譯成本等
實現原理的話,可以去看下官網解釋,反正我是沒怎么看懂
① . play_hosts
為內置參數,指當前正在執行的playbook中的主機列表
②. 盡可能快的
指到運行模塊前的階段
說了這么多,那么怎么配置呢?
1. 下載安裝包
- wget https://files.pythonhosted.org/packages/source/m/mitogen/mitogen-0.2.8.tar.gz
- tar axf mitogen-0.2.8.tar.gz -C /opt/
2.配置插件(修改ansible.cfg)
- [defaults]
- strategy_plugins = /opt/mitogen-0.2.8/ansible_mitogen/plugins/strategy
- strategy = mitogen_linear
注: mitogen中也有三種模式
- mitogen_linear: 對應原生的linear
- mitogen_free: 對應原生的free
- mitogen_host_pinned: 對應原生的host_pinned
插件配置很簡單,我們來測試看看效果
我環境沒有很多主機,這里測試只用5個主機,所以我用了loop循環來代替大量的任務,主要有如下task:
- gather facts
- 創建臨時文件夾
- loop循環copy小文件指目標服務器(大文件帶寬不夠,大概1065個文件)
- loop循環執行shell一個echo(大概1000次)
- 刪除臨時目錄
playbook如下所示:
--- - hosts: cluster tasks: - name: Create directory file: path=/tmp/soft state=directory - name: Loop copy files copy: src={{ item }} dest=/tmp/soft/ loop: "{{ lookup('fileglob','/opt/soft/*').split(',') }}" - name: Loop execution shell shell: echo {{ item }} loop: "{{ range(0,1000) | list }}" - name: Delete tmp file: path=/tmp/soft state=absent
1.使用默認strategy策略(linear)
2.使用strategy策略為mitogen_linear
注:本例中我們開啟了profile_tasks
插件來統計task的任務時長(ansible.cfg中
配置callback_whitelist = profile_tasks
)
可怕。。。非常可怕,我們可以直觀的看到原來的任務用了半個多小時(等的難受),優化后只用了三分鍾!!其中循環傳輸文件的任務提高了13倍,循環執行shell的任務提高了4倍,非常不錯~
(該測試非理想場景,實際提升應根據特性考慮執行場景)
另外注意:
- 該插件目前支持Ansible2.3~2.8
- 該插件需要python(包括raw/script模塊)
- 該插件會影響一些插件的執行過程,需要額外配置(become sudo模式,delegate_to等)