Найти в Дзене
Василий Волченко

Сжимать или не сжимать - вот в чём вопрос

Оглавление

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

Практически любому очевидно, что свободного места на диске много не бывает (кроме небольшого периода времени после покупки нового диска) - там и хлам, созданный операционной системой, и семейный фото- и видеоархив (хотя он и сжат), и документы со времён школы или ВУЗа, и старые игры, и т.д. и т.п. Поэтому неудивительно, что уже через несколько месяцев свободного места на диске практически не остаётся. И нужно либо усиленно чистить временные файлы, либо жертвовать своим хламом (а жалко! И чаще всего случается так, что на следующий день после удаления, казалось бы, полного хлама именно этого файла будет так недоставать, что чуть ли не во всякие средства восстановления полезешь, но шансов мало). Либо... Либо использовать сжатие данных, и сэкономить этим себе процентов 30-40, а то и больше места... Особенно на SSD. Или лучше не стоит?

О чём мы вообще говорим

(продвинутые пользователи могут пропустить этот раздел)

Вопрос сжатия информации возник уже очень давно. Первый аспект заключается в том, что данные на диске расположены не так, чтобы они не занимали лишнего места, а так, чтобы их быстрее было прочитать. То есть, место, занимаемое на диске одним файлом, должно исчисляться целым числом кластеров. Например, если размер кластера равен 1 килобайт (бывает и меньше, и больше, но эта цифра вполне реальная), то файл размером 1025 байт будет занимать 2 килобайта. Ну, здесь, конечно, не повезло - так не повезло, но в реальности небольших файлов, дающих полупустые кластеры, встречается очень много. Можете проверить даже сейчас (если у Вас, конечно, не включено сжатие): выберите какую-нибудь папку (в Windows, например, Program Files, а ещё лучше - ProgramData, но она скрытая, так что кому-то придётся повозиться чуть дольше) и посмотрите свойства. И места на диске она будет занимать заметно больше, чем просто суммарный объём файлов. И вот справиться с этим может помочь использование простейших архивов типа tar (изначально предназначались для хранения данных на магнитной ленте). Размер архива будет соответствовать суммарному размеру файлов, их названий и очень небольшой служебной информации, и это окажется заметно меньше того, что эти данные бы занимали в виде файлов в файловой системе (ФС). Но это касается именно архивов, т.е., информации, которая часто использоваться не будет, или же передаётся с машины на машину, потому как сэкономив на полупустых кластерах, мы теряем в возможности доступа к некоему конкретному файлу. Ведь даже чтобы прочитать этот файл, надо "прокрутить" tar-архив до него, а если потребуется что-то изменить - то практически наверняка придётся перепаковать всё.

Но выгода от архива tar не столь уж и велика, надо идти дальше. Давайте возьмём большой текст в однобайтовой кодировке (например, русский текст в кодировке cp1251, обычный файл txt в Windows - отбросим UTF-8 и прочие юникоды, у которых каждая русская буква будет занимать 2 байта). Скажем, это будет обычный текст какого-нибудь романа или повести страниц эдак на 1000. Поскольку на странице умещается чуть меньше двух килобайт, эта книга будет занимать где-то чуть меньше двух мегабайт (ну, пусть будет полтора). Сейчас кажется, что немного, но раньше мы бы её не "втиснули" на дискету. А если таких книг - вся мировая библиотека? И всё это мы "втискиваем" на SSD ноутбука? Места-то жалко! Что делать? Давайте посчитаем. Каждый символ текста в кодировке cp1251 может быть представлен либо буквой (русской или латинской), либо цифрой, либо специальными символами (знаки пунктуации, математических действий, пробелы и т.д), к тому же, ещё с нулевого по тридцать первый символ - вообще служебные (например, седьмой символ раньше включал "пищалку", но он никуда не делся). Большая часть текста укладывается где-то в 64 возможных символа (большие и маленькие русские буквы, причём, скорее всего, без "ё", а твёрдые знаки встречаются лишь в единичных количествах, точка, запятая и пробел; заглавную букву "Ы" тем более будет отыскать крайне сложно, только если пойдёт "капс"). 64 байта кодируются 6 байтами (2^6=64), то есть, вместо 8 бит мы могли бы расходовать на каждый символ по 6. Получается экономия 25 %, очень неплохо для начала. Пойдём дальше: некоторые буквы встречаются чаще, а другие - днём с огнём не найдёшь. Кстати, на этом принципе построена азбука Морзе. Почему бы не использовать такой подход для сжатия данных? И, наконец, некоторые слова и словосочетания в тексте встречаются чаще других, если их зашифровать каким-то кодом, мы ещё сэкономим.

