오래 못 할 짓 하지 않기

Erasure Coding - Reed Solomon 본문

4학년/캡스톤 (Capstone)

Erasure Coding - Reed Solomon

쫑알bot 2025. 1. 7. 14:54
728x90

https://github.com/klauspost/reedsolomon

 

GitHub - klauspost/reedsolomon: Reed-Solomon Erasure Coding in Go

Reed-Solomon Erasure Coding in Go. Contribute to klauspost/reedsolomon development by creating an account on GitHub.

github.com

 

위 코드에 있는 RS 를 사용했다.

 

[ 테스트 ]

 

 

 

1. 이걸 Encoding 해서 여러 조각(w/parity)으로 나누고

2. 한 조각을 지워서

3. 다시 복구해본다.

 

 

 

1. 여러 조각으로 나누고 ( 개수 지정 가능함 )

 

 

 

이렇게 여러 조각으로 만들고, 원본 파일을 지운다.

 

 

 

2. 한 조각을 지운다.

 

 

3. 복구 도전.

 

 

 

 

 


분산  /  복구 팀으로 나누어져 있었다.

 

본인은 복구 팀이었는데,

위와 같이 우리가 파일을 쪼갰을 때 그 데이터들이 새로운 .bin file로 만들어졌다.

 

이에 분산팀에서 우리가 쪼갰을 때 만들어진 file path만 주면 된다고 하여 코드를 수정했음.

 

func doEncode(fname string) []string {
	var paths []string

	// Create encoding matrix.
	enc, err := reedsolomon.NewStream(*dataShards, *parShards)
	checkErr(err)

	fmt.Println("Opening", fname)
	f, err := os.Open(fname)
	checkErr(err)

	instat, err := f.Stat()
	checkErr(err)

	shards := *dataShards + *parShards
	out := make([]*os.File, shards)

	// Create the resulting files.
	dir, file := filepath.Split(fname)
	if *outDir != "" {
		dir = *outDir
	}
	for i := range out {
		outfn := fmt.Sprintf("%s.%d", file, i)
		fmt.Println("Creating", outfn)
		out[i], err = os.Create(filepath.Join(dir, outfn))
		paths = append(paths, out[i].Name())

		checkErr(err)
	}

	// Split into files.
	data := make([]io.Writer, *dataShards)
	for i := range data {
		data[i] = out[i]
	}
	// Do the split
	err = enc.Split(f, data, instat.Size())
	checkErr(err)

	// Close and re-open the files.
	input := make([]io.Reader, *dataShards)

	for i := range data {
		out[i].Close()
		f, err := os.Open(out[i].Name())
		checkErr(err)
		input[i] = f
		defer f.Close()
	}

	// Create parity output writers
	parity := make([]io.Writer, *parShards)
	for i := range parity {
		parity[i] = out[*dataShards+i]
		defer out[*dataShards+i].Close()
	}

	// Encode parity
	err = enc.Encode(input, parity)
	checkErr(err)
	fmt.Printf("File split into %d data + %d parity shards.\n", *dataShards, *parShards)

	return paths
}

func main() {
	flag.Parse()
	args := flag.Args()
	if len(args) != 1 {
		fmt.Fprintf(os.Stderr, "Error: No input filename given\n")
		flag.Usage()
		os.Exit(1)
	}
	if (*dataShards + *parShards) > 256 {
		fmt.Fprintf(os.Stderr, "Error: sum of data and parity shards cannot exceed 256\n")
		os.Exit(1)
	}
	fname := args[0]
	paths := doEncode(fname)

	fmt.Println("result is the below")
	for i, path := range paths {
		fmt.Println(i, ": ", path)
	}
}

 

쪼개면서 파일을 만들 때

해당 파일의 이름(Path)을 배열에 담고

그 배열을 Return하는 방식으로 바꿨다.

 

 

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

(참고)

 

https://www.electricity-magnetism.org/ko/%EC%98%A4%EB%A5%98-%EC%A0%95%EC%A0%95-%EC%BD%94%EB%93%9C-%EB%94%94%EC%BD%94%EB%8D%94/