場(chǎng)景我有一批平鋪數(shù)據(jù)放在txt文件,其量大概在10W條,接下來(lái)我們希望將這10W條記錄進(jìn)行切割獲取,并且將單條數(shù)據(jù)分析校驗(yàn),然后插入到DB中。前提是我們使用的是HTTP文件上傳方式來(lái)導(dǎo)入數(shù)據(jù)?,F(xiàn)在的問(wèn)題是:如果用戶直接上傳,然后我們一條條數(shù)據(jù)讀取、校驗(yàn)并將其插入數(shù)據(jù)庫(kù),這個(gè)過(guò)程將會(huì)耗費(fèi)非常長(zhǎng)的時(shí)間(大概在1小時(shí)以上),而這么長(zhǎng)的時(shí)間等待會(huì)導(dǎo)致apache、nginx或者瀏覽器端(一般情況下是60分鐘)的超時(shí)。那么我們應(yīng)該如何的解決這個(gè)問(wèn)題呢? 分批次處理分批次解決辦法意思就是,將文件的大數(shù)據(jù)轉(zhuǎn)化為多個(gè)塊,例如10W條分成20塊,每塊處理5K數(shù)據(jù),這樣每次處理的時(shí)間將會(huì)縮短,用戶也可以實(shí)時(shí)的看到交互過(guò)程而不至于超時(shí)無(wú)法知曉結(jié)果。 1、使用本地讀取文件數(shù)據(jù)方法,將數(shù)據(jù)分批次傳遞到服務(wù)端,服務(wù)端接手?jǐn)?shù)據(jù)后處理返回,客戶端獲取到執(zhí)行結(jié)果后批次的展示給用戶結(jié)果。 2、Socket解決辦法,服務(wù)端和客戶端使用socket機(jī)制,客戶端一次性將文件傳遞到服務(wù)端,服務(wù)端接受數(shù)據(jù)后批次處理,每次處理完成一部分將會(huì)通過(guò)socket通知前端部分處理結(jié)果完成。 這種方法用戶必須在前端等待查看執(zhí)行結(jié)果,如果用戶關(guān)閉則會(huì)導(dǎo)致只上傳或者處理了部分?jǐn)?shù)據(jù),當(dāng)然這種用戶可以直接的看到運(yùn)行過(guò)程。 異步過(guò)程處理異步的解決過(guò)程主要是,一次性上傳到服務(wù)端,服務(wù)端接受數(shù)據(jù)后不立即執(zhí)行,而是放在一個(gè)DB的隊(duì)列中或者異步執(zhí)行隊(duì)列中,當(dāng)執(zhí)行完成后通過(guò)在DB中回調(diào)寫(xiě)入執(zhí)行過(guò)程,而客戶端則只需要在用戶主動(dòng)查詢時(shí),才會(huì)去查詢結(jié)果。 1、通過(guò)使用異步函數(shù),例如Node.js中的一些異步文件讀取操作來(lái)異步執(zhí)行,而同步則直接提示用戶文件數(shù)據(jù)正在上傳中。 2、通過(guò)隊(duì)列任務(wù)模式,如果這種數(shù)據(jù)上傳比較頻繁,那么建議是使用隊(duì)列任務(wù)模式,當(dāng)前端有上傳時(shí),就將任務(wù)放在任務(wù)隊(duì)列中,而再需要開(kāi)啟一個(gè)進(jìn)程專(zhuān)門(mén)的去負(fù)責(zé)任務(wù)的讀取以及解析執(zhí)行過(guò)程,執(zhí)行完成后再寫(xiě)入執(zhí)行結(jié)果。 這種方法用戶無(wú)法實(shí)時(shí)的查看結(jié)果,服務(wù)端只能通過(guò)文件的大小來(lái)預(yù)估執(zhí)行結(jié)束時(shí)間,這種方案的最大優(yōu)點(diǎn)就是保證文件可以完成的上傳和數(shù)據(jù)導(dǎo)入完成,缺點(diǎn)就是用戶無(wú)法準(zhǔn)確的知道執(zhí)行結(jié)束的時(shí)間點(diǎn)。 歡迎提供更好的解決辦法。 |
|