Go 構(gòu)建 CLI 實(shí)踐: 在 ETL 中使用扇出模式

Go 語言在構(gòu)建微服務(wù)、特別是有使用 gRPC 的應(yīng)用中,非常地流行,其實(shí)在構(gòu)建命令行程序時(shí)也是特別地好用。為了學(xué)習(xí)扇出模式,我會(huì)基于我們公司使用 ETL 的例子,來介紹這個(gè)模式。
ETL
ETL(提?。‥xtract),轉(zhuǎn)換(Transform),加載(Load))通常都需要處理大量的數(shù)據(jù)。在這樣的場(chǎng)景下,有一個(gè)好的并發(fā)策略對(duì)于 ETL 來說,能夠帶來巨大的性能提升。
ETL 中有兩個(gè)最重要的部分是提?。╡xtracting)和加載(Load),通常它們都跟數(shù)據(jù)庫(kù)有關(guān),瓶頸通常也屬于老生常談的話題:網(wǎng)絡(luò)帶寬,查詢性能等等?;谖覀円幚淼臄?shù)據(jù)以及瓶頸所在,兩種模式對(duì)于處理數(shù)據(jù)或者處理輸入流的編碼和解碼過程中,非常有用。
扇入扇出模式(Fan-in, fan-out pattern)
扇入和扇出模式在并發(fā)場(chǎng)景中能得到較大的好處。這里將對(duì)它們逐個(gè)做專門的介紹(review):
扇出,在 GO 博客中這樣定義:
多個(gè)函數(shù)能夠同時(shí)從相同的 channel 中讀數(shù)據(jù),直到 channel 關(guān)閉。
這種模式在快速輸入流到分布式數(shù)據(jù)處理中,有一定的優(yōu)勢(shì):

扇入,在 Google 這樣定義:
一個(gè)函數(shù)可以從多個(gè)輸入中讀取,并繼續(xù)操作,直到所有 channel 所關(guān)聯(lián)的輸入端,都已經(jīng)關(guān)閉。
這種模式,在有多個(gè)輸入源,且需要快速地?cái)?shù)據(jù)處理中,有一定的優(yōu)勢(shì):

在實(shí)際中使用扇出模式(Fan-out in action)
在我們的項(xiàng)目中,我們需要處理存儲(chǔ)在 CSV 文件的大量數(shù)據(jù),它們加載后,將在 elastic 中被檢索。輸入的處理必須快,否則(阻塞加載)加載就會(huì)變得很慢。因此,我們需要比輸入生成器更多的數(shù)據(jù)處理器。扇出模式在這個(gè)例子中,看起來非常適合:

下面是我們的偽代碼:
Variables:
data chan
Start:
// a goroutine will parse the CSV and will send it to the channel
ParseCSV(data<-)
// a goroutine is started for each workers, defined as command line arguments
For each worker in workers
Start goroutine
For each value in <-data
Insert the value in database by chunk of 50
Wait for the workers
Stop
輸入和加載程序是并發(fā)執(zhí)行的,我們不需要等到解析完成后再開始啟動(dòng)數(shù)據(jù)處理程序。
這種模式讓我們可以單獨(dú)考慮業(yè)務(wù)邏輯的同時(shí),還可以使用(Go)并發(fā)的特性。幾個(gè)工作器之間原生的分布式負(fù)載能力,有助于我們解決此類過程中的峰值負(fù)載問題。
via: https://medium.com/a-journey-with-go/go-fan-out-pattern-in-our-etl-9357a1731257
作者:Vincent Blanchon[1] 譯者:gogeof[2] 校對(duì):Xiaobin.Liu[3]
本文由 GCTT[4] 原創(chuàng)編譯,Go 中文網(wǎng)[5] 榮譽(yù)推出
參考資料
Vincent Blanchon: https://medium.com/@blanchon.vincent
[2]gogeof: https://github.com/gogeof
[3]Xiaobin.Liu: https://github.com/lxbwolf
[4]GCTT: https://github.com/studygolang/GCTT
[5]Go 中文網(wǎng): https://studygolang.com/
推薦閱讀
