Можно ли распараллелить распаковку bz2?

Я использую модуль pythons bz2 для генерации (и сжатия) большого файла jsonl (сжатого bzip2 17 ГБ).

Однако, когда я позже пытаюсь распаковать его с помощью pbzip2, кажется, что для распаковки используется только одно ядро ЦП, что довольно медленно.

Когда я сжимаю его с помощью pbzip2, он может использовать несколько ядер при распаковке. Есть ли способ сжатия внутри python в pbzip2-совместимом формате?

import bz2,sys
from Queue import Empty
#...
compressor = bz2.BZ2Compressor(9)
f = open(path, 'a')

    try:
        while 1:
            m = queue.get(True, 1*60)
            f.write(compressor.compress(m+"\n"))
    except Empty, e:
        pass
    except Exception as e:
        traceback.print_exc()
    finally:
        sys.stderr.write("flushing")
        f.write(compressor.flush())
        f.close()

1 ответ

Решение

pbzip2 Поток является не чем иным, как объединением нескольких bzip2 потоки.

Пример использования оболочки:

bzip2 < /usr/share/dict/words > words_x_1.bz2
cat words_x_1.bz2{,,,,,,,,,} > words_x_10.bz2
time bzip2 -d < words_x_10.bz2 > /dev/null
time pbzip2 -d < words_x_10.bz2 > /dev/null

Я никогда не использовал питона bz2 модуля, но должно быть легко закрыть / открыть поток в 'a'Режим ppend, так много байтов, чтобы получить тот же результат. Обратите внимание, что если BZ2File создается из существующего файлового объекта, закрывая BZ2File не будет закрывать основной поток (что вы и хотите здесь).

Я не измерял, сколько байтов является оптимальным для разбиения на фрагменты, но я бы предположил, что каждые 1-20 мегабайт - это определенно должно быть больше, чем размер блока bzip2 (900 КБ).

Также обратите внимание, что если вы записываете сжатые и несжатые смещения каждого блока, вы можете сделать довольно эффективный произвольный доступ. Вот как dictzip программа работает, хотя это основано на gzip,

Если вам абсолютно необходимо использовать pbzip2 при декомпрессии это вам не поможет, но альтернатива lbzip2 может выполнять многоядерную декомпрессию "нормальной" .bz2 файлы, такие как созданные Python BZ2File или традиционный bzip2команда. Это позволяет избежать ограниченияpbzip2 вы описываете, где он может достичь параллельной распаковки, только если файл также сжат с использованием pbzip2. См. https://lbzip2.org/.

В качестве бонуса тесты предлагают lbzip2 существенно быстрее, чем pbzip2, как при декомпрессии (на 30%), так и при сжатии (на 40%), при этом достигается несколько лучшая степень сжатия. Кроме того, его пиковое использование ОЗУ составляет менее 50% от ОЗУ, используемогоpbzip2. См. https://vbtechsupport.com/1614/.

Другие вопросы по тегам