2016-04-08 103 views
3

recent SO question中,我概述了在處理大量每個包含數百萬條記錄的csv文件時遇到的OOM條件。事件隊列中的節流事件

我越看到這個問題,越是在Node.js上閱讀,越是確信OOM不會因爲內存泄漏而發生,但是因爲我沒有限制數據輸入到系統中。

該代碼只是盲目地吸收所有數據,爲每一行創建一個回調事件。事件不斷增加到主事件循環中,最終變得非常大以至於耗盡所有可用內存。

什麼是Node處理這種情況的慣用模式?我是否應該將csv文件讀取到某種阻塞隊列中,一旦阻塞隊列,阻塞文件讀取器解析更多數據?處理大型數據集有沒有好的例子?


更新:要快於它可以處理不同的輸出把這個更簡單,節點可以處理輸入和鬆弛被存儲在存儲器中(排隊作爲事件隊列事件)。因爲有很多鬆弛,內存最終會耗盡。所以問題是:將輸入限制爲輸出速率的慣用方法是什麼?

+0

如果我的答案沒有提供足夠的細節,那麼共享一些示例代碼可以幫助我做一個更具體的示例。 – Paul

+0

代碼鏈接在第一句話中。謝謝。 –

+0

我的錯誤是,我習慣於在被問到的問題中看到相關的代碼。我會盡快更新我的答案。 – Paul

回答

1

最好的辦法是把事情設置爲流,並依靠內置的背壓語義來實現。 Streams Handbook作爲一個非常好的概述。

與unix類似,節點流模塊的主要組合操作符稱爲.pipe(),並且您可以獲得一個免費的背壓機制來爲緩慢的使用者節流寫入。

更新

我沒有用比以前的終端輸入其他任何內容readline模塊,但閱讀文檔,它看起來像它接受一個輸入流和輸出流。如果您將數據庫寫入器構建爲可寫入數據流,則應該可以讓readline在內部爲您提供管道。

+0

啊!事情已經開始爲我點擊了......我使用流來讀取數據,但我沒有使用管道。 –

+1

最終,我將從readline切換到[node-csv](https://github.com/wdavidw/node-csv),它實現了流。另一方面,我發現至少有一些庫([mongoose-object-stream](https://tonicdev.com/npm/mongoose-object-stream)和[mongoose-write-stream](https) ://www.npmjs.com/package/mongoose-write-stream)),它在Mongoose之上實現可寫的流。感謝您讓我朝着正確的方向前進。 –