wget 下载到 CIFS 挂载的速度太糟糕了;本地下载并cp分享即可

wget 下载到 CIFS 挂载的速度太糟糕了;本地下载并cp分享即可

我的 CIFS 共享 wget 下载速度非常糟糕。

这是wget直接下载到共享的速度:

d64-18ef-43d5-b295-   2%[                    ] 100.18M  11.7MB/s    eta 6m 2s

这是wget下载到本地FS的速度:

glish_x32.iso?t=cff   6%[>                   ] 253.20M  55.2MB/s    eta 70s

令人惊讶的是,这是从本地 FS 到 CIFS 共享的复制速度:

root@gw:/tmp# pv Win10_22H2_English_x32.iso > /opt/isos_rw/Win10_22H2_English_x32.iso
1.29GiB 0:00:25 [53.4MiB/s] [==============>                   ] 45% ETA 0:00:30

显然 wget 在这里做了一些有趣的事情。如何解决这个问题?其他下载工具也是一个选择。

编辑:我的主动坐骑:

//172.16.8.232/Install/Isos on /opt/isos_rw type cifs (rw,relatime,vers=3.0,cache=strict,username=InstallRW,uid=0,noforceuid,gid=0,noforcegid,addr=172.16.8.232,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mapposix,rsize=8388608,wsize=8388608,echo_interval=60,actimeo=1)

有问题的机器是我的网关机器,4 核 AMD GX-412TC SOC,具有 2GB RAM。我的上行链路是 0.5 Gig 光纤,通过 CAT6e 1000BASE-T 铜缆连接到 CIFS 共享。

在网关上,两个接口都是全双工的:

[   13.385878] igb 0000:01:00.0 enp1s0: igb: enp1s0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[   14.325858] igb 0000:02:00.0 enp2s0: igb: enp2s0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX

硬件:

01:00.0 Ethernet controller: Intel Corporation I211 Gigabit Network Connection (rev 03)
        Subsystem: Intel Corporation I211 Gigabit Network Connection
        Flags: bus master, fast devsel, latency 0, IRQ 29
        Memory at f7b00000 (32-bit, non-prefetchable) [size=128K]
        I/O ports at 1000 [size=32]
        Memory at f7b20000 (32-bit, non-prefetchable) [size=16K]
        Capabilities: [40] Power Management version 3
        Capabilities: [50] MSI: Enable- Count=1/1 Maskable+ 64bit+
        Capabilities: [70] MSI-X: Enable+ Count=5 Masked-
        Capabilities: [a0] Express Endpoint, MSI 00
        Capabilities: [100] Advanced Error Reporting
        Capabilities: [140] Device Serial Number 00-0d-b9-ff-ff-57-9b-8c
        Capabilities: [1a0] Transaction Processing Hints
        Kernel driver in use: igb
        Kernel modules: igb

CIFS 服务器(在我的 LAN 上)显示

Intel I210 Gigabit Network Connection 1 Gbps

还有什么值得补充的请在下面评论。

编辑:我将订购新硬件来检查这是否是硬件问题。我会回来报告。

编辑 N+1:运行 wget 和 top。查看结果。 CIFS 的 CPU 利用率约为 33%,而 SSD 几乎已满,为 95%。

CIFS wget CPU 利用率

SSD wget CPU 利用率

编辑 N+2: 今天有了新硬件。它还具有 I210 NICS,而不是 I211。现在我应该将发送-接收队列的数量增加一倍。我现在正在设置硬件。

编辑 N+3: 新硬件没有什么区别。不过,我正在做一些追踪。

wget to SSD (55 MB/s):

