У меня есть несколько файлов gz с общим размером около 120 ГБ. Я хочу разархивировать (gzip) эти файлы в тот же каталог и удалить существующий gz файл. В настоящее время мы делаем это вручную, и у вас больше времени на распаковку с помощью gzip -d <filename>
.
Есть ли способ, которым я могу разархивировать эти файлы параллельно, создав python script или любую другую технику. В настоящее время эти файлы находятся на машине Linux.
Вы можете сделать это очень легко с многопроцессорными пулами:
import gzip
import multiprocessing
import shutil
filenames = [
'a.gz',
'b.gz',
'c.gz',
...
]
def uncompress(path):
with gzip.open(path, 'rb') as src, open(path.rstrip('.gz'), 'wb') as dest:
shutil.copyfileobj(src, dest)
with multiprocessing.Pool() as pool:
for _ in pool.imap_unordered(uncompress, filenames, chunksize=1):
pass
Этот код породит несколько процессов, и каждый процесс будет извлекать один файл за раз.
Здесь я выбрал chunksize=1
, чтобы избежать остановок процессов, если некоторые файлы больше среднего.
Большая часть времени настенных часов, затрачиваемых на распаковку файла с помощью gunzip
или gzip -d
, будет выполняться из операций ввода-вывода (чтение и запись на диск). Это может быть даже больше, чем время, затрачиваемое на декомпрессию данных. Вы можете воспользоваться этим, имея несколько заданий gzip, идущих в фоновом режиме. Поскольку некоторые операции блокируются при вводе-выводе, другое задание может выполняться без ожидания в очереди.
Вы можете ускорить распаковку всего набора файлов с помощью нескольких процессов gunzip
, работающих в фоновом режиме. Каждый из них обслуживает определенный набор файлов.
Вы можете взломать что-то легкое в BASH. Разделите список файлов на отдельные команды и используйте &
, чтобы запустить его как фоновое задание. Затем wait
для каждого завершения каждого задания.
Я бы рекомендовал, чтобы у вас было от 2 до 2 * N заданий, идущих одновременно. Где N - количество ядер или логических процессоров на вашем компьютере. Поэкспериментируйте, чтобы получить правильный номер.
Вы можете легко взломать что-то в BASH.
#!/bin/bash
argarray=( "$@" )
len=${#argarray[@]}
#declare 4 empty array sets
set1=()
set2=()
set3=()
set4=()
# enumerate over each argument passed to the script
# and round robin add it to one of the above arrays
i=0
while [ $i -lt $len ]
do
if [ $i -lt $len ]; then
set1+=( "${argarray[$i]}" )
((i++))
fi
if [ $i -lt $len ]; then
set2+=( "${argarray[$i]}" )
((i++))
fi
if [ $i -lt $len ]; then
set3+=( "${argarray[$i]}" )
((i++))
fi
if [ $i -lt $len ]; then
set4+=( "${argarray[$i]}" )
((i++))
fi
done
# for each array, start a background job
gzip -d ${set1[@]} &
gzip -d ${set2[@]} &
gzip -d ${set3[@]} &
gzip -d ${set4[@]} &
# wait for all jobs to finish
wait
В приведенном выше примере я выбрал 4 файла на одно задание и начал два отдельных задания. Вы можете легко расширить script, чтобы иметь больше заданий, больше файлов для каждого процесса и взять имена файлов в качестве параметров командной строки.
gzip -d
. Я посмотрю, смогу ли я что-нибудь проработать позже ...