簡體   English   中英

Python中處理大文件的最快方法

[英]Fastest way to process large files in Python

我們在需要處理的各種目錄中有大約 500GB 的圖像。 每張圖片的大小約為 4MB,我們有一個 python 腳本來一次處理一張圖片(它讀取元數據並將其存儲在數據庫中)。 每個目錄可能需要 1-4 小時來處理,具體取決於大小。

我們在 GNU/Linux 操作系統上擁有一個 2.2Ghz 四核處理器和 16GB 內存。 當前腳本僅使用一個處理器。 利用其他內核和 RAM 來更快地處理圖像的最佳方法是什么? 啟動多個 Python 進程來運行腳本會利用其他內核嗎?

另一種選擇是使用 Gearman 或 Beanstalk 之類的工具將工作外包給其他機器。 我看過多處理庫,但不確定如何使用它。

啟動多個 Python 進程來運行腳本會利用其他內核嗎?

是的,如果任務受 CPU 限制,它會。 這可能是最簡單的選擇。 但是,不要為每個文件或每個目錄生成一個進程; 考慮使用諸如parallel(1)之類的工具,並讓它產生類似每個內核兩個進程的東西。

另一種選擇是使用 Gearman 或 Beanstalk 之類的工具將工作外包給其他機器。

那可能行得通。 另外,看看ZeroMQ 的 Python 綁定,它使分布式處理變得非常容易。

我看過多處理庫,但不確定如何使用它。

定義一個 function,比如process ,它讀取單個目錄中的圖像,連接到數據庫並存儲元數據。 讓它返回一個 boolean 表示成功或失敗。 directories成為要處理的目錄列表。 然后

import multiprocessing
pool = multiprocessing.Pool(multiprocessing.cpu_count())
success = all(pool.imap_unordered(process, directories))

將並行處理所有目錄。 如果需要,您還可以在文件級別進行並行處理; 這需要更多的修補。

請注意,這將在第一次失敗時停止; 使其具有容錯性需要做更多的工作。

啟動獨立的 Python 進程是理想的。 進程之間不會發生鎖爭用,操作系統會安排它們並發運行。

您可能想嘗試看看理想的實例數是多少——它可能多於或少於核心數。 磁盤和高速緩存 memory 將發生爭用,但另一方面,您可能會在另一個等待 I/O 的同時讓一個進程運行。

您可以使用多處理池來創建進程以提高性能。 比方說,您有一個 function handle_file 用於處理圖像。 如果你使用迭代,它最多只能使用你的核心的 100%。 為了利用多個核心,Pool multiprocessing 會為您創建子流程,並將您的任務分配給它們。 這是一個例子:

import os
import multiprocessing

def handle_file(path):
    print 'Do something to handle file ...', path

def run_multiprocess():
    tasks = []

    for filename in os.listdir('.'):
        tasks.append(filename)
        print 'Create task', filename

    pool = multiprocessing.Pool(8)
    result = all(list(pool.imap_unordered(handle_file, tasks)))
    print 'Finished, result=', result

def run_one_process():
    for filename in os.listdir('.'):
        handle_file(filename)

if __name__ == '__main__':
    run_one_process
    run_multiprocess()

run_one_process 是處理數據的單核方式,簡單但速度慢。 另一方面,run_multiprocess 會創建 8 個工作進程,並向它們分發任務。 如果你有 8 個核心,它會快大約 8 倍。 我建議您將工作人員數量設置為您的核心數的兩倍或恰好是您的核心數。 您可以嘗試一下,看看哪種配置更快。

對於高級分布式計算,您可以像 larsmans 提到的那樣使用ZeroMQ 一開始很難理解。 但是一旦你理解了它,你就可以設計一個非常高效的分布式系統來處理你的數據。 對於您的情況,我認為一個 REQ 和多個 REP 就足夠了。

在此處輸入圖像描述

希望這會有所幫助。

請參閱此問題答案

如果應用程序可以處理輸入數據范圍,那么您可以啟動 4 個具有不同輸入數據范圍的應用程序實例進行處理,並在完成后合並結果。

盡管該問題看起來是特定於 Windows 的,但它適用於所有操作系統上的單線程程序。

警告:請注意,此進程將受 I/O 限制,並且由於對 I/O 資源的爭用,對硬盤驅動器的並發訪問過多實際上會導致進程作為一個組執行得比順序處理

如果您正在讀取大量文件並將元數據保存到數據庫中,則您的程序不需要更多內核。

您的進程很可能是 IO 綁定而不是 CPU 綁定。 將 twisted 與適當的延遲和回調一起使用可能會勝過任何試圖征用 4 個核心的解決方案。

我認為在這種情況下使用Celery是完全合理的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM