我正在使用Ansible将目录(900个文件,136MBytes)从一个主机复制到另一个主机:
---
- name: copy a directory
copy: src={{some_directory}} dest={{remote_directory}}
此操作需要17分钟,而简单的scp -r <src> <dest>
只需7秒钟。
我尝试过加速模式,根据ansible docs“可以比启用ControlPersist的SSH快2-6倍,比paramiko快10倍。”,但无济于事。
答案 0 :(得分:78)
TLDR:使用synchronize
代替copy
。
这是我正在使用的copy
命令:
- copy: src=testdata dest=/tmp/testdata/
作为一种猜测,我认为同步操作很慢。 files module documentation也暗示了这一点:
“复制”模块递归复制工具不会扩展到批量(>数百)文件。有关替代方法,请参阅synchronize模块,它是rsync的包装。
深入了解来源each file is processed with SHA1。那是implemented using hashlib.sha1。本地测试意味着900个文件只需要10秒钟(恰好需要400mb的空间)。
所以,下一个途径。该副本由module_utils/basic.py's atomic_move method处理。我不确定加速模式是否有帮助(这是mostly-deprecated feature),但我尝试pipelining,将其放在本地ansible.cfg
中:
[ssh_connection]
pipelining=True
它没有出现来提供帮助;我的样本需要24分钟才能运行。显然有一个循环可以检查文件,上传文件,修复权限,然后在下一个文件上启动。即使ssh连接处于打开状态,这也是很多命令。在线之间阅读它有点意义 - 我认为,“文件传输”无法在流水线中完成。
因此,按照提示使用synchronize
命令:
- synchronize: src=testdata dest=/tmp/testdata/
即使使用pipeline=False
,也需要18秒。显然,synchronize
命令是这种情况下的方法。
请记住synchronize
使用rsync,默认为mod-time和文件大小。如果您需要或需要校验和,请在命令中添加checksum=True
。即使启用了校验和,时间也没有真正改变 - 仍然是15-18秒。我通过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": []}
答案 1 :(得分:8)
synchronize
的环境中, become_user
配置可以是difficult。对于一次性部署,您可以归档源目录并使用unarchive
模块复制它:
- name: copy a directory
unarchive:
src: some_directory.tar.gz
dest: {{remote_directory}}
creates: {{remote_directory}}/indicator_file
答案 2 :(得分:2)
我发现的最佳解决方案是只压缩文件夹并使用unarchive
模块。
450 MB文件夹在1分钟内完成。
unarchive:
src: /home/user/folder1.tar.gz
dest: /opt
答案 3 :(得分:0)
虽然synchronize
在这种情况下比copy
更可取,但它是由rsync烘焙的。这意味着还保留了rsync(客户端-服务器体系结构)的缺点:CPU和磁盘边界,大文件的文件内增量计算速度较慢等。听起来对您而言速度至关重要,所以我建议您寻找一种基于对等体系结构的解决方案,可快速轻松地扩展到许多计算机。类似于基于BitTorrent的Resilio Connect。