MIT6.824 Lab1-MapReduce任务计数测试失败与ioutil.ReadDir重复文件问题
问题解决:WSL2下MIT6.824 Lab1 Job Count测试重复文件条目问题
问题背景
在WSL2 Ubuntu环境完成MIT6.824 Lab1-MapReduce实验时,其他测试全部通过,但任务计数测试(job count test)失败,输出如下:
*** Starting job count test. --- map jobs ran incorrect number of times (10 != 8) --- job count test: FAIL
排查发现:实际仅生成8个mr-worker-jobcount-*文件,但jobcount.go的Reduce函数调用ioutil.ReadDir(".")返回了重复的文件条目。
相关代码片段:
jobcount.go 原Map/Reduce函数
func Map(filename string, contents string) []mr.KeyValue { me := os.Getpid() f := fmt.Sprintf("mr-worker-jobcount-%d-%d", me, count) count++ err := ioutil.WriteFile(f, []byte("x"), 0666) if err != nil { panic(err) } time.Sleep(time.Duration(2000+rand.Intn(3000)) * time.Millisecond) return []mr.KeyValue{mr.KeyValue{"a", "x"}} } func Reduce(key string, values []string) string { files, err := ioutil.ReadDir(".") if err != nil { panic(err) } invocations := 0 for _, f := range files { invocations++ } return strconv.Itoa(invocations) }
测试脚本片段
echo '***' Starting job count test. rm -f mr-* $TIMEOUT ../mrcoordinator ../pg*txt & sleep 1 $TIMEOUT ../mrworker ../../mrapps/jobcount.so & $TIMEOUT ../mrworker ../../mrapps/jobcount.so $TIMEOUT ../mrworker ../../mrapps/jobcount.so & $TIMEOUT ../mrworker ../../mrapps/jobcount.so NT=`cat mr-out* | awk '{print $2}'` if [ "$NT" -eq "8" ] then echo '---' job count test: PASS else echo '---' map jobs ran incorrect number of times "($NT != 8)" echo '---' job count test: FAIL failed_any=1 fi wait
重复文件条目的成因
核心原因是WSL2的跨系统文件系统挂载机制:
- 当实验目录位于Windows挂载目录(如
/mnt/c)时,WSL2通过9P协议访问NTFS文件系统,该协议在并发文件操作场景下,目录遍历可能出现缓存不一致或重复枚举的问题。 - Map任务是并发执行的,多个worker同时创建
mr-worker-jobcount-*文件,Reduce任务读取目录时,9P协议的目录缓存未及时同步,导致ioutil.ReadDir返回重复的文件条目。 ioutil.ReadDir底层依赖系统调用readdir,在非原生Linux文件系统(如NTFS通过9P挂载)中,该调用的实现可能存在竞态条件,导致重复返回同一目录项。
不修改jobcount.go的解决方案
方案1:将实验目录迁移到WSL2原生文件系统
把Lab1的代码和测试文件放在WSL2内部的ext4文件系统中(如/home/your-username/6.824),而非Windows挂载目录。原生Linux文件系统不会有9P协议的兼容性问题,ioutil.ReadDir会正确返回唯一的目录条目。
方案2:调整WSL2文件系统挂载参数
修改WSL2的挂载配置,减少缓存不一致的概率:
- 在WSL2中创建
/etc/wsl.conf文件(若不存在)。 - 添加以下内容:
[automount] options = "metadata,umask=0022,case=off,noatime" mountFsTab = false - 关闭WSL2(在Windows命令行执行
wsl --shutdown),重新启动WSL2。该配置会优化9P协议的挂载参数,降低目录缓存不一致的概率。
方案3:确保Reduce任务在所有Map任务完成后执行
检查你的coordinator实现,确认是否严格遵循MapReduce流程:所有Map任务完成后才触发Reduce任务。若coordinator提前触发Reduce,可能导致Reduce在Map文件创建过程中读取目录,从而遇到未同步的文件条目。不过此方案仅适用于coordinator流程存在瑕疵的情况,若其他测试已通过,优先级低于前两个方案。
内容的提问来源于stack exchange,提问作者Aj002Th
相关产品推荐
相关产品推荐

