我有一台 KVM 主机,上面有几台虚拟机。每台虚拟机都使用主机上的逻辑卷。我需要将 LV 复制到另一台主机。
通常情况下,我会使用类似的东西:
dd if=/the/logical-volume of=/some/path/machine.dd
将 LV 转换为映像文件并使用 SCP 移动它。然后使用 DD 将文件复制回新主机上的新 LV。
这种方法的问题是,你需要两倍于虚拟机在两台机器上占用的磁盘空间。例如,5GB LV 使用 5GB 空间用于 LV,而 dd 副本还使用额外的 5GB 空间用于映像。这对于小型 LV 来说没问题,但如果(就像我的情况一样)你有一个 500GB 的 LV 用于大型虚拟机怎么办?新主机有 1TB 硬盘,因此无法容纳 500GB dd 映像文件和有一个 500GB 的逻辑卷需要复制和有空间容纳主机操作系统和可供其他较小的客人使用。
我想要做的是这样的:
dd if=/dev/mygroup-mylv of=192.168.1.103/dev/newvgroup-newlv
换句话说,通过网络将数据直接从一个逻辑卷复制到另一个逻辑卷,并跳过中间映像文件。
这可能吗?
答案1
当然,当然有可能。
dd if=/dev/mygroup-mylv | ssh 192.168.1.103 dd of=/dev/newvgroup-newlv
繁荣。
不过,请帮自己一个忙,使用比默认块大小更大的块大小。也许可以添加 bs=4M(以 4 MB 的块为单位进行读取/写入)。您可以在评论中看到对块大小的吹毛求疵;如果您发现自己经常这样做,请花点时间用不同的块大小尝试几次,亲自看看哪种块大小能为您带来最佳传输速率。
回答评论中的一个问题:
您可以通过管道传输光伏获取有关传输的统计数据。这比发送信号到 获得的输出好得多dd
。
我还要说的是,虽然使用 netcat(或任何其他不产生加密开销的工具)当然会更高效,但我通常发现额外的速度是以牺牲一些便利性为代价的。除非我要移动非常大的数据集,否则我通常会坚持使用 ssh,尽管这会带来开销,因为在大多数情况下,一切都已设置为 Just Work。
答案2
这是一个优化版本,它显示了使用进度pv
并使用 BS 来处理更大的块,还用于gzip
减少网络流量。
在互联网服务器等慢速连接之间移动数据时,这非常完美。我建议在屏幕或 tmux 会话中运行该命令。这样,您执行命令的主机的 ssh 连接就可以毫无问题地断开。
$ dd if=/dev/volumegroupname/logicalvolume bs=4096 | pv | gzip | \
ssh [email protected] 'gzip -d | dd of=/dev/volumegroupname/logicalvolume bs=4096'
答案3
用老朋友来做这件事怎么样?NetCat。
在丢失逻辑卷类型的系统上
$ dd if=/dev/[directory]/[volume-name] | nc -l [any high number port]
然后在接收系统上输入
$ nc -w 10 [ip or name] [port] | dd of=/dev/[directory/[volume name]
翻译一下,orgin box dd 此文件并将其通过管道传输到将监听此端口的 nc (netcat)。在接收系统上,如果 netcat 在关闭 [端口] 上的 [ip 或名称] 之前未收到任何数据,则它将等待 10 秒,然后将该数据通过管道传输到 dd 以将其写出。
答案4
首先确保逻辑卷未挂载。如果已挂载,并且您想要进行“热复制”,请先创建快照,然后改用以下方法:
lvcreate --snapshot --name transfer_snap --size 1G
我必须在两个 1Gbit 连接的服务器之间传输大量数据(7TB),因此我需要尽可能快的方式来完成。
您应该使用 SSH 吗?
使用 ssh 是不可能的,不是因为它的加密(如果你有一个支持 AES-NI 的 CPU,它不会造成太大的伤害),而是因为它的网络缓冲区。这些都不是很好的扩展。有一个修补的 Ssh 版本解决了这个问题,但由于没有预编译的包,所以不太方便。
使用压缩
传输原始磁盘映像时,始终建议使用压缩。但您不希望压缩成为瓶颈。大多数 unix 压缩工具(如 gzip)都是单线程的,因此如果压缩使一个 CPU 饱和,它将成为瓶颈。出于这个原因,我总是使用 pigz,这是一种使用所有 CPU 核心进行压缩的 gzip 变体。如果您想要达到或超过 GBit 的速度,这是必要的。
使用加密
如前所述,ssh 很慢。如果您有 AES-NI CPU,这应该不会成为瓶颈。因此,我们可以直接使用 openssl,而不是使用 ssh。
速度
为了让您了解组件对速度的影响,以下是我的结果。这些是两个生产系统在读取和写入内存之间的传输速度。您的实际结果取决于网络速度、硬盘速度和源 CPU 速度!我这样做是为了表明至少没有巨大的性能下降。
Simple nc dd: 5033164800 bytes (5.0 GB, 4.7 GiB) copied, 47.3576 s, 106 MB/s +pigz compression level 1 (speed gain depends on actual data): network traffic: 2.52GiB 5033164800 bytes (5.0 GB, 4.7 GiB) copied, 38.8045 s, 130 MB/s +pigz compression level 5: network traffic: 2.43GiB 5033164800 bytes (5.0 GB, 4.7 GiB) copied, 44.4623 s, 113 MB/s +compression level 1 + openssl encryption: network traffic: 2.52GiB 5033164800 bytes (5.0 GB, 4.7 GiB) copied, 43.1163 s, 117 MB/s
结论:使用压缩可以显着提高速度,因为它可以大大减少数据大小。如果您的网络速度较慢,这一点就更为重要。使用压缩时,请注意您的 CPU 使用率。如果使用率达到最大值,您可以尝试不使用它。使用压缩对 AES-NI 系统的影响很小,在我看来只是因为它从压缩中窃取了大约 30-40% 的 CPU。
使用 Screen
如果你像我一样正在传输大量数据,你肯定不希望因为 ssh 客户端的网络断开而中断传输,所以最好在两端都使用 screen 启动。这只是一个说明,我不会在这里写一个 screen 教程。
让我们复制
安装一些依赖项(在源和目标上):
apt install pigz pv netcat-openbsd
然后在目标上创建一个与源大小相同的卷。如果不确定,请在源上使用 lvdisplay 获取大小并创建目标,即:
lvcreate -n lvname vgname -L 50G
接下来,准备接收数据的目标:
nc -l -p 444 | openssl aes-256-cbc -d -salt -pass pass:asdkjn2hb | pigz -d | dd bs=16M of=/dev/vgname/lvname
准备就绪后,开始在源上进行传输:
pv -r -t -b -p -e /dev/vgname/lvname | pigz -1 | openssl aes-256-cbc -salt -pass pass:asdkjn2hb | nc <destip/host> 444 -q 1
注意:如果您在本地传输数据或不关心加密,只需从两侧删除 Openssl 部分。如果您关心,asdkjn2hb 是加密密钥,您应该更改它。