2017-02-02 3 views
2

пытаются получить лучшее понимание этого: https://pymotw.com/2/multiprocessing/basics.htmlпитон многопроцессорных разных файлов

У меня есть 20+ «большие» журналы (каждое бревно примерно 6-9gigs но сжатый т.е. log1 ... 20.gz)

Мой скрипт python будет проходить через каждый журнал в назначенном каталоге и выработать итоговое значение для определенного столбца, а затем записать в файл и перейти к следующему файлу журнала. Я заметил, что когда я это сделал, я не использовал все ядра в системе. Таким образом, чтобы использовать больше ядер я сделал это

script1.py < folder 1 (contains logs 1-5 , write to report1-5.txt) 
script2.py < folder 2 (contains logs 6-10, write to report6-10.txt) 
script3.py < folder 3 (contains logs 11-15, write to report11-15.txt) 
script4.py < folder 4 (contains logs 16-20, write to report16-20.txt 

В идеале я бы просто script1.py < папки 1 (содержит все 20 журналов и пишет Report.txt)

Если включить «импорт мультипроцессирование «смогу ли я добиться того, чтобы 1 сценарий и многие работники проходили через разные файлы или много рабочих пытались работать с файлом log.gz для продажи? или я пропускаю информацию

ответ

2

Если я правильно понял ваш вопрос, вы ищете хороший способ ускорить обработку сжатых gzip лог-файлов.

Первый вопрос, на который вам нужно ответить, - это то, что ваш текущий процесс связан с ЦП или связана с IO. Это означает: когда вы в настоящее время запускаете script.py < folder 1 и смотрите его, например. с top, ваш процесс идет до 100% использования ЦП? Если да, то ваш процесс связан с ЦП (т. Е. ЦП является узким местом). Если это так, то вам поможет параллелизация в python. Если это не так (и это, безусловно, не так, как диск будет вашим узким местом, если файлы gz не лежат на разных дисках), то вам не нужно беспокоиться, так как вы не получите больше скорости.

Для распараллеливания вы в основном есть два варианта:

  1. питона: вам нужно использовать многопроцессорность, как вы предложили. Но для того, чтобы это, вы не можете просто импортировать мультипроцессирование, вы должны явно сказать, что каждый процесс должен сделать, например:

    from multiprocessing import Pool, Queue 
    
    def crunch_file(queue): 
        while not queue.empty() 
         filename = queue.get() 
         # gunzip file, do processing, write to reportx-y.txt 
    
    if __name__ == '__main__': 
        queue = Queue() 
        # put all filenames into queue with os.walk() and queue.put(filename) 
        pool = Pool(None, crunch_file, (queue,)) 
        pool.close() # signal that we won't submit any more tasks to pool 
        pool.join() # wait until all processes are done 
    

    Несколько вещей, чтобы отметить:

    • с помощью Pool(None, ...) питона будет фигурировать из числа ядер у вас есть и начать один процесс для каждого ядра процессора
    • с помощью Queue поможет вам никогда не иметь холостой ход процессов: если один из процессов осуществляется с помощью его файла, он будет принимать следующий в очереди
  2. bash: Поскольку вы, похоже, не знакомы с многопроцессорной обработкой питонов, а разные процессы не должны говорить друг с другом, намного легче начать, например. 4 python-программы параллельно, например.

    script.py < folder 1 & 
    script.py < folder 2 & 
    script.py < folder 3 & 
    script.py < folder 4 & 
    
+0

Это было отличное описание. Итак ... 1 и 2 в основном делают то же самое, что и распространение нагрузки? – chowpay

+0

@chowpay в основном они делают то же самое, да. С python у вас больше контроля, так как вы можете равномерно распределять нагрузку на ядра. Кроме того, вы можете воспользоваться всеми ядрами, даже если количество папок меньше количества ядер. Тем не менее, решение bash намного проще реализовать и может быть достаточно для вашего варианта использования. – hansaplast

0

Да вы на правильном пути. Я все время делаю подобное. Работает намного быстрее. Сначала вам нужно разархивировать файл. Glob файлы, чтобы забрать и передать их в список имен файлов в pool.map (fn, lst) Я должен добавить SSD, что я использую, и если вы используете обычный HD, который вращается, возможно, не будет улучшения скорости совершенно печально.SSD отлично подходит для этого. Не используйте Queue, закрывайте, присоединяйте, все ненужно, поэтому просто используйте map()

+0

Я не могу быстро распаковать 100 файлов log.gz размером 6-7gigs. Я прочитал их строки за строкой в ​​память в форме gz перед обработкой и выводя их также в формате gz – chowpay