就在上周末,我为我的 FreeNAS 主机器设置了一个新的(全新安装)备份服务器,并在它们之间启动了手动完整池备份。两台机器都是企业级硬件,运行速度很快,之间的链接是直接的 10G 光纤 LAN(Chelsio),两台机器都拥有大量快速的 NVMe ZIL/缓存和 128GB 快速 ddr4,以及 Xeon v4 和 Supermicro 基板。我正在复制/拷贝的池是 14GB 实际数据,已删除 35GB 引用数据(2.5 倍重复数据删除)。池是条带镜像(4 组 3 向镜像,带有企业级 6+TB 7200 磁盘),而不是 RaidZ,因此它们甚至没有奇偶校验来减慢它们的速度。除了用于传输的 SSH 连接外,服务器或其连接上没有运行任何其他东西。该zfs send
命令包括发送重复数据删除所需的参数(尽管由于疏忽,未压缩)。
发件人命令:
zfs send -vvDRLe mypool@latest_snapshot | nc -N BACKUP_IP BACKUP_PORT
对接收方的命令:
nc -l PORT | zfs receive -vvFsd my_pool
我原本以为会发生以下两种情况之一 - 要么发送 14TB 并完成,要么发送 35TB,但已经发送的 21TB(重复数据删除)非常快,只需要发送 14 多 TB。但是相反,它似乎有意发送全部 35TB,而且速度非常慢 - 我做错了什么或误解了吗?
我不明白的是,即使对快照/数据集进行序列化,备份服务器的磁盘仍以几乎 100% 的速度运行,gstat
并且已经这样运行了整整 4 天。数据正确到达(我可以安装那些已完成的快照/数据集)。但发送整个池看起来总共需要大约 7 天的时间,整个过程中磁盘活动几乎为 100%。
在两台快速服务器之间的 10G 链路上传输 14TB 甚至 35TB - 无论控制台上显示的状态信息是什么 - 都不应该花那么长时间,除非难以置信效率低下,这似乎不太可能。
这两个系统都可以以接近 500 MB/s 的速度读取/写入 HDD 旋转器,并且 ZFS 优化了磁盘访问,并且不需要重新对数据进行重复数据删除,因为数据已经进行重复数据删除。
为什么要花这么长时间?为什么不只发送一次池中的原始块?
回复评论中的一些观点:
- netcat(北卡罗来纳州):
netcat (nc)
提供裸露的透明未加密 TCP 传输/隧道,用于在两个系统之间传输数据(还有其他用途) - 有点像 ssh/VPN,但除了线路上的裸露 TCP 握手之外,没有减速或重新打包。就zfs send
/zfs receive
而言,它们是直接通信,除了微小的延迟之外,链接netcat
应该以发送/接收可以处理的最大速度运行。 - 镜像盘速度:镜像的写入速度是所有磁盘中最慢的,但 ZFS 将这些磁盘视为条纹镜(两个系统上的 4 个 vdev 上的数据条带,每个 vdev 都是一个镜像)。如果源池已满 55%,目标池为空,假设 CPU 可以跟上,zfs 应该能够同时从 12 个磁盘读取数据,并写入 4 个磁盘,并且写入应该几乎都是连续的,没有其他 IO 活动。我认为任何镜像中最慢的磁盘可以以 >= 125MB/s 的速度进行顺序写入,这远低于现代企业 7200 HDD 的速率,并且备份可以按顺序填充,而不是随机 IO。这就是我获得持续复制率 >> 500MB/s 的地方。
- 重复数据删除表/RAM 充足性:重复数据删除表占用的 RAM 约为 40GB(每个条目的字节数 x 每个源池中的总块数
zdb
)。我在两个系统上都设置了一个 sysctl,为重复数据删除表和其他元数据保留 85GB 的 RAM,因此在使用 L2ARC(如果与 send/rcv 一起使用)之前,大约有 35GB 的 RAM 用于缓存数据。因此,重复数据删除和元数据不应从任何一台机器的 RAM 中清除。
速度和进度更新:
- 运行 5 天后,我得到了一些更新的进度统计数据。它以平均约 58 MB/秒的速度发送数据。虽然不是完全灾难性的,但它仍然支撑了上述问题。我预计速率约为该值的 10 倍,因为磁盘组一次最多可以读取 12 个 HDD(几乎 2 GB/秒)并一次最多写入 4 个磁盘(约 500 GB/秒)。它不必对数据进行重复数据删除或重新重复数据删除(据我所知),它在 3.5 GHz 4 + 8 核 Xeon v4 上运行,两个系统上都有大量 RAM,并且 LAN 可以达到 1GB/秒。
答案1
从你提到的压缩来看,我假设你描述的所有存储大小/速度都是未压缩的大小。如果不是,那么可以使传输时间延长一个等于平均压缩率的倍数(但如果磁盘访问是瓶颈则不然,因为解压缩/压缩发生在从磁盘读取之后zfs send
和写入磁盘之前zfs receive
)。
根据您目前收集的信息,您的瓶颈似乎是磁盘带宽,而不是网络连接。您提到每个系统都可以以 ~500MB/s 的速度读取/写入,因此 35TB 的最佳传输时间约为 20 小时(比仅通过 10Gb/s 网络传输慢 2.5 倍)。但是,根据您的镜像设置,我很惊讶读取和写入会获得相同的吞吐量 - 您确定吗?在发送系统上,您只需要从一个磁盘读取(因此您可以在三个磁盘上并行读取),但在接收系统上,您必须写入所有三个磁盘(因此您在任何给定时间都受到最慢磁盘的吞吐量的限制)。要测试接收端的写入吞吐量,您可以运行dd if=/dev/urandom of=some_file_in_pool bs=1M count=1024 conv=fdatasync
。
由于您说接收磁盘处于 100% 繁忙状态,我猜测它没有达到 500MB/s 的写入带宽。这可能是因为实际写入限制低于该值(dd
上面的命令应该可以确认),也可能是系统在接收期间必须执行元数据读取,这会通过添加大量磁盘寻道来破坏您良好的大 IO 大小写入工作负载。您应该能够使用 DTrace 更深入地调查第二个假设,以查看提供商io
认为您的读/写大小是多少。