_newselect(5, [4], NULL, NULL, {tv_sec=0, tv_usec=949999}) = 1 (in [4], left {tv_sec=0, tv_usec=949994})
read(4, "\7\0\0H\213D$0L\213 H\270\0\0\0\0\0\0\0\0H\2138H\270\0\0\0\0\0\0"..., 8192) = 8192
write(3, "\7\0\0H\213D$0L\213 H\270\0\0\0\0\0\0\0\0H\2138H\270\0\0\0\0\0\0"..., 4096) = 4096
write(3, "_net_resolve_address\0grub_net_ro"..., 4096) = 4096
_newselect(5, [4], NULL, NULL, {tv_sec=0, tv_usec=949999}) = 1 (in [4], left {tv_sec=0, tv_usec=949995})
read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = 8192
write(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
write(3, "\0\0\1\0\0\0\3\0\0\0Y\0\0\0\0\0\0\0\236\1\0\0\0\0\0\0\1\0\0\0\f\0"..., 4096) = 4096
_newselect(5, [4], NULL, NULL, {tv_sec=0, tv_usec=949999}) = 1 (in [4], left {tv_sec=0, tv_usec=949995})
read(4, "\0\0\225\0\0\0\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\0\0\0\20\0"..., 8192) = 8192
write(3, "\0\0\225\0\0\0\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\0\0\0\20\0"..., 4096^C) = 4096
strace: Process 12012 detached

wget to CIFS (13MB/s):

_newselect(5, [4], NULL, NULL, {tv_sec=0, tv_usec=949999}) = 1 (in [4], left {tv_sec=0, tv_usec=949994})
read(4, "ATH\213L$0H\213T$8H\213t$(L\215L$pH\270\0\0\0\0\0\0\0\0"..., 8192) = 8192
write(3, "ATH\213L$0H\213T$8H\213t$(L\215L$pH\270\0\0\0\0\0\0\0\0"..., 8192) = 8192
_newselect(5, [4], NULL, NULL, {tv_sec=0, tv_usec=949999}) = 1 (in [4], left {tv_sec=0, tv_usec=949994})
read(4, "\0\0\0\0\0D\2138\351\202\6\0\0\200{\1\0\17\205d\4\0\0A\376\305\17\205[\4\0\0"..., 8192) = 8192
write(3, "\0\0\0\0\0D\2138\351\202\6\0\0\200{\1\0\17\205d\4\0\0A\376\305\17\205[\4\0\0"..., 8192) = 8192
_newselect(5, [4], NULL, NULL, {tv_sec=0, tv_usec=949999}) = 1 (in [4], left {tv_sec=0, tv_usec=949994})
read(4, "CRIPTION\0net_get_dhcp_option\0per"..., 8192) = 8192
write(3, "CRIPTION\0net_get_dhcp_option\0per"..., 8192^Cstrace: Process 12050 detached
 <detached ...>

因此,cp 最终使用了最佳的 write(2) 缓冲区大小 131072。但是,wget 使用 8192。该缓冲区大小明显根据上下文而变化,如您所见,直接 wget 到 FS 使用的写入缓冲区大小为 4096。

如果我自己缓冲输出:

root@gw:/opt/isos_rw/ubuntu# wget http://ftp.funet.fi/pub/Linux/mirrors/debian-cdimage/current/amd64/iso-cd/debian-9.7.0-amd64-xfce-CD-1.iso -O - | dd bs=100k > iso.iso
--2023-04-23 16:18:45--  http://ftp.funet.fi/pub/Linux/mirrors/debian-cdimage/current/amd64/iso-cd/debian-9.7.0-amd64-xfce-CD-1.iso
Resolving ftp.funet.fi (ftp.funet.fi)... 193.166.3.2, 2001:708:10:8::2
Connecting to ftp.funet.fi (ftp.funet.fi)|193.166.3.2|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 672137216 (641M) [application/x-iso9660-image]
Saving to: ‘STDOUT’

-                           100%[===========================================>] 641.00M  43.2MB/s    in 14s

2023-04-23 16:18:59 (46.0 MB/s) - written to stdout [672137216/672137216]

1+9203 records in
1+9203 records out
672137216 bytes (672 MB, 641 MiB) copied, 13.9526 s, 48.2 MB/s

我达到了足够好的速度。有什么线索吗?

之前忘记添加内核版本了,这里是:

root@gw:/opt/isos_rw/ubuntu# uname -a
Linux gw 4.19.0-23-686-pae #1 SMP Debian 4.19.269-1 (2022-12-20) i686 GNU/Linux

顺便说一句,curl 具有相同的速度:

root@gw:/opt/isos_rw/ubuntu# curl http://ftp.funet.fi/pub/Linux/mirrors/debian-cdimage/current/amd64/iso-cd/debian-9.7.0-amd64-xfce-CD-1.iso -o iso.iso
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  641M  100  641M    0     0  12.3M      0  0:00:51  0:00:51 --:--:-- 12.7M

通过 strace 分析,curl 交替对 SSD 进行 4096 和 12288 字节写入,奇怪的是对 CIFS 进行 8192 字节写入,似乎也利用某种上下文来获取该值。 curl 将其 102400 字节的接收缓冲区拆分为 CIFS 上的多个 8192 缓冲区写入。

答案1

我的设置也有这个问题。

正如 Artem S.Tashkinov 建议的那样,我尝试使用卷曲而不是 wget,奇迹发生了:我全速写入我的 cif fs。 ✅

所以获取阿克塞尔可能在文件系统上有写入方法,例如可能在每个字节写入之间刷新,因此它会产生低效的网络调用往返(这是猜测)。

编辑:

这篇文章之后我做了一些快速搜索,我发现这个线程

它解释了如何向 wget 添加缓冲系统。我使用的命令是

wget https://abigfile.iso -O- | buffer -s 512k -b 10 -p 85 > ./outfile.iso

这个命令还让我可以用我的全部带宽下载。

我怀疑现在 axel 和 wget 有默认的小缓冲区否(截至 08/23)暴露的选项让用户更改它。

相关内容