在 Ansible 中并行解压 zip 存档以加速 playbook 执行失败:“此任务不支持异步。”

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

我有一个剧本,应该下载并解压多个 zip 文件。这些存档大小为数百 MB 到数 GB,因此这两个步骤都需要一些时间。我想通过异步操作提高性能:

- name: Downloading cnx 6.5 files from flexnet
  become: yes
  flexnet_download:
    user: "{{ flexnet_download.user }}"
    password: "{{ flexnet_download.password }}"
    target: "{{ flexnet_download.target }}/cnx"
    package_id: HCL_Connections_6.5_CRx
    files:
      - HCL_Connections_6.5_lin.tar

- name: Downloading db2 files from flexnet
  become: yes
  async: 3600 #1h
  poll: 0
  flexnet_download:
    user: "{{ flexnet_download.user }}"
    password: "{{ flexnet_download.password }}"
    target: "{{ flexnet_download.target }}/db2"
    package_id: HCL_Connections_6.5
    files:
      - CNB75ML.tar
      - CNB23ML.zip

- name: "Unpack cnx installer archive {{ cnx.install_archive_core }} to {{ cnx.install_dir_core }}"
  become: yes
  async: 3600 #1h
  poll: 0
  unarchive:
    src: "{{ cnx.install_archive_core }}"
    dest: "{{ cnx.install_dir_core }}"
    creates: "{{ cnx.install_dir_core }}/launchpad.sh"
    extra_opts:
      - --strip=1

第一个任务下载第一个 zip。然后,我尝试在提取第一个 zip 的同时并行下载其他 zip(

cnx.install_archive_core
HC6.5_CR1.zip
的完整路径)。不幸的是,
unarchive
任务失败了:

TASK [Unpack cnx installer archive /opt/cnx-install/cnx/HCL_Connections_6.5_lin.tar to /opt/cnx-install/cnx/core] **********************************************************************************
Saturday 06 February 2021  12:45:19 +0000 (0:02:39.856)       0:02:40.551 *****
fatal: [127.0.0.1]: FAILED! => changed=false
  msg: async is not supported for this task.

我猜

unarchive
模块不支持。但我想知道 unarchive
 模块
中似乎没有关于它的文档。由于 Ansible 幸运的是开源的,我
发现了这个检查,似乎模块需要设置一个属性_supports_async = True
以允许异步使用。当
搜索异步插件时,我只找到了8个插件 - 它们都不能用于提取。

有没有其他方法可以异步解压档案?

或者必须做什么才能向

unarchive

 模块添加异步支持?我猜异步是通过
在后台运行任务然后在指定的时间间隔内轮询stdout/stderr来实现的。

以这种方式使用

unzip
 CLI 工具提取时需要考虑什么?

我知道这不是首选的

Ansible 做事方式。但我看到的唯一方法是在 shell 上手动运行 unzip

command 插件支持异步

python asynchronous parallel-processing ansible unzip
1个回答
0
投票
unarchive

模块仍然不支持异步模式。

但是仍然有一些方法可以欺骗 Ansible。

使用库存并行运行戏剧

我们可以连接到同一目标主机两次(或更多)并照常运行它们,而不是异步运行两个(或更多)任务。因为 Ansible 并行运行这些戏剧。

我们应该调整我们的库存 - 定义两个主机,它们的下载和目标目录参数具有不同的值:

--- downloads: vars: ansible_connection: local # it could be any type ansible_host: localhost # also any - the idea is that it's the same machine for both host names in inventory install_archive_core: "./archive/Archive-{{ inventory_hostname }}.zip" install_dir_core: "unarchived/{{ inventory_hostname }}" # `cox` or `db2` is used to separate the paths hosts: cnx: package_id: HCL_Connections_6.5_CRx files: - HCL_Connections_6.5_lin.tar db2: package_id: HCL_Connections_6.5 files: - CNB75ML.tar - CNB23ML.zip

示例剧本(肯定是为了测试而简化的):

- name: Test async unpacking hosts: downloads gather_facts: false tasks: - name: Create the target directories file: path: "{{ install_dir_core }}" state: directory - name: Unpack the archive unarchive: src: "{{ install_archive_core }}" dest: "{{ install_dir_core }}" when: not ansible_check_mode

我们来测试一下。我有两个相同的档案:
Archive-cnx.zip

Archive-db2.zip
(均为 207,4 MB)。 解压一个
db2
存档大约需要 13.5 秒,而
cnx
则需要相同的时间:
ansible-playbook playbook.yml --inventory inventory.yml --limit db2

PLAY RECAP ******************************************************************************************************************************************************************************************
cnx                        : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Friday 29 December 2023  04:08:47 +0100 (0:00:13.492)       0:00:14.092 *******
=============================================================================== 
Unpack the archive ----------------------------------------------------- 13.49s
Create the target directories ------------------------------------------- 0.58s


并行解压两个档案仅需 20 秒:

ansible-playbook playbook.yml --inventory inventory.yml

PLAY RECAP ******************************************************************************************************************************************************************************************
cnx                        : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
db2                        : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Friday 29 December 2023  04:12:06 +0100 (0:00:19.866)       0:00:20.532 ******* 
=============================================================================== 
Unpack the archive ----------------------------------------------------- 19.87s
Create the target directories ------------------------------------------- 0.65s
策略

以此为基础,我们可以走得更远,取得更大的成就。由于我们需要在解压之前下载档案,并且可能还要做其他事情,因此我们可以让不同文件的工作流程是独立的,这样它们就不会互相等待。这就是

strategy: free

 可以提供帮助的地方:它不会阻止播放中当前批次的其他主机执行后续任务:
- name: Test async downloading and unpacking hosts: downloads gather_facts: false strategy: free tasks: - name: Downloading files from flexnet become: yes flexnet_download: user: "{{ flexnet_download.user }}" password: "{{ flexnet_download.password }}" target: "{{ install_archive_core }}" package_id: "{{ package_id }}" files: "{{ files }}" - name: Create the target directories file: path: "{{ install_dir_core }}" state: directory - name: Unpack the archive unarchive: src: "{{ install_archive_core }}" dest: "{{ install_dir_core }}" when: not ansible_check_mode

在此示例中,即使 
Downloading files from flexnet

任务需要更长的时间来处理其中一个文件,Ansible 也不会等待其完成,而是会尽快继续执行

Create the target directories
Unpack the archive
任务。我们仍然可以使用
Test async downloading and unpacking
并在以后的游戏中定义我们自己的同步点。
我解释了这种方法,并在此处稍微不同的上下文中提到了一些其他细节:
Ansible Playbook 运行一些主机并行和一些串行

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