Таким образом, получается, что текстовые данные можно сжать примерно в 2 раза, иногда чуть больше (английский текст сжимается по такому же принципу, вот бессмысленное сочетание русских и латинских букв будет сжать куда сложнее). А текстовых данных у нас - великое множество, это не только библиотека и текстовые документы, но и практически все настройки, скрипты, да и исходные коды программ. То есть, на этих данных мы экономим не меньше половины от того, что они занимают.

Идём дальше. Рисунки - сжимаются хорошо, но специальные программы делают это куда лучше, настолько, что сейчас несжатые рисунки (скажем, bmp и pnm) найти сложно, практически все рисунки сохранены в сжатых jpeg и png.

Исполняемые файлы и библиотеки - сжимаются средне, всё зависит от конкретного формата, наличия отладочной информации и оптимизации. Для сжатия исполняемых файлов тоже есть свои, более эффективные, методы (например, UPX), но сейчас они почти забыты, может, и незаслуженно.

Вот что бесполезно сжимать - так это уже сжатые файлы. На них мы только потеряем место за счёт служебной информации в попытке сжатия (поэтому иногда хорошие архиваторы и дисковые компрессоры, обнаружив сжатые данные, специально записывали их несжатыми). Впрочем, эффект от полупустых кластеров никуда не девается.

Итак, сжимая данные, мы можем экономить заметное количество места. Какие у нас варианты?

1. Запаковать ряд файлов и каталогов в tar-архив, а потом сжать его. Получится архив .tar.gz, .tar.xz и т.п. Неплохо для хранения и пересылки, но когда потребуется извлечь из него хотя бы один файл, надо будет разархивировать сначала архиватором, потом tar. Неудобно и ресурсозатратно. Т.е., хорошо при передаче данных или при хранении того, что пока близко не понадобится. Другим недостатком является большая чувствительность к повреждениям: иногда при повреждении даже одного байта такого архива удастся восстановить только данные, находящиеся до этого байта (без особых методик).

картинка из галереи Яндекса
картинка из галереи Яндекса

2. Специальные архивы, имеющие определённое индексирование (например, .zip). В него сразу пакуется несколько файлов и каталогов, но структура архива отображается очень быстро и быстро же можно извлечь любой из файлов. Вот если надо его заменить, может потребоваться перепаковать архив (и то есть варианты). Если вдруг архив окажется повреждён, то с большой вероятностью повреждение затронет только один-два файла, остальные можно будет извлечь. Обратная сторона медали - несколько больший размер архива (особенно при обилии в нём мелких файлов) по сравнению с .tar.gz или .tar.xz даже при использовании аналогичного по эффективности алгоритма. Сюда же войдут и архивы с избыточной информацией для восстановления.

картинка из галереи Яндекса
картинка из галереи Яндекса

3. Сжатие данных на уровне файловой системы. Этот подход позволяет нам забыть об отдельной процедуре архивации-деархивации, файлы сжимаются и восстанавливаются "на лету", экономится место, но... Конечно, эффективность сжатия куда меньше, чем в архивах .tar.xz (даже при использовании эффективных алгоритмов - нам ведь надо иметь моментальный доступ к файлам не только на чтение, но и на запись). Но, тем не менее, этот пост именно о таком сжатии.

Сжатие на уровне ФС: история и современность на ПК

