2021-MIT6.284 lab1 실험 환경 구축 및 디버깅 기술

GitHub 저장소에서 프로젝트 복제

$ git clone git://g.csail.mit.edu/6.824-golabs-2021 6.824
$ cd 6.824
$ ls
Makefile src
$

직렬 Wordcount 프로그램을 실행하면 사용자가 특정 Map 및 Reduce 기능을 제공하므로 wc.go를 wc.so 동적 링크 라이브러리로 컴파일해야합니다.

$ cd ~/6.824
$ cd src/main
$ go build -race -buildmode=plugin ../mrapps/wc.go
$ rm mr-out*
$ go run -race mrsequential.go wc.so pg*.txt
$ more mr-out-0
A 509
ABOUT 2
ACT 8
...

여러분의 임무는 코디네이터와 작업 자라는 두 프로그램으로 구성된 분산 형 MapReduce를 구현하는 것입니다. 코디네이터 프로세스는 하나만 있고 하나 이상의 작업자 프로세스가 병렬로 실행됩니다. 실제 시스템에서는 작업자가 여러 대의 다른 컴퓨터에서 실행되지만이 실습에서는 모두 단일 컴퓨터에서 실행됩니다. 작업자는 RPC를 통해 코디네이터와 대화합니다. 각 작업자 프로세스는 코디네이터에게 작업을 요청하고, 하나 이상의 파일에서 작업의 입력을 읽고, 작업을 실행하고, 작업의 출력을 하나 이상의 파일에 기록합니다. 코디네이터는 작업자가 적절한 시간 (이 실습의 경우 10 초 사용) 내에 작업을 완료하지 않았는지 확인하고 동일한 작업을 다른 작업자에게 제공해야합니다.

 

시작하기 위해 약간의 코드를 제공했습니다. 코디네이터와 작업자의 "기본"루틴은  main / mrcoordinator.go  및  main / mrworker.go에 있습니다 . 이 파일을 변경하지 마십시오. 구현을  mr / coordinator.gomr / worker.go 및  mr / rpc.go에 넣어야 합니다.

단어 수 MapReduce 애플리케이션에서 코드를 실행하는 방법은 다음과 같습니다. 먼저 단어 수 플러그인이 새로 빌드되었는지 확인합니다.

go build -race -buildmode=plugin ../mrapps/wc.go

기본 디렉터리에서 코디네이터를 실행합니다.

$ rm mr-out*
$ go run -race mrcoordinator.go pg-*.txt

mrcoordinator.go에 대한 pg-*. txt 인수는 입력 파일입니다. 각 파일은 하나의 "분할"에 해당하며 하나의 맵 태스크에 대한 입력입니다. -race 플래그 실행은 경쟁 감지기와 함께 이동합니다.

하나 이상의 다른 창에서 일부 작업자를 실행하십시오.

$ go run -race mrworker.go wc.so

 

  • 시작하는 한 가지 방법은 mr / worker.go의 Worker ()를 수정하여 작업을 요청하는 코디네이터에게 RPC를 보내는 것입니다. 그런 다음 아직 시작되지 않은 맵 작업의 파일 이름으로 응답하도록 코디네이터를 수정합니다. 그런 다음 작업자를 수정하여 해당 파일을 읽고 mrsequential.go에서와 같이 응용 프로그램 Map 함수를 호출합니다.

 

먼저 두 인터페이스 doMap 및 doReduce를 구현합니다.이 두 인터페이스에는 기본 알고리즘과 파일 읽기 및 쓰기가 포함됩니다.

func DoMap(inFile string, NReduce int, mapTask int, mapf func(string, string) []KeyValue){
	intermediate := []KeyValue{}
	file, err := os.Open(inFile)
	if err != nil {
		log.Fatalf("cannot open %v", inFile)
	}
	content, err := ioutil.ReadAll(file)
	if err != nil {
		log.Fatalf("cannot read %v", inFile)
	}
	file.Close()
	kva := mapf(inFile, string(content))
	intermediate = append(intermediate, kva...)
	OutFileArray := make([][]KeyValue,NReduce)
	for _, kv := range intermediate{
		index := ihash(kv.Key)%NReduce
		OutFileArray[index] = append(OutFileArray[index],kv)
	}

	for i :=0;i<NReduce;i++{
		outFile := fmt.Sprintf("mr-%v-%v", mapTask, i)
		f, openErr := os.OpenFile(outFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0664)
		if openErr != nil {
			log.Fatal("OpenFile: ", openErr)
		}
		defer f.Close()

		enc := json.NewEncoder(file)
		for _, kv :=  range OutFileArray[i] {
			enc.Encode(&kv)
		}
	}
}

 

doReduce

func DoReduce(reduceTask int, NMap int, outFile string, reducef func(string, []string) string){
	interMaps := make(map[string][]string)
	for i:=0;i<NMap;i++{
		filename := fmt.Sprintf("mr-%v-%v",i, reduceTask)
		file, err := os.Open(filename)
		if err != nil {
			log.Fatalf("cannot open %v", filename)
		}
		dec := json.NewDecoder(file)
		for {
			var kv KeyValue
			if err := dec.Decode(&kv); err != nil {
				break
			}
			// 如果Key还没有被统计过
			if _, ok := interMaps[kv.Key]; !ok {
				interMaps[kv.Key] = []string{kv.Value}
			}else{
				interMaps[kv.Key] = append(interMaps[kv.Key],kv.Key)
			}
		}
		f, openErr := os.OpenFile(outFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0664)
		if openErr != nil {
			log.Fatal("Open result file: ", openErr)
		}
		enc := json.NewEncoder(f)

		for key, value := range interMaps{
			enc.Encode(KeyValue{key, reducef(key,value)})
		}

		f.Close()
	}
}

그 후 RPC 로직을 디버그하십시오.

 

 

추천

출처blog.csdn.net/wwxy1995/article/details/113885853