我有一個包含大約5.2M行的大型CSV文件。我想解析這個文件並將數據插入到數據庫中。我爲此使用apache駱駝。使用Apache Camel插入大型CSV文件時的GC問題
路線是相當容易的(簡化本示例)
from("file:work/customer/").id("customerDataRoute")
.split(body().tokenize("\n")).streaming()
.parallelProcessing()
.unmarshal(bindyCustomer)
.split(body())
.process(new CustomerProcessor())
.to("sql:INSERT INTO CUSTOMER_DATA(`FIELD1`,`FIELD2`) VALUES(#,#)");
bindyCustomer是CSV文件和 CustomerProcessor一個BindyCsvDataFormat是返回Bindy客戶對象的數據作爲對象的陣列的處理器爲SQL插入。實際的對象有39個字段(以上簡化)。
這對第一個800.000到1.000.000行都可以,但是它會停下來。
我用JVisualVM和Visual GC插件監視了駱駝實例,我可以看到老一代填滿了,當它達到最大值時,整個系統停止運行,但不會崩潰。 在這一點上,老一代已經滿員了,伊甸園的空間幾乎已經滿了,兩個倖存者空間都是空的(因爲它不能將任何東西移動到我猜想的老一代)。
那麼這裏有什麼問題?這看起來像是Camel SQL組件中的內存泄漏。 數據主要存儲在ConcurrentHashMap對象中。
當我拿出SQL組件時,老一代幾乎沒有填充。
我正在使用駱駝2.15.1將嘗試使用2.17.1看看是否解決了這個問題。
更新:我試過駱駝2.17.1(同樣的問題),我試圖用java.sql.Statement.executeUPdate在Java中插入插入。有了這個選項,我設法插入了大約2.6 M行,但隨後它也停止了。有趣的是我沒有收到內存錯誤。它只是停下來。
感謝您的提示。我試過了,但並沒有解決問題。 .unmarchal(bindyCustomer)只返回一個元素的數組,所以在這種情況下流應該不會有太大的區別。你能想到其他可能會出錯的東西嗎?我將嘗試在Java中執行插入以查看是否解決了問題。 – Ben
嗯,我有一些粗略的猜測。你能夠添加id標籤到你的路線,然後打開你的JConsole來確認所有線程是「掛起」的嗎? –
這條路線已經作爲一個ID(customerDataRoute)或者你指的是別的嗎? – Ben