日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Golang編程并發工具庫MapReduce使用實踐_Golang

作者:EvaCcino ? 更新時間: 2022-06-27 編程語言

環境

go version go1.16.4 windows/amd64
Intel(R) Core(TM) i7-7820HK CPU @ 2.90GHz 4核心8線程

項目需求

處理數個約5MB的小文件

從源目錄讀取文件并拷貝到目標目錄

計算源文件MD5和目標文件MD5進行對比,如不相同則報錯并終止程序執行

mapReduce使用說明

go get -u github.com/tal-tech/go-zero

需求實現

判斷上下文是否中止 → 讀取數據 → 寫入數據 → 校驗MD5

 func fnBuilder(name string) func() error {
   return func() error {
        // 判斷上下文是否終止
        select {
        case <-ctx.Done():
          return ctx.Err()
        default:
        }
        // 讀取源數據
        data, _err := os.ReadFile(filepath.Join(sourcePath, fileName))
        // 計算源數據MD5
        sourceMD5 := hash.Md5(data)
        // 獲取名稱
        fields := strings.Split(d.Name(), "-")
        // 目標文件路徑
        distFilePath := filepath.Join(distPath, fileName)
        // 拷貝數據
        os.WriteFile(distFilePath, data, 0600)
        // 校驗數據
        distData, _err := os.ReadFile(distFilePath)
        distMD5 := hash.Md5(distData)
        if !bytes.EqualFold(sourceMD5, distMD5) {
          return errors.New("md5校驗失敗")
        }
        return nil
      }
 }

業務邏輯

創建任務隊列

type SourceMap = map[string]fs.DirEntry
func CopyFileToDist(ctx context.Context, source SourceMap) (err error) {
  // 創建工作隊列
  work := make([]func() error, 0, len(source))
  for _name := range source {
    // 創建任務
    work = append(work, fnBuilder(_name))
  }
  switch concurrency {
  default:
    // mapReduce
  case 1:
    // sync.waitGroup
  case 2:
    // 串行
  }
}

執行方式1:MapReduce

 func() {
    if err = mr.Finish(work...); err != nil {
      return err
    }
 }

執行方式2:sync.WaitGroup

func() {
    var wg sync.WaitGroup
    wg.Add(len(work))
    for k := range work {
      go func(index int) {
        defer wg.Done()
        if err = work[index](); err != nil {
          log.Errorln(err)
          return
        }
      }(k)
    }
    wg.Wait()
}

執行方式3:串行

func() {
    for _, fn := range work {
      if err = fn(); err != nil {
        return err
      }
    }
} 

運行結果

MapReduce

耗時 109220900 ns

{"file":"D:/go/src/filenamesSorter/main.go:44","func":"main.init.0","level":"info","msg":"并發處理(0-mapReduce 1-Sync.WaitGroup 2-不并發) 0","time":"2021-06-02T13:32:05+08:00"}
{"file":"D:/go/src/filenamesSorter/main.go:69","func":"main.main","level":"info","msg":"文件分類完畢","time":"2021-06-02T13:32:05+08:00","文件數":17,"耗時(ns)":109220900}

sync.WaitGroup

耗時 109798000 ns

{"file":"D:/go/src/filenamesSorter/main.go:44","func":"main.init.0","level":"info","msg":"并發處理(0-mapReduce 1-Sync.WaitGroup 2-不并發) 1","time":"2021-06-02T13:31:28+08:00"}
{"file":"D:/go/src/filenamesSorter/main.go:69","func":"main.main","level":"info","msg":"文件分類完畢","time":"2021-06-02T13:31:28+08:00","文件數":17,"耗時(ns)":109798000} 

串行

耗時 359307700 ns

{"file":"D:/go/src/filenamesSorter/main.go:44","func":"main.init.0","level":"info","msg":"并發處理(0-mapReduce 1-Sync.WaitGroup 2-不并發) 2","time":"2021-06-02T13:33:02+08:00"}
{"file":"D:/go/src/filenamesSorter/main.go:69","func":"main.main","level":"info","msg":"文件分類完畢","time":"2021-06-02T13:33:02+08:00","文件數":17,"耗時(ns)":359307700} 

結論

  • 在不嚴格的情況下,執行效率方面可以認為 mapReduce ≈ sync.WaitGroup
  • 易用性(包括并發和錯誤處理),mapReduce 完勝 sync.WaitGroup
  • mapReduce好用

引申閱讀

通過MapReduce降低服務響應時間

原文鏈接:https://blog.csdn.net/yes169yes123/article/details/117467920

欄目分類
最近更新