WSL 1 和 WSL 2 有哪些关键不同?以及使用 Linux 工具链时,如何获取最大的文件性能?
WSL概述
适用于 Linux 的 Windows 子系统(Windows Subsystem for Linux,WSL)是 Windows 的一项功能,用于在 Windows 计算机上运行 Linux 环境,而无需完整的虚拟机。
目前 WSL 有 WSL 1 和 WSL 2 两个版本,虽然都是为了在 Windows 上运行 Linux 环境,但它们的实现方式完全不同。
| 功能 / 特点 |
WSL 1 |
WSL 2 |
| 架构 |
系统调用的翻译层 |
Hyper-V 轻量级虚拟机 |
| 文件系统 |
Windows NT 层模拟 Linux 文件系统 |
ext4 格式的 VHDX 文件系统 |
| 完整 Linux 内核 |
❌ |
✅ |
| 完整的系统调用兼容性 |
❌ |
✅ |
| systemd 支持 |
❌ |
✅ |
| 读写 Linux 上文件的性能 |
🚲 |
🚀 |
| 读写 Windows 上文件的性能 |
🚀 |
🐌 |
比较实现方式
WSL 1 是一个翻译层,在 Windows NT 内核上模拟 Linux 系统调用层,不是虚拟机也没有 Linux 内核。
WSL1 的机制是:
- Windows 截获 Linux 程序发出的系统调用;
- 转换成 Windows 的系统调用;
- 在 Windows 内核中执行。
WSL 2 是使用 Hyper-V 技术在轻量级虚拟机内运行特制内核的完整 Linux。
轻量级虚拟机是 Hyper-V 的一种特殊虚拟化模式,只提供运行 WSL 2、Docker Desktop 等功能所需的最少组件,由 Windows 自动创建、启动、停止和配置,动态分配资源且与 Windows 深度集成。
WSL 2 上 Linux 内核的“完整”和“特制”体现在以下方面:
- 保留核心功能:有完整的进程、内存管理、网络栈和文件系统支持,完整的系统调用接口;
- 精简非必须的功能:移除显卡等大多数硬件的驱动,硬件由 Hyper-V 虚拟化层提供;移除对老旧架构和部分企业级功能的支持;
- 添加 WSL 特有的功能模块:9P 文件系统用于访问 Windows 磁盘,内存动态调整,启动速度优化。
比较文件系统
WSL 1 的文件操作本质上都是 Windows 的 NTFS 文件系统在操作:
- 访问 Windows 文件:Windows 磁盘看似“挂载”在
/mnt 下,实际上翻译层会直接将文件路径 /mnt/c/xxx 转换为 Windows 路径 C:\xxx,相当于 NTFS 直接访问原始文件,速度快;
- Linux 根文件系统:在 NTFS 上仿真实现 Linux 文件系统的行为,增加额外的仿真开销,速度稍慢;
WSL 2 强烈建议将文件放在 Linux 文件系统中:
- 访问 Windows 文件:Windows 磁盘使用 9P 网络文件系统协议挂载在
/mnt 下,属于跨系统文件访问,速度很慢;
- Linux 根文件系统:独立的 ext4 格式的 VHDX 文件,速度很快。
对文件读写性能进行排序:WSL 2 读写 Linux 文件 > WSL 1 读写 Windows 文件 > WSL 1 读写 Linux 文件 > WSL 2 读写 Windows 文件。
WSL2读写性能测试
若想获得最快的性能速度,请将文件存储在 WSL 文件系统中,使用 Linux 工具在 Linux 命令行中处理这些文件。跨操作系统访问文件可能会显著降低性能。
WSL 文档 - 最佳设置实践
WSL 2 操作 Linux 文件和 Windows 文件的性能差距有多大呢?让 AI 生成个脚本简单测试下:
>folded wsl_fs_benchmark.sh#!/bin/bash
echo "=== WSL2 Disk I/O Benchmark ===" echo
TEST_SIZE_MB=512 SMALL_FILES=2000
EXT4_DIR="$HOME/wsl_test_ext4" WIN_DIR="/mnt/d/wsl_test_win"
mkdir -p "$EXT4_DIR" "$WIN_DIR"
benchmark_seq_write() { DIR=$1 echo "[SEQ WRITE] Testing $DIR ..." dd if=/dev/zero of=$DIR/testfile bs=1M count=$TEST_SIZE_MB conv=fdatasync 2>&1 | grep -E --color=never 'copied' }
benchmark_seq_read() { DIR=$1 echo "[SEQ READ] Testing $DIR ..." dd if=$DIR/testfile of=/dev/null bs=1M 2>&1 | grep -E --color=never 'copied' }
benchmark_small_files() { DIR=$1 echo "[SMALL FILES] Creating $SMALL_FILES files in $DIR ..." START=$(date +%s.%N) for i in $(seq 1 $SMALL_FILES); do echo "hello" > "$DIR/small_$i.txt" done END=$(date +%s.%N) TIME=$(echo "$END - $START" | bc) echo "Time: $TIME seconds" }
echo "------------------------------------------" echo "Testing ext4 (/home)" echo "------------------------------------------" benchmark_seq_write "$EXT4_DIR" benchmark_seq_read "$EXT4_DIR" benchmark_small_files "$EXT4_DIR"
echo echo "------------------------------------------" echo "Testing Windows (/mnt/d)" echo "------------------------------------------" benchmark_seq_write "$WIN_DIR" benchmark_seq_read "$WIN_DIR" benchmark_small_files "$WIN_DIR"
echo echo "Benchmark complete!"
|
在 i5-12500H(4E8P)和 NVMe SSD 的环境下,测试结果如下:
>folded 原始测试结果$ ./wsl_fs_benchmark.sh === WSL2 Disk I/O Benchmark ===
------------------------------------------ Testing ext4 (/home) ------------------------------------------ [SEQ WRITE] Testing /home/thinklong/wsl_test_ext4 ... 536870912 bytes (537 MB, 512 MiB) copied, 0.592031 s, 907 MB/s [SEQ READ] Testing /home/thinklong/wsl_test_ext4 ... 536870912 bytes (537 MB, 512 MiB) copied, 0.102132 s, 5.3 GB/s [SMALL FILES] Creating 2000 files in /home/thinklong/wsl_test_ext4 ... Time: .079443942 seconds
------------------------------------------ Testing Windows (/mnt/d) ------------------------------------------ [SEQ WRITE] Testing /mnt/d/wsl_test_win ... 536870912 bytes (537 MB, 512 MiB) copied, 4.79956 s, 112 MB/s [SEQ READ] Testing /mnt/d/wsl_test_win ... 536870912 bytes (537 MB, 512 MiB) copied, 3.87322 s, 139 MB/s [SMALL FILES] Creating 2000 files in /mnt/d/wsl_test_win ... Time: 10.715896161 seconds
Benchmark complete!
|
---
config:
theme: 'base'
xyChart:
width: 600
height: 150
plotReservedSpacePercent: 50
showDataLabel: false
themeVariables:
xyChart:
darkMode: true
fontSize: 16px
backgroundColor: '#000'
titleColor: '#fcee09'
labelFontSize: 16
xAxisLabelColor: '#fff'
xAxisTitleColor: '#fff'
xAxisTickColor: '#fff'
xAxisLineColor: '#fff'
yAxisLabelColor: '#fff'
yAxisTitleColor: '#fff'
yAxisTickColor: '#fff'
yAxisLineColor: '#fff'
plotColorPalette: '#fcee09, #02d7f2'
---
xychart horizontal
title "WSL2操作不同文件系统的性能"
x-axis ["顺序读", "顺序写", "创建小文件"]
y-axis "速度(GB/s)" 0 --> 5.5
bar [5.3,0.89,5.36]
bar [0.14,0.11,0.04]
| 测试项目 |
Windows |
Linux |
| 顺序读(GB/s) |
0.14 |
5.3 |
| 顺序写(GB/s) |
0.11 |
0.89 |
| 创建大量小文件用时(秒) |
10.72 |
0.08 |
可以看到在 WSL 2 中,Linux 工具处理 Linux 文件的性能远远大于挂载的 Windows 文件。因此,官方文档强烈建议将文件存储在 Linux 文件系统中。
使用代理
想要在 WSL 2 内使用 Windows 宿主机上的代理,首先要知道 Widnows 在 WSL2 中的 IP 地址,可以通过下面两种方式来获取:
HOST_IP=$(ip route | awk '/default/ {print $3}')
HOST_IP=$(powershell.exe -Command "Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias 'WLAN' | Select-Object -ExpandProperty IPAddress" | tr -d '\r')
|
两种方式获得的 IP 地址不同,但都可以访问并使用到代理,只是访问路径会有略微差别:
- 方式一:WSL 2 直接通过 Hyper-V 虚拟交换机访问到 Windows 主机。
- 方式二:WSL 2 经过 NAT 网关通过 Windows 主机在物理网络中的真实 IP 访问。
脚本:
set_proxy.sh#!/bin/bash
HOST_IP=$(ip route | awk '/default/ {print $3}')
export http_proxy="http://$HOST_IP:7890" export https_proxy="$http_proxy" export HTTP_PROXY="$http_proxy" export HTTPS_PROXY="$http_proxy"
git config --global http.proxy "$http_proxy" git config --global https.proxy "$http_proxy"
|
管理维护
迁移wsl实例
wsl 实例默认位于 C 盘,如果需要迁移已有实例到其他磁盘,可以走先备份再导入的流程实现迁移。
PS > wsl --shutdown
PS > wsl -l -v NAME STATE VERSION * Ubuntu-24.04 Stopped 2
PS > wsl --export Ubuntu-24.04 D:\wsl\Ubuntu-24.04_20260127.tar 正在导出,这可能需要几分钟时间。 (40229 MB) 操作成功完成。
PS > wsl --unregister Ubuntu-24.04 正在注销。 操作成功完成。
PS > wsl --import Ubuntu-24.04 D:\wsl\Ubuntu-24.04\ D:\wsl\Ubuntu-24.04_20260127.tar --version 2 操作成功完成。
PS > wsl
PS > ubuntu2404.exe config --default-user thinklong
|
给磁盘瘦身
使用 diskpart 工具回收 VHDX 内已经释放但尚未回收的空间,适合在,可以减小 ext4.vhdx 文件体积:
PS > wsl --shutdown
PS > wsl -l -v NAME STATE VERSION * Ubuntu-24.04 Stopped 2
PS > (Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | Where-Object { $_.GetValue("DistributionName") -eq 'Ubuntu-24.04' }).GetValue("BasePath") + "\ext4.vhdx" C:\Users\chikai\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx
PS > diskpart Copyright (C) Microsoft Corporation. 在计算机上: THINKBOOK14PLUS DISKPART> select vdisk file="C:\Users\thinklong\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx" DiskPart 已成功选择虚拟磁盘文件。 DISKPART> attach vdisk readonly 100 百分比已完成 DiskPart 已成功连接虚拟磁盘文件。 DISKPART> compact vdisk 100 百分比已完成 DiskPart 已成功压缩虚拟磁盘文件。 DISKPART> detach vdisk DiskPart 已成功分离虚拟磁盘文件。 DISKPART> exit 退出 DiskPart...
|
参考资料
WSL 文档 - 比较 WSL 版本
WSL 文档 - 跨文件系统的文件存储和性能