- PVSM.RU - https://www.pvsm.ru -
Всё началось с простой задачи: скачать по 100-мегабитной сети большой объём данных с помощью rsync. Возник вопрос, можно ли ускорить этот процесс. Утилита top показала, что на сервере-источнике шифрование занимает не более 10 процентов процессора, поэтому было решено что можно попробовать сжатие данных. Тогда мне было неясно, будет ли хватать производительности процессора для упаковки данных с необходимой скоростью, поэтому была выставлена самая маленькая степень сжатия, а именно использовался флаг --compress-level=1 для rsync. Оказалось, что загрузка процессора не превысила 65%, то есть производительности процессора хватило, при этом скорость скачивания данных несколько повысилась.
После этого возник вопрос о анализе применимости распространённых программ сжатия
для передачи данных по сети.
Первой задачей было собрать исходные данные для анализа. Выбор подопытных пал на распространённые в *nix мире программы сжатия. Все программы были установлены из стандартных репозиториев Ubuntu 11.10:
Программа Версия Тестируемые ключи По умолчанию lzop 1.03 1, 3, 7-9 3 gzip 1.3.12 1-9 6 bzip2 1.0.5 1-9 9 xz 5.0.0 0-9 7
Официальные сайты: lzop [1], gzip [2], bzip2 [3], xz [4].
bzip2 основан на алгоритме BWT [5] (англ. [6]), остальные же основаны на алгоритме LZ77 [7] (англ. [8]) и его модификациях.
Для lzop степени сжатия 2-6 являются идентичными, и поэтому не тестировались.
Тестовая система представляла собой ноутбук на Intel P8600 (Core 2 Duo, 2.4 GHz)
c 4 GB оперативной памяти, работающий под Ubuntu 11.10 64-bit.
Для тестирования применялись несколько разных наборов данных:
Несжатый объём: 127641600 байт = 122 МиБ [10]
Несжатый объём: 392028160 байт = 374 МиБ
Несжатый объём: 151367680 байт = 145 МиБ
Ну и более «классические» наборы:
Несжатый объём: 56657920 байт = 55 МиБ
Несжатый объём: 490035200 байт = 468 МиБ
Методика измерений была таковой: для каждой программы, степени сжатия, и исходного файла производилось сжатие в промежуточный файл с замером времени, затем запоминался размер сжатого файла,
затем производилась распаковка с замером времени. Распакованный файл на всякий случай сравнивался с исходным, затем промежуточный и распакованный файлы удалялись.
Для исключения влияния дискового ввода-вывода на результаты все файлы размещались в /run/shm (это общая память в linux, с которой можно работать, как с файловой системой).
Каждое измерение проводилось 3 раза. В качестве результата использовалось минимальное время из трёх.
Результаты приведены на графиках в координатах время упаковки — размер упакованного файла.
Рис. 1: График результатов для исходных кодов компилятора gcc:
![Сжатие данных / [Из песочницы] Сравнение программ сжатия в применении к передаче больших объёмов данных Сжатие данных / [Из песочницы] Сравнение программ сжатия в применении к передаче больших объёмов данных](http://www.pvsm.ru/images/6e258394c2bbbed97e726a74d4c3ab8b.png)
Рис. 2: График результатов для бинарного дистрибутива ParaView:
![Сжатие данных / [Из песочницы] Сравнение программ сжатия в применении к передаче больших объёмов данных Сжатие данных / [Из песочницы] Сравнение программ сжатия в применении к передаче больших объёмов данных](http://www.pvsm.ru/images/3aaa2f59d9da05bdecc68dce09250f01.png)
Рис. 3: График результатов для набора бинарных научных данных:
![Сжатие данных / [Из песочницы] Сравнение программ сжатия в применении к передаче больших объёмов данных Сжатие данных / [Из песочницы] Сравнение программ сжатия в применении к передаче больших объёмов данных](http://www.pvsm.ru/images/86ed4f4a5b66d0f677f7ba5a84a3f08a.png)
Также графики для: заголовков ядра [12] и исходного кода OpenFoam [13].
При степени сжатия по умолчанию lzop же, как и ожидалось, очень быстр. Степень сжатия -1 не даёт большого выигрыша по времени, давая больший размер файла.
Также стоит заметить, что разные ключи меняют степень сжатия и время работы bzip2 совсем незначительно.
Малые степени сжатия вплотную приближаются к gzip -9 по времени работы, обеспечивая лучшую степень сжатия.
Вообще же можно видеть что xz даёт довольно большой выбор соотношений степени сжатия и времени.
У bzip2 распаковка происходит медленнее, причём время распаковки увеличивается с повышением степени сжатия.
Рассмотрим такой сценарий передачи данных по сети: сначала данные упаковываются, затем передаются по сети, затем распаковываются. Тогда общее время будет:
t = t_c + s/bw + t_d
где t_c — время упаковки, s — размер упакованного файла в байтах,bw — пропускная способность сети в байтах/с, t_d — время распаковки.
Это уравнение определяет кривую постоянного времени на приведённых графиках, наклон которой определяется пропускной способность сети. Чтобы определить оптимальный алгоритм упаковки для данной пропускной способности, нужно найти самую нижнюю прямую с нужным наклоном, проходящую через какую-либо точки графика.
То есть оптимальные методы сжатия и скорости их «переключения» определяются прямыми, касательными к нашему множеству точек на графике. Остаётся только определить их.
То что мы ищем, это не что иное, как выпуклая оболочка [14] (англ. convex hull). Для построения выпуклой оболочки множества точек разработаны многочисленные алгоритмы [15]. Мной использовалась реализация на питоне отсюда [16].
После построения выпуклой оболочки, точки, ей принадлежащие, будут нашими оптимальными алгоритмами, а наклоны рёбер, их соединяющих, будут граничными пропускными способностями.
Таким образом получаем такие оптимальные алгоритмы для наших файлов:
![Сжатие данных / [Из песочницы] Сравнение программ сжатия в применении к передаче больших объёмов данных Сжатие данных / [Из песочницы] Сравнение программ сжатия в применении к передаче больших объёмов данных](http://www.pvsm.ru/images/a4c095ccade5938f999df23ff3b2ff01.png)
Теперь рассмотри другой сценарий: данные упаковываются, и сразу по мере упаковки отправляются по сети, а на приёмной стороне сразу распаковываются.
Тогда полное время передачи данных определяется не суммой, а максимумом из трёх времён: упаковки, распаковки, и передачи по сети.
Кривая постоянного времени для выбранной пропускной способности сети тогда будет выглядеть как угол с вершиной на прямой
t = s / bw
и двумя лучами, идущими вниз и влево от вершины.
Алгоритм, позволяющий найти все оптимальные способы сжатия и граничные пропускные способности, в этом случае гораздо проще. Вначале мы сортируем точки по времени, затем выбираем первую оптимальную точку (это будет точка без сжатия, с нулевым временем. Отсутствие сжатия оптимально для сети бесконечной пропускной способности.) Теперь перебираем точки в порядке возрастания времени сжатия. Если размер файла меньше размера файла предыдущего оптимального метода, то текущий метод становится новым оптимальным. При этом граничная пропускная способность будет равна размеру файла предыдущего метода поделённому на время сжатия нового метода.
Вот результаты для такого сценария использования:
![Сжатие данных / [Из песочницы] Сравнение программ сжатия в применении к передаче больших объёмов данных Сжатие данных / [Из песочницы] Сравнение программ сжатия в применении к передаче больших объёмов данных](http://www.pvsm.ru/images/54a9c44aa59492e786a02f8c3fc2f81b.png)
Известно, что один из самых быстрых каналов доставки больших объёмов информации на небольшие дистанции — велокурьер с жёсткими дисками.
Посчитаем. Пусть расстояние составляет 10 километров. Велокурьер сделает рейс туда-обратно за час-полтора (в нормальном темпе и с учётом всяких задержек, погрузки и разгрузки) Пусть это даст 6 рейсов за 8-часовой рабочий день. Пусть он возьмёт с собой 10 дисков по 1 ТБ. Тогда за день он перевезёт 60 ТБ. Это эквивалентно круглосуточной работе линии с пропускной способностью 60 ТБ / (24 * 3600) с = 662 МиБ/с что примерно составляет 5 Гбит/c. Неплохо.
По полученным результатам видно, что если пытаться сжимать данные для такой линии связи на одном ядре, аналогичном ядрам моего ноутбука, то оптимальным оказывается отсутствие сжатия.
А если же рассмотреть случай с переносом данных на одном USB 2.0 жёстком диске, то это аналогично сценарию 2 со скоростью в примерно 30 МБ/сек, если мы учитываем затраты времени только на передающей стороне.
Глядя на наш график, получаем: lzop -3 оптимален для переноса данных на внешнем USB жёстком диске для наших тестовых наборов данных.
Если же мы сначала сжимаем, а затем копируем на внешний диск, то это сценарий 1, и тогда оптимальным по общим затратам времени для исходных кодов и бинарного дистрибутива оказывается lzop -1, а для плохо сжимаемых бинарных данных — отсутствие сжатия.
Автор: encyclopedist
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/szhatie/2643
Ссылки в тексте:
[1] lzop: http://www.lzop.org
[2] gzip: http://www.gzip.org
[3] bzip2: http://www.bzip.org/
[4] xz: http://tukaani.org/xz/
[5] BWT: http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%91%D0%B0%D1%80%D1%80%D0%BE%D1%83%D0%B7%D0%B0_%E2%80%94_%D0%A3%D0%B8%D0%BB%D0%B5%D1%80%D0%B0
[6] англ.: http://en.wikipedia.org/wiki/BWT
[7] LZ77: http://ru.wikipedia.org/wiki/LZ77
[8] англ.: http://en.wikipedia.org/wiki/LZ77
[9] openfoam.com: http://www.openfoam.com
[10] МиБ: http://ru.wikipedia.org/wiki/%D0%94%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B5_%D0%BF%D1%80%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B8
[11] paraview.org: http://www.paraview.org
[12] заголовков ядра: http://habrastorage.org/storage2/e43/01f/702/e4301f702ca4b3d1bfde63f4e39c04e8.png
[13] исходного кода OpenFoam: http://habrastorage.org/storage2/dfc/0c8/c17/dfc0c8c17e570a0888bf0911995a8e45.png
[14] выпуклая оболочка: http://ru.wikipedia.org/wiki/%D0%92%D1%8B%D0%BF%D1%83%D0%BA%D0%BB%D0%B0%D1%8F_%D0%BE%D0%B1%D0%BE%D0%BB%D0%BE%D1%87%D0%BA%D0%B0
[15] алгоритмы: http://en.wikipedia.org/wiki/Convex_hull_algorithms
[16] отсюда: http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain
[17] snappy: http://code.google.com/p/snappy
[18] snzip: https://github.com/kubo/snzip
[19] http://stephane.lesimple.fr/wiki/blog/lzop_vs_compress_vs_gzip_vs_bzip2_vs_lzma_vs_lzma2-xz_benchmark_reloaded: http://stephane.lesimple.fr/wiki/blog/lzop_vs_compress_vs_gzip_vs_bzip2_vs_lzma_vs_lzma2-xz_benchmark_reloaded
[20] http://www.linuxjournal.com/node/8051/: http://www.linuxjournal.com/node/8051/
Нажмите здесь для печати.