Пользователи ПК впервые массово столкнулись со сжатием в операционной системе MS DOS 6.0 (до этого были сторонние средства типа Stacker, кстати, в итоге засудившие Microsoft, но далеко не все с этим вообще сталкивались). Там был внедрён компрессор DoubleSpace (далее, в версии 6.22, чтобы обойти последствия суда - DriveSpace). Этот компрессор подключал сжатый диск, хранящийся на основном разделе FAT, зачастую подменяя название исходного диска, а также "подделывал" количество свободного места, удваивая его (коэффициент можно было настроить). То есть, если объём диска 100 Мб, заполнено 60 Мб (уже сжатых данных), то отображалось 80 Мб свободного места. И это не совсем честно: если мы вдруг захотим записать архив размером 45 Мб, система разрешит это сделать, но "застрянет" на тех самых честных 40 свободных мегабайтах (архивы практически несжимаемы!). С другой стороны, если мы поставим коэффициент 1, оставив честные 40 Мб, то при попытке скопировать туда текстовый файл (скажем, tar-архив) размером 50 Мб, мы получим системную ошибку даже до начала копирования (ведь не влезет же!), тогда как при наличии запаса мы скопируем этот файл без проблем.

Далее этот DoubleSpace/DriveSpace перекочевал в Windows 95/98, получив дополнительные алгоритмы HiPack и UltraPack. Помнится, я сжимал последним алгоритмом небольшой диск на древнем компьютере со свежеустановленной 95-й, несмотря явную надпись: "Не рекомендуется для 486-х процессоров". Но меня-то это не касалось, у меня был 386-й (правда, DX) :) И да, тогда дисковый компрессор изрядно тормозил. Впрочем, что не тормозило на таком процессоре? Главное - оно всё запускалось, а для работы можно было использовать и старое ПО от Win3.1, которое, как я заметил, запускалось в разы быстрее. Впрочем, это было давно и "экстремально".

И всё бы отлично, только появившаяся с Windows 95 OSR2 файловая система Fat32 не поддерживалась дисковым компрессором от слова "совсем". Видимо, это был маркетинговый ход: размеры новых жёстких дисков увеличились, сжатие перестало быть столь критичным, но потребовалась более ёмкая файловая система. Так что либо сиди на старой ФС с маленьким жёстким диском, либо покупай сразу большой диск, где места на всё хватит. Или...?

Или надо было переходить на Windows NT. В её файловую систему NTFS уже было встроено сжатие файлов и каталогов (правда, там уже были не сжатые диски, а сжимались отдельные файлы, так что огромное количество мелких файлов тоже оказывались расточительны для свободного места). Другой недостаток - нельзя было сжимать критически важные файлы (ни при каких обстоятельствах нельзя было сжимать загрузчик и всё, что с ним связано).

Дальше (Windows 2000, XP, Vista, 7, 8) этот механизм совершенствовался, насколько я понимаю, в "семёрке" уже можно без проблем сжимать все данные на диске, но принципиально нового подхода не появилось. Начиная с "десятки", подход несколько улучшился, ввели решим CompactOS, включающий ещё дополнительные меры по сжатию, но общий подход остался.

В Linux со сжатием не было так уж хорошо. Да, во многих местах конфигурационные файлы можно "скармливать" в сжатом виде (.gz), но весь объём файлов сразу уж сжатым не окажется. Основная файловая система Linux (ext2, ext3, ext4) не поддерживает сжатия, хотя следы того, что могла бы - есть. И существовал проект ext2compr, позволяющий после патча ядра сжимать данные... Но это нестандартно, т.е., носитель, отформатированный в такой вот патченной системе, который случайно прогнать через сжатие (установку атрибута "compressed"), будет малочитаем в стандартной системе.

Но неужели решения нет? В таком, казалось бы, системном вопросе Linux уступает Windows? А ведь именно возможности гибкой настройки системы любым возможным способом - сильная сторона Linux. На самом деле, есть. Первые бросающиеся в глаза решения - загрузка из сжатых файловых систем, доступных только для чтения (и это позволяет уложить большую систему на небольшой компакт-диск)... Но это всё не то. Хотя есть и более привычный вариант. Некоторые не столь распространённые файловые системы поддерживают сжатие. И в их числе встроенная в ядро систем btrfs (вообще, она много чего поддерживает, но и сжатие тоже). Причём она по умолчанию сжимает все записываемые файлы, если при монтировании указать опцию compress. Ничуть не хуже Windows 10. И без проблем можно выбрать алгоритм сжатия.

Собственно, сжимать или не сжимать? За и против.

Итак, что говорили и иногда говорят противники сжатия?

1. Сжатие тормозит работу ПК и требует дополнительных ресурсов.

Теоретически - да. Компьютер должен сперва загрузить файл, потом распаковать его, и только потом - запустить или дать отредактировать. Если файл изменился, то надо его запаковать (а в классических алгоритмах архивации упаковка либо в разы медленнее распаковки, либо алгоритм не очень эффективен) и только потом записать на диск.

Практически - всегда нужно искать узкое место. Да, если выбрать самый сложный алгоритм и запустить это всё на древнем "атоме", то, может быть, мы упрёмся в алгоритм сжатия. Да, если памяти едва хватает, чтобы крутилась операционная система, а мы ещё всё время пакуем что-то - это может быть критично (хотя для этого случая есть и механизмы сжатия данных в памяти). Но в остальных случаях "узкое место" - чтение с диска/запись на диск (особенно для реального диска, а не SSD). И тут сжатие может дать не только прирост места на диске, но и прирост скорости: если сжатый файл можно прочитать в память практически в два раза быстрее, и система ускорится. Да, конечно, этот эффект не столь существенен на SSD, но там каждый гигабайт ценится куда больше, так что эффект от высвобожденного места будет выше.

2. Жёсткие диски и так дешёвые, зачем зря экономить? (аргумент около 2000-го года). Если что, можно докупить ещё один диск.

Первую часть можно сразу отмести как несостоятельную, тем более, последние чуть ли не 10 лет объём HDD почти не растёт, лучше становятся лишь SSD, включая NVMe, но и для них 1-2 Тб - практически предел за реальную стоимость.

Вторая часть - я бы с этим подходом был как можно более аккуратным, особенно если речь идёт о начинающем пользователе или о том, у кого "кривые руки". Лишний жёсткий диск - источник лишних проблем (если, конечно, это не RAID). Даже если это - SSD, логически получаются дополнительные разделы, и возможны сюрпризы - что-то вдруг не оттуда загрузится. Да, сейчас большинство систем ищет нужные разделы по UUID, но не все и не всегда. Но это как раз не так страшно. А вот "зоопарк" HDD, особенно трёхдюймовых... Это заметная нагрузка на питание, и часто бывали случаи, что со слабеньким БП, да ещё не с самой маломощной видеокартой, один из двух HDD отваливался в самый неподходящий момент. Нет, настроить систему изначально для двух и даже трёх HDD - не невозможно, но докупить HDD "с бухты-барахты" - не всегда самый лучший вариант.

3. Всего должно быть в меру, а архивы лучше хранить в интернете. А хлам вообще надо чистить.

Вот этот аргумент резонный, порядок - важное дело. В том числе и в данных. Ещё бы объяснить это Microsoft'у, который любит "разбухшую" систему, и даже dism не всегда и не всё чистит. Что же до облачных хранилищ... В нынешней политической ситуации 100 %-й гарантии они не дают, важное лучше иметь где-то у себя.

4. Сжатые данные ненадёжны и непереносимы.

Если брать патчи уровня e2compr, то да. В противном случае - не особо. Да, могут быть отдельные ограничения, но в большинстве случаев - нет. Что же до надёжности, то шансов что-то прочитать из "битого кластера" и без того маловато (если он уже совсем не читается).

Теперь "плюсы" идеи сжатия ФС:

1. Лишнего места не бывает. Зачем изощряться, если можно сэкономить 20-30 %? Особенно в операционной системе.

2. Современные системы оснащены SSD, объём которых крайне ограничен (особенно на нетбуках). А часто туда хочется "запихнуть" не только Windows, но и Linux. И пусть на HDD ещё полно места, SSD приходится ужимать.

3. Если работа с HDD - узкое место, то почему бы не уменьшить объём считываемых данных, сжав их?

Итоговый вывод - если хотите - сжимайте данные! Причём чем раньше Вы установите режим сжатия, тем меньше потом придётся пережимать. Хотя сжатие - это не абсолютное решение, позволяющее забыть об экономии места.