首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在SSH连接方面优化Ansible剧本的性能?

如何在SSH连接方面优化Ansible剧本的性能?
EN

Stack Overflow用户
提问于 2020-10-02 10:19:59
回答 1查看 155关注 0票数 2

我有下面的剧本test1.yml,它在这个目录/var/myfile/pdf下获取26个子文件夹的istat数据。

代码语言:javascript
复制
  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秒才能完成。

代码语言:javascript
复制
time ANSIBLE_SSH_PIPELINING=True ansible-playbook -i=10.9.9.12, -f 30 test1.yml -vvv

在游戏完成后,下面是详细信息输出所需的时间:

代码语言:javascript
复制
Output:

    real    0m29.144s
    user    0m6.206s
    sys     0m5.618s

现在,我将与istat任务相同的代码放在include_tasks文件中,如下所示。

剧本test2.yml

代码语言:javascript
复制
  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 }}"
代码语言:javascript
复制
cat innertest.yml
代码语言:javascript
复制
      - raw: "istat {{ item }}"
代码语言:javascript
复制
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连接的数量?

EN

回答 1

Stack Overflow用户

发布于 2022-07-31 08:43:54

有没有办法提高表演..。减少到同一台主机的SSH连接的数量?

我知道您想知道“如何提高特定任务的性能并缩短执行时间?”

为了实现您的目标,您可以查看下面的示例、文档和进一步的链接。

代码语言:javascript
复制
---
- 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

的执行和运行时

代码语言:javascript
复制
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

我还用模块进行了测试,而不是使用shell模块

代码语言:javascript
复制
Gather stats (loop) via 'raw' ---------------- 4.96s
Gather stats (list) via 'raw' ---------------- 0.27s

将命令循环起来并为每次运行的命令提供一个参数也会导致大量开销和多个SSH连接,直接向命令提供列表是可能的,从而提高性能,减少运行时和资源消耗。

出于性能原因,最好为同一主机上的26个子目录为istat提供一个SSH连接。

为此,您只需执行一次任务,只需建立一个SSH连接。为此,您可能可以通过Ansible直接向命令提供目录列表,例如

代码语言:javascript
复制
istat {01,02,03,...,24,25,26}

如您所见,为此,命令需要包含大括号,这些大括号需要在Ansible中转义。目录列表需要是一个字符串,其中目录是逗号分隔的。为此,您可以使用join()过滤器。

最后你最终会

代码语言:javascript
复制
istat {% raw %}{{% endraw %}{{ subdir.stdout_lines | join(',') }}{% raw %}}{% endraw %}"

类似的问题,答案是

进一步文档

进一步阅读

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64169947

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档