2012-10-21 27 views
0

我編寫了一個程序來關閉一些約220萬條記錄的數據。對於每個記錄,它將通過一系列20次計算,總共需要大約0.01秒。爲了讓它運行得更快,我使用Python多進程,將我的數據通常分成6個塊,並與主進程並行地運行它們,將有效負載分發到進程並協調執行。順便說一句,作爲計算的結果,該程序將向數據庫寫出大約2200萬條記錄。運行了很長時間並消耗大量內存足跡後奇怪的Python性能下降

我在MacBookPro i7 2.2GHz上運行,運行在Python 3.2.2上的8GB RAM。數據在本地MySQL服務器上。

程序啓動良好 - 以可預測的方式運行,CPU平均使用率爲60-70%,而我的Macbook Pro只是像烤箱一樣升溫。然後,運行約5個小時後CPU速度降低,每個內核的CPU利用率平均降低20%。我當時所做的一些觀察是: - 每個Python進程消耗大約480 MB真實RAM和大約850 MB虛擬RAM。總共有6個這些繁重的進程 - OSX消耗的總虛擬內存(如Activity Monitor所示)大約爲300GB

我懷疑性能下降是由於內存消耗巨大並且可能存在高頁面交換。

我該如何更好地診斷這些症狀? 長時間運行大內存對象的Python有沒有問題?真的,我不認爲運行6小時對於今天的技術來說是沉重的,但是我只有大約半年的Python經驗,所以......我知道什麼?!

謝謝!

+0

我不知道你是否能夠使用存儲過程對數據庫本身進行這些計算,並消除中間層和網絡延遲。爲了進行一些計算,220萬條記錄中有很多字節來回移動。數據庫可以做到嗎? – duffymo

+0

我已經考慮過這個選項,但沒有。我選擇Python的原因是編程速度快。這20個系列的計算只是一個開始,可能會很快增長。將它們作爲存儲過程來解決現在可能會解決我的性能問題,但它會降低我在實現附加計算插件邏輯方面的速度。我也試圖對2,200萬條記錄的db回寫進行評論,但這並沒有多大幫助。 – Thomas

+0

不管你決定走哪條路,聽起來就像你必須這樣做,並以大塊的形式提交。 2.2M記錄的回滾段太大。 – duffymo

回答

0

我猜測性能下降是因爲它交換內存和內存的東西。我不認爲問題是程序運行了多長時間 - Python使用垃圾收集器,所以它沒有內存泄漏。

那麼,這不是完全是真的。垃圾收集器將確保它刪除任何無法訪問的東西。 (換句話說,它不會刪除你可以想象到的東西。)但是,它不夠聰明,無法檢測數據結構何時不會用於其他程序;您可能需要澄清,將所有對它的引用設置爲None,以使其正常工作。

  1. 你可以發佈代碼?

  2. 這是一個程序,你需要一個給定的記錄不止一次?您加載記錄的順序是否對您的程序很重要?

  3. 如果python進程只分配了幾千兆字節的內存,那麼爲什麼你有300 GB的已用內存?

+0

對不起,代碼會太長,我會解釋一下設計。 該程序使用了大量的生成器函數,因爲下一個值計算總是需要一些較早的值/狀態。從讀取db記錄到20次計算,每一個都是通過封裝在各自對象中的生成器函數執行的。目前我有大約1000(不同的數據流)×20(計算)對象。每個數據流都是獨特的產品,我通過按時間順序進行迭代來對它們進行迴歸和分析。 – Thomas

+0

至於你的第3頁。我不知道,這就是爲什麼我把這個問題標記爲Python和OSX :) 我對Python很新,是否有任何指導如何解決內存和性能問題? – Thomas

+0

我想我發現了這個問題。在Python進程中,220萬條記錄的查詢實際佔用了2.6 GB的內存。顯然,pymysql驅動程序不支持(或者我錯誤地使用它)通過打開的遊標連接從數據庫中檢索數據。我懷疑它會在返回第一條記錄之前緩存完整的結果集。 – Thomas

相關問題