Большая часть данных хранится в удобных для чтения форматах файлов, что упрощает взаимодействие приложений. Хотя существуют широко используемые форматы для сжатия изображений, видео и звука, большая часть других данных хранится в виде текста, например JSON, CSV или других подобных текстовых форматов.
Такие форматы, как Parquet, Avro и ORC, имеют дополнительное сжатие, поэтому обычно эти форматы уже сжаты при сохранении. Видео и изображения также обычно сжимаются с помощью специализированных алгоритмов, которые обеспечивают лучшее сжатие, чем общие форматы.
Однако для пользовательских данных предпочтительнее хранить данные в несложном формате, который не требует этапа распаковки для доступа. Мы хотим предложить возможность сжимать эти данные перед сохранением на дисках.
Сжатие для MinIO было разработано для обеспечения прозрачного сжатия без ущерба для общей производительности системы.
MinIO использует метод сжатия на основе Snappy под названием S2. Он совместим с контентом Snappy, но имеет два расширения формата . Прежде всего, он допускает блоки размером больше 64 КБ, разрешенные для потоков Snappy. Это значительно улучшает сжатие. Во-вторых, он добавляет «смещения повторения», что обеспечивает улучшение сжатия главным образом данных, сгенерированных машиной, таких как файлы журналов, JSON и CSV. Это также позволяет эффективно кодировать совпадения длиной более 64 байт, что является проблемой для Snappy.
S2 также позволяет одновременно сжимать несколько блоков, когда входные данные быстрее, чем может поглотить одно ядро. Это важно для обеспечения оперативности реагирования на отдельные запросы. По сути, ограничением при наличии 16+ ядер будет скорость памяти.
Некоторые поставщики устройств обещают или даже предполагают заданную степень сжатия при расчете стоимости за ТБ. При сжатии не существует гарантированного соотношения выше 1:1. Разные типы данных дают разную степень сжатия, и, по нашему мнению, не существует эффективного способа обеспечить среднюю степень сжатия. Коэффициенты сжатия никогда не следует оценивать в вакууме — их всегда следует сопоставлять со скоростью сжатия, поскольку практическое сжатие — это компромисс между этими двумя факторами.
Давайте сравним один тип данных, чтобы увидеть различия. Мы сравниваем реализации этих алгоритмов на Go на платформе AMD64, использующей до 16 ядер.
Прежде всего, горизонтальная ось представляет собой усеченную степень сжатия, уменьшение достигается за счет несжатого размера. Правее лучше. Для справки: включен однопоточный gzip уровня 5.
Компрессор | Скорость МБ/с | Размер | Снижение | Декабрь МБ/с |
---|---|---|---|---|
S2 по умолчанию | 15148 | 1043196283 | 83,37% | 2378 |
S2 лучше | 11551 | 954430842 | 84,79% | 2300 |
S2 Лучший | 680 | 832855431 | 86,73% | 2572 |
LZ4 Самый быстрый | 5645 | 1280414160 | 79,59% | 2680 |
LZ4 Лучший | 1552 г. | 1091826460 | 82,60% | 2694 |
шустрый | 946 | 1525176492 | 75,69% | 1828 г. |
Gzip L5 | 206 | 942726276 | 84,97% | 557 |
Скорость декомпрессии использует одно ядро, хотя S2 предлагает параллельную декомпрессию.
По этим данным Snappy отстает примерно на 10% от эталонного Gzip. Поскольку мы имеем дело с процентами сокращения, это также означает, что Snappy занимает примерно в 1,6 раза больше места, чем данные, сжатые Gzip. При этом игнорируется тот факт, что Snappy распаковывает примерно в 4 раза быстрее, чем Gzip.
LZ4 обычно считается превосходящим Snappy. Реализация LZ4, позволяющая осуществлять сжатие на нескольких ядрах, также проясняет этот момент. Но базовое сжатие лучше. LZ4 Best, также иногда называемый LZ4-HC, предлагает сжатие, близкое к gzip, но даже несмотря на то, что распаковка быстрая, сжатие не происходит на интерактивных скоростях.
S2 предлагает три уровня сжатия; S2 Default является самым быстрым из возможных и может рассматриваться как прямой конкурент Snappy в отношении использования одного ядра. С этим типом данных он работает лучше, чем любой уровень LZ4, со значительно более высокой пропускной способностью. Этот режим используется MinIO для платформ, где реализация сборки недоступна.
S2 Better позволяет использовать немного ресурсов ЦП для более высокого сжатия. Здесь сжатие конкурирует с Gzip, но скорость распаковки намного выше. Этот режим используется MinIO на платформах, где доступна сборка — на данный момент AMD64.
S2 Best — лучшее сжатие, которое S2 может выполнить с текущим форматом. Это можно использовать в ситуациях, когда скорость/ресурсы сжатия не являются наиболее важными, но быстрая распаковка по-прежнему необходима. В настоящее время MinIO не использует этот режим, но может реализовать его как вариант жизненного цикла для объектов, которые давно не менялись.
Для сравнения приведем несколько сравнений других типов данных:
Важной особенностью современного сжатия является то, что оно хорошо работает с предварительно сжатыми данными. Традиционно предварительно сжатые данные были проблемой для алгоритмов сжатия. Часто компрессоры неоправданно замедляли работу при работе с несжимаемыми данными.
Поэтому многие люди инстинктивно знают, что повторное сжатие уже сжатых данных — это плохо. Однако многие современные реализации теперь могут в разумной степени быстро пропускать несжимаемые разделы.
Для приведенных выше компрессоров это скорости несжимаемых данных объемом 2 ГБ (2 147 483 647 байт):
Компрессор | Скорость МБ/с | Размер | Снижение |
---|---|---|---|
S2 по умолчанию | 13045 | 2147487753 | 0,00% |
S2 лучше | 9894 | 2147487753 | 0,00% |
S2 Лучший | 3938 | 2147487753 | 0,00% |
LZ4 Быстрый | 6400 | 2147485710 | 0,00% |
LZ4 Лучший | 12488 | 2147745841 | -0,01% |
шустрый | 6564 | 2147745801 | -0,01% |
Gzip (Go) L5 | 63 | 2148139030 | -0,03% |
Gzip (альт) L5 | 5535 | 2147647512 | -0,01% |
Здесь мы также включили gzip из стандартной библиотеки Go как представитель этого «плохого» поведения. Альтернативная реализация gzip не показывает этой проблемы. Во всех остальных случаях контент обрабатывается достаточно быстро и проходит проверку.
Это означает, что MinIO может хорошо обрабатывать предварительно сжатые данные.
Типичным недостатком сжатия является потеря возможности пропуска внутри файла. Решением этой проблемы является независимое сжатие блоков и сохранение индекса, который сопоставляет ряд несжатых смещений со сжатыми смещениями, с которых может начаться распаковка.
Сжатие независимых блоков немного уменьшит сжатие, но в меньшей степени для блоков большего размера. Snappy/S2 изначально сжимает потоки как независимые блоки.
Для MinIO это актуально, поскольку запросы S3 GetObject могут включать дополнительные диапазоны для извлечения. Это позволяет извлекать части объектов, и мы хотим, чтобы это было максимально эффективно.
Начиная с RELEASE.2022-07-13T23-29-44Z , мы теперь генерируем индекс для каждой загруженной части файла размером более 8 МБ. Затем индекс прикрепляется к метаданным. Это позволяет нам эффективно пропустить вперед и декодировать только ту часть объекта, которая необходима для возврата запрошенных данных.
Индекс обычно составляет 16 байт + примерно 3 байта на МБ данных. Это позволяет MinIO обрабатывать любой байт из сжатого файла с той же скоростью, что и при извлечении первого байта.
По умолчанию MinIO требуется дополнительный параметр для сжатия данных для шифрования на диске. Это сделано для того, чтобы вы осознавали последствия этого.
При сжатии данных вы получаете два числа; несжатый и сжатый размер. Без сжатия любой, кто получит ваши данные, сможет увидеть только один из них — несжатый размер.
Хотя это по-прежнему не дает вам доступа к каким-либо данным в сжатом файле, оно дает некоторые подсказки относительно данных. Он может сообщить вам некоторые типы данных, которыми он не может быть. Если вы видите файл, сжатый на 50%, крайне маловероятно, что он будет содержать видео, сжатое в формате MP4.
Точно так же файл, сжатый всего до нескольких байт, скорее всего, будет содержать очень простую повторяющуюся последовательность. Невозможно сказать, какова последовательность, но это уменьшает возможности. MinIO из RELEASE.2022-07-13T23-29-44Z дополняет сжатый вывод до кратного 256 байтам. Это дополнение нигде не записывается. Мы не считаем это полным решением проблемы, но это значительно снижает полезность утечки информации о размере для злоумышленников.
Это основная причина, по которой MinIO не возвращает клиентам никакой информации о размерах сжатых файлов. Поэтому любая информация об этом потребует доступа к внутреннему хранилищу или внутренней сети.
Благодаря этой информации вы теперь обладаете достаточными знаниями, чтобы определить, считаете ли вы безопасным включение сжатия и шифрования.
Атаки в стиле CRIME невозможны на MinIO, поскольку мы не разрешаем изменять или добавлять какие-либо сжатые потоки. Мы также не выполняем дедупликацию/сжатие версий объектов, поскольку это приведет к утечке слишком большого количества информации о файлах.
По умолчанию сжатие на диске в MinIO отключено. Сжатие на диске можно включить или отключить в любое время. Чтобы включить сжатие на диске, используйте mc admin config set myminio compression enable=on
.
Это включит сжатие для заданного количества расширений и типов MIME. По умолчанию они будут включать в себя:
Расширения | Типы пантомимы |
---|---|
.txt.log.csv.json.tar.xml.bin | текст/*приложение/jsonapplication/xmlbinary/октет-поток |
Вы можете проверить текущие настройки с помощью mc admin config get myminio compression
.
Вы можете изменить этот список в любое время, изменив:
mc admin config set myminio compression \ extensions=.txt,.log,.csv,.json,.tar,.xml,.bin \ mime_types=text/*,application/json,application/xml,binary/octet-stream
По умолчанию MinIO принудительно исключает расширения обычно несжимаемых данных, таких как gzip, аудио, видео и файлы изображений.
Можно включить сжатие для всех объектов, кроме исключенных, установив пустой список расширений и типы mime:
mc admin config set myminio compression enable=on extensions= mime_types=
Последний параметр allow_encryption=on
, который позволяет сжимать даже те объекты, которые будут зашифрованы. Устанавливайте это значение только тогда, когда вы прочитали раздел выше и поняли последствия.
MinIO предлагает лучшую в своем классе схему сжатия, которая обеспечивает полностью прозрачное сжатие данных на диске. Во многих сценариях это может привести к снижению затрат на хранение, просто включив сжатие.
Производительность GET и PUT во всех случаях должна оставаться примерно одинаковой при включенном сжатии. Фактически, в ситуациях, когда производительность ограничена скоростью чтения с диска, сжатие может обеспечить дополнительную производительность, поскольку необходимо читать меньше данных.
Мы будем продолжать добавлять новые функции. В настоящее время мы оцениваем варианты конфигурации на уровне корзины/префикса, а также сжатие через жизненный цикл, которое будет сжимать файлы по мере достижения ими определенного возраста.
Если вас интересуют эти функции, скачайте MinIO и опробуйте его сами. Если у вас есть какие-либо вопросы или вы хотите рассказать нам о замечательных приложениях, которые вы создаете с помощью MinIO, напишите нам по адресу [email protected] , присоединитесь к сообществу Slack , следите за нашим блогом или подпишитесь на нашу рассылку новостей.
Также опубликовано здесь .