为什么用 Ansible 复制目录这么慢?

Why is copying a directory with Ansible so slow?

我正在使用 Ansible 将目录(900 个文件,136MBytes)从一台主机复制到另一台主机:

---
- name: copy a directory
      copy: src={{some_directory}} dest={{remote_directory}}

这个操作耗时令人难以置信的 17 分钟,而一个简单的 scp -r <src> <dest> 只需 7 秒。

按照ansible docs试过Accelerated模式,但是没用。

can be anywhere from 2-6x faster than SSH with ControlPersist enabled, and 10x faster than paramiko.

TLDR:使用 synchronize 而不是 copy

这是我正在使用的 copy 命令:

- copy: src=testdata dest=/tmp/testdata/

作为猜测,我假设同步操作很慢。 files module documentation 也暗示了这一点:

The "copy" module recursively copy facility does not scale to lots (>hundreds) of files. For alternative, see synchronize module, which is a wrapper around rsync.

深入研究源显示 each file is processed with SHA1. That's implemented using hashlib.sha1。本地测试表明 900 个文件只需要 10 秒(恰好需要 400mb space)。

那么,下一条路。使用 module_utils/basic.py's atomic_move method. I'm not sure if accelerated mode helps (it's a mostly-deprecated feature), but I tried pipelining 处理副本,将其放在本地 ansible.cfg:

[ssh_connection]
pipelining=True

它没有出现来提供帮助;我的样本花了 24 分钟才达到 运行 。显然有一个循环检查文件、上传文件、修复权限,然后开始处理下一个文件。这是很多命令,即使 ssh 连接保持打开状态也是如此。从字里行间读起来有点道理——我认为 "file transfer" 无法在流水线中完成。

所以,按照提示使用 synchronize 命令:

- synchronize: src=testdata dest=/tmp/testdata/

这花了 18 秒,即使是 pipeline=False。显然,synchronize 命令是这种情况下的方法。

记住 synchronize 使用 rsync,它默认为 mod-时间和文件大小。如果您想要或需要校验和,请将 checksum=True 添加到命令中。即使启用了校验和,时间也没有真正改变——仍然是 15-18 秒。我通过 运行ning ansible-playbook-vvvv 验证了校验和选项,可以在这里看到:

ok: [testhost] => {"changed": false, "cmd": "rsync --delay-updates -FF --compress --checksum --archive --rsh 'ssh  -o StrictHostKeyChecking=no' --out-format='<<CHANGED>>%i %n%L' \"testdata\" \"user@testhost:/tmp/testdata/\"", "msg": "", "rc": 0, "stdout_lines": []}

synchronize 配置在 become_user 的环境中可以是 difficult。对于一次性部署,您可以存档源目录并使用 unarchive 模块复制它:

- name: copy a directory
  unarchive:
    src: some_directory.tar.gz
    dest: {{remote_directory}}
    creates: {{remote_directory}}/indicator_file

我找到的最佳解决方案是压缩文件夹并使用 unarchive 模块。

450 MB 文件夹在 1 分钟内完成。


unarchive:
   src: /home/user/folder1.tar.gz
   dest: /opt

虽然 synchronize 在这种情况下比 copy 更可取,但它是由 rsync 烘焙的。这意味着 rsync(客户端-服务器架构)的缺点也仍然存在:CPU 和磁盘边界、大文件的文件内增量计算速度慢等。听起来对你来说速度很关键,所以我建议您正在寻找一种基于对等架构的解决方案,该架构可以快速且轻松地扩展到多台机器。类似于基于 BitTorrent 的 Resilio Connect。