Golang編程并發(fā)工具庫(kù)MapReduce使用實(shí)踐
環(huán)境
go version go1.16.4 windows/amd64 Intel(R) Core(TM) i7-7820HK CPU @ 2.90GHz 4核心8線程
項(xiàng)目需求
處理數(shù)個(gè)約5MB的小文件
從源目錄讀取文件并拷貝到目標(biāo)目錄
計(jì)算源文件MD5和目標(biāo)文件MD5進(jìn)行對(duì)比,如不相同則報(bào)錯(cuò)并終止程序執(zhí)行
mapReduce使用說(shuō)明
go get -u github.com/tal-tech/go-zero
需求實(shí)現(xiàn)
判斷上下文是否中止 → 讀取數(shù)據(jù) → 寫(xiě)入數(shù)據(jù) → 校驗(yàn)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))
// 計(jì)算源數(shù)據(jù)MD5
sourceMD5 := hash.Md5(data)
// 獲取名稱
fields := strings.Split(d.Name(), "-")
// 目標(biāo)文件路徑
distFilePath := filepath.Join(distPath, fileName)
// 拷貝數(shù)據(jù)
os.WriteFile(distFilePath, data, 0600)
// 校驗(yàn)數(shù)據(jù)
distData, _err := os.ReadFile(distFilePath)
distMD5 := hash.Md5(distData)
if !bytes.EqualFold(sourceMD5, distMD5) {
return errors.New("md5校驗(yàn)失敗")
}
return nil
}
}
業(yè)務(wù)邏輯
創(chuàng)建任務(wù)隊(duì)列
type SourceMap = map[string]fs.DirEntry
func CopyFileToDist(ctx context.Context, source SourceMap) (err error) {
// 創(chuàng)建工作隊(duì)列
work := make([]func() error, 0, len(source))
for _name := range source {
// 創(chuàng)建任務(wù)
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
}
}
}
運(yùn)行結(jié)果
MapReduce
耗時(shí) 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,"耗時(shí)(ns)":109220900}
sync.WaitGroup
耗時(shí) 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,"耗時(shí)(ns)":109798000}
串行
耗時(shí) 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,"耗時(shí)(ns)":359307700}
結(jié)論
- 在不嚴(yán)格的情況下,執(zhí)行效率方面可以認(rèn)為 mapReduce ≈ sync.WaitGroup
- 易用性(包括并發(fā)和錯(cuò)誤處理),mapReduce 完勝 sync.WaitGroup
- mapReduce好用
引申閱讀
通過(guò)MapReduce降低服務(wù)響應(yīng)時(shí)間
以上就是Golang編程并發(fā)工具庫(kù)MapReduce使用實(shí)踐的詳細(xì)內(nèi)容,更多關(guān)于Golang并發(fā)工具庫(kù)MapReduce的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Go語(yǔ)言實(shí)現(xiàn)MapReduce的示例代碼
- 使用golang實(shí)現(xiàn)一個(gè)MapReduce的示例代碼
- golang并發(fā)工具M(jìn)apReduce降低服務(wù)響應(yīng)時(shí)間
- golang如何實(shí)現(xiàn)mapreduce單進(jìn)程版本詳解
- MongoDB中MapReduce的使用方法詳解
- Mongodb中MapReduce實(shí)現(xiàn)數(shù)據(jù)聚合方法詳解
- MongoDB學(xué)習(xí)筆記之MapReduce使用示例
- MongoDB中的MapReduce簡(jiǎn)介
- MongoDB中MapReduce編程模型使用實(shí)例
- Go通用的?MapReduce?工具函數(shù)詳解
相關(guān)文章
Golang利用compress/flate包來(lái)壓縮和解壓數(shù)據(jù)
在處理需要高效存儲(chǔ)和快速傳輸?shù)臄?shù)據(jù)時(shí),數(shù)據(jù)壓縮成為了一項(xiàng)不可或缺的技術(shù),Go語(yǔ)言的compress/flate包為我們提供了對(duì)DEFLATE壓縮格式的原生支持,本文將深入探討compress/flate包的使用方法,揭示如何利用它來(lái)壓縮和解壓數(shù)據(jù),并提供實(shí)際的代碼示例,需要的朋友可以參考下2024-08-08
多階段構(gòu)建優(yōu)化Go?程序Docker鏡像
這篇文章主要為大家介紹了多階段構(gòu)建優(yōu)化Go?程序Docker鏡像,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Go語(yǔ)言實(shí)現(xiàn)配置熱加載的方法分享
web項(xiàng)目,經(jīng)常需要熱啟動(dòng)各種各樣的配置信息,一旦這些服務(wù)發(fā)生變更,我們需要重新啟動(dòng)web server,以使配置生效,實(shí)現(xiàn)配置熱加載,本文為大家整理了幾個(gè)方法實(shí)現(xiàn)這個(gè)需求,需要的可以參考下2023-05-05
Golang Gin框架實(shí)現(xiàn)文件下載功能的示例代碼
本文主要介紹了Golang Gin框架實(shí)現(xiàn)文件下載功能的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
Go語(yǔ)言實(shí)現(xiàn)字符串切片賦值的方法小結(jié)
這篇文章主要給大家介紹了Go語(yǔ)言實(shí)現(xiàn)字符串切片賦值的兩種方法,分別是在for循環(huán)的range中以及在函數(shù)的參數(shù)傳遞中實(shí)現(xiàn),有需要的朋友們可以根據(jù)自己的需要選擇使用。下面來(lái)一起看看吧。2016-10-10
golang?使用chromedp獲取頁(yè)面請(qǐng)求日志network
這篇文章主要為大家介紹了golang?使用chromedp獲取頁(yè)面請(qǐng)求日志network方法實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11

