如何优化 Ansible playbook 在 SSH 连接方面的性能?

问题描述 投票:0回答:1

我有下面的剧本

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 连接数量?

performance time ssh ansible performance-testing
1个回答
0
投票

有没有办法提高性能......并减少同一主机的 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 连接,直接向命令提供列表可能是可能的,可以提高性能并减少运行时间和资源消耗。

出于性能原因,如果能够在同一主机上为

istat
提供单个 SSH 连接来连接 26 个子目录就好了。

为此,您只需执行一次任务,从而仅产生一个 SSH 连接。为此,您可以直接通过 Ansible 向命令提供目录列表,如示例中所示

istat {01,02,03,...,24,25,26}

如您所见,为此命令需要包含需要在 Ansible 中转义的大括号。目录列表需要是一个字符串,目录之间用逗号分隔。为此,您可以使用

join()
过滤器。

最后你会得到

istat {% raw %}{{% endraw %}{{ subdir.stdout_lines | join(',') }}{% raw %}}{% endraw %}"

类似问题及答案


更多文档

© www.soinside.com 2019 - 2024. All rights reserved.