我有下面的剧本
test1.yml
,它获取此目录下26个子文件夹的istat
数据/var/myfile/pdf
。
tasks:
- name: List directories
raw: "ls -d "/var/myfile/pdf/*/"
register: subdir
- name: List pid files
raw: "istat {{ item }}"
with_items: "{{ subdir.stdout_lines }}"
我运行剧本,需要 29 秒才能完成。
time ANSIBLE_SSH_PIPELINING=True ansible-playbook -i=10.9.9.12, -f 30 test1.yml -vvv
剧本完成后,下面是所用时间的详细输出:
Output:
real 0m29.144s
user 0m6.206s
sys 0m5.618s
我现在将与
istat
任务相同的代码放入 include_tasks
文件中,如下所示。
剧本
test2.yml
tasks:
- name: List directories
raw: "ls -d "/var/myfile/pdf/*/"
register: subdir
- name: List pid files
include_tasks: "innertest.yml"
with_items: "{{ subdir.stdout_lines }}"
cat innertest.yml
- raw: "istat {{ item }}"
time ANSIBLE_SSH_PIPELINING=True ansible-playbook -i=10.9.9.12, -f 30 test2.yml -vvv
Output:
real 0m59.044s
user 0m18.203s
sys 0m10.118s
正如您所见,由于
include_tasks
,相同数量的任务所花费的时间增加了一倍以上
在调试中,我还看到同一目标主机
with_items
的26个子目录10.9.9.12
触发了26个SHH连接。
我不确定这在内部是如何工作的,但出于性能原因,如果在同一主机上有 26 个子目录的
istat
单个 SSH 连接就好了。
有没有办法提高
include_tasks
的性能并减少同一主机的 ssh 连接数量?
有没有办法提高性能......并减少同一主机的 SSH 连接数量?
我理解您想知道“如何提高特定任务的性能并减少执行时间?”。
为了实现您的目标,您可以查看以下示例、文档和更多链接。
---
- hosts: test
become: false
gather_facts: false
tasks:
- name: Gather subdirectories
shell:
cmd: "ls -d /home/{{ ansible_user }}/*/"
warn: false
register: subdirs
- name: Gather stats (loop)
shell:
cmd: "stat {{ item }}"
warn: false
loop: "{{ subdirs.stdout_lines }}"
loop_control:
label: "{{ item }}"
- name: Gather stats (list)
shell:
cmd: "stat {% raw %}{{% endraw %}{{ subdirs.stdout_lines | join(',') }}{% raw %}}{% endraw %}"
warn: false
register: result
- name: Show result
debug:
var: result.stdout
导致
的执行和运行时间TASK [Gather subdirectories] ***********************
changed: [test.example.com]
Sunday 31 July 2022 (0:00:01.412) 0:00:01.448 ******
TASK [Gather stats (loop)] *************************
changed: [test.example.com] => (item=/home/user/01/)
changed: [test.example.com] => (item=/home/user/02/)
changed: [test.example.com] => (item=/home/user/03/)
...
changed: [test.example.com] => (item=/home/user/24/)
changed: [test.example.com] => (item=/home/user/25/)
changed: [test.example.com] => (item=/home/user/26/)
Sunday 31 July 2022 (0:00:31.715) 0:00:33.164 ******
TASK [Gather stats (list)] *************************
changed: [test.example.com]
Sunday 31 July 2022 (0:00:01.361) 0:00:34.525 ******
Gather subdirectories ------------------------ 1.41s
Gather stats (loop) ------------------------- 31.72s
Gather stats (list) -------------------------- 1.36s
Show result ---------------------------------- 0.08s
raw
模块 进行了测试,而不是使用 shell
模块
Gather stats (loop) via 'raw' ---------------- 4.96s
Gather stats (list) via 'raw' ---------------- 0.27s
循环命令并为每次运行的命令提供一个参数会导致大量开销和多个 SSH 连接,直接向命令提供列表可能是可能的,可以提高性能并减少运行时间和资源消耗。
出于性能原因,如果能够在同一主机上为
提供单个 SSH 连接来连接 26 个子目录就好了。istat
为此,您只需执行一次任务,从而仅产生一个 SSH 连接。为此,您可以直接通过 Ansible 向命令提供目录列表,如示例中所示
istat {01,02,03,...,24,25,26}
如您所见,为此命令需要包含需要在 Ansible 中转义的大括号。目录列表需要是一个字符串,目录之间用逗号分隔。为此,您可以使用
join()
过滤器。
最后你会得到
istat {% raw %}{{% endraw %}{{ subdir.stdout_lines | join(',') }}{% raw %}}{% endraw %}"
类似问题及答案
更多文档