Golang編程并發(fā)工具庫MapReduce使用實踐
環(huán)境
go version go1.16.4 windows/amd64 Intel(R) Core(TM) i7-7820HK CPU @ 2.90GHz 4核心8線程
項目需求
處理數(shù)個約5MB的小文件
從源目錄讀取文件并拷貝到目標目錄
計算源文件MD5和目標文件MD5進行對比,如不相同則報錯并終止程序執(zhí)行
mapReduce使用說明
go get -u github.com/tal-tech/go-zero
需求實現(xiàn)
判斷上下文是否中止 → 讀取數(shù)據(jù) → 寫入數(shù)據(jù) → 校驗MD5
func fnBuilder(name string) func() error {
return func() error {
// 判斷上下文是否終止
select {
case <-ctx.Done():
return ctx.Err()
default:
}
// 讀取源數(shù)據(jù)
data, _err := os.ReadFile(filepath.Join(sourcePath, fileName))
// 計算源數(shù)據(jù)MD5
sourceMD5 := hash.Md5(data)
// 獲取名稱
fields := strings.Split(d.Name(), "-")
// 目標文件路徑
distFilePath := filepath.Join(distPath, fileName)
// 拷貝數(shù)據(jù)
os.WriteFile(distFilePath, data, 0600)
// 校驗數(shù)據(jù)
distData, _err := os.ReadFile(distFilePath)
distMD5 := hash.Md5(distData)
if !bytes.EqualFold(sourceMD5, distMD5) {
return errors.New("md5校驗失敗")
}
return nil
}
}
業(yè)務邏輯
創(chuàng)建任務隊列
type SourceMap = map[string]fs.DirEntry
func CopyFileToDist(ctx context.Context, source SourceMap) (err error) {
// 創(chuàng)建工作隊列
work := make([]func() error, 0, len(source))
for _name := range source {
// 創(chuàng)建任務
work = append(work, fnBuilder(_name))
}
switch concurrency {
default:
// mapReduce
case 1:
// sync.waitGroup
case 2:
// 串行
}
}
執(zhí)行方式1:MapReduce
func() {
if err = mr.Finish(work...); err != nil {
return err
}
}
執(zhí)行方式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()
}
執(zhí)行方式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":"并發(fā)處理(0-mapReduce 1-Sync.WaitGroup 2-不并發(fā)) 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","文件數(shù)":17,"耗時(ns)":109220900}
sync.WaitGroup
耗時 109798000 ns
{"file":"D:/go/src/filenamesSorter/main.go:44","func":"main.init.0","level":"info","msg":"并發(fā)處理(0-mapReduce 1-Sync.WaitGroup 2-不并發(fā)) 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","文件數(shù)":17,"耗時(ns)":109798000}
串行
耗時 359307700 ns
{"file":"D:/go/src/filenamesSorter/main.go:44","func":"main.init.0","level":"info","msg":"并發(fā)處理(0-mapReduce 1-Sync.WaitGroup 2-不并發(fā)) 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","文件數(shù)":17,"耗時(ns)":359307700}
結論
- 在不嚴格的情況下,執(zhí)行效率方面可以認為 mapReduce ≈ sync.WaitGroup
- 易用性(包括并發(fā)和錯誤處理),mapReduce 完勝 sync.WaitGroup
- mapReduce好用
引申閱讀
以上就是Golang編程并發(fā)工具庫MapReduce使用實踐的詳細內(nèi)容,更多關于Golang并發(fā)工具庫MapReduce的資料請關注腳本之家其它相關文章!
相關文章
Mac上Go環(huán)境和VS Code的正確安裝與配置方法
Go語言是一個新興的語言。下面介紹一下如何在Mac系統(tǒng)下安裝和使用這個語言,Go語言提供了mac下安裝包,可直接下載安裝包點擊安裝2018-03-03
golang使用sync.singleflight解決熱點緩存穿透問題
在go的sync包中,有一個singleflight包,里面有一個?singleflight.go文件,代碼加注釋,一共200行出頭,通過?singleflight可以很容易實現(xiàn)緩存和去重的效果,避免重復計算,接下來我們就給大家詳細介紹一下sync.singleflight如何解決熱點緩存穿透問題2023-07-07
一文帶你了解Go語言實現(xiàn)的并發(fā)神庫conc
前幾天逛github發(fā)現(xiàn)了一個有趣的并發(fā)庫-conc,這篇文章將為大家詳細介紹一下這個庫的實現(xiàn),文中的示例代碼講解詳細,感興趣的可以了解一下2023-01-01
golang之數(shù)據(jù)驗證validator的實現(xiàn)
這篇文章主要介紹了golang之數(shù)據(jù)驗證validator的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-10-10

