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":"文件分類(lèi)完畢","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":"文件分類(lèi)完畢","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":"文件分類(lèi)完畢","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)文章
淺析Go語(yǔ)言容器之?dāng)?shù)組和切片的使用
在?Java?的核心庫(kù)中,集合框架可謂鼎鼎大名:Array?、List、Set等等,隨便拎一個(gè)出來(lái)都值得開(kāi)發(fā)者好好學(xué)習(xí)如何使用甚至是背后的設(shè)計(jì)源碼。雖然Go語(yǔ)言沒(méi)有如此豐富的容器類(lèi)型,但也有一些基本的容器供開(kāi)發(fā)者使用,接下來(lái)讓我們認(rèn)識(shí)一下這些容器類(lèi)型吧2022-11-11
Mac上Go環(huán)境和VS Code的正確安裝與配置方法
Go語(yǔ)言是一個(gè)新興的語(yǔ)言。下面介紹一下如何在Mac系統(tǒng)下安裝和使用這個(gè)語(yǔ)言,Go語(yǔ)言提供了mac下安裝包,可直接下載安裝包點(diǎn)擊安裝2018-03-03
beego獲取ajax數(shù)據(jù)的實(shí)例
下面小編就為大家分享一篇beego獲取ajax數(shù)據(jù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Go實(shí)現(xiàn)socks5服務(wù)器的方法
SOCKS5 是一個(gè)代理協(xié)議,它在使用TCP/IP協(xié)議通訊的前端機(jī)器和服務(wù)器機(jī)器之間扮演一個(gè)中介角色,使得內(nèi)部網(wǎng)中的前端機(jī)器變得能夠訪問(wèn)Internet網(wǎng)中的服務(wù)器,或者使通訊更加安全,這篇文章主要介紹了Go實(shí)現(xiàn)socks5服務(wù)器的方法,需要的朋友可以參考下2023-07-07
golang使用sync.singleflight解決熱點(diǎn)緩存穿透問(wèn)題
在go的sync包中,有一個(gè)singleflight包,里面有一個(gè)?singleflight.go文件,代碼加注釋,一共200行出頭,通過(guò)?singleflight可以很容易實(shí)現(xiàn)緩存和去重的效果,避免重復(fù)計(jì)算,接下來(lái)我們就給大家詳細(xì)介紹一下sync.singleflight如何解決熱點(diǎn)緩存穿透問(wèn)題2023-07-07
一文帶你了解Go語(yǔ)言實(shí)現(xiàn)的并發(fā)神庫(kù)conc
前幾天逛github發(fā)現(xiàn)了一個(gè)有趣的并發(fā)庫(kù)-conc,這篇文章將為大家詳細(xì)介紹一下這個(gè)庫(kù)的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的可以了解一下2023-01-01
簡(jiǎn)單聊聊Go語(yǔ)言中空結(jié)構(gòu)體和空字符串的特殊之處
在日常的編程過(guò)程中,大家應(yīng)該經(jīng)常能遇到各種”空“吧,比如空指針、空結(jié)構(gòu)體、空字符串等,本文就以?Go?語(yǔ)言為例,一起來(lái)看看空結(jié)構(gòu)體和空字符串在?Go?語(yǔ)言中的特殊之處吧2024-03-03
golang之?dāng)?shù)據(jù)驗(yàn)證validator的實(shí)現(xiàn)
這篇文章主要介紹了golang之?dāng)?shù)據(jù)驗(yàn)證validator的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
go語(yǔ)言中結(jié)構(gòu)體tag使用小結(jié)
Go語(yǔ)言是一種靜態(tài)類(lèi)型、編譯型的編程語(yǔ)言,其中結(jié)構(gòu)體是一種非常重要的數(shù)據(jù)類(lèi)型,本文就來(lái)介紹一下go語(yǔ)言中結(jié)構(gòu)體tag使用,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10

