Эта статья является продолжением руководства по форматам файлов в Spark и Hadoop, которое послужит хорошей отправной точкой, если вы еще ничего не знаете о форматах файлов big data.
Что из себя представляет «столбчатый формат файла»?
Этот термин часто используется, но я не уверен, что всем до конца ясно, что он означает на практике.
Определение из учебника гласит, что столбчатые (колоночные, многоколоночные, columnar) форматы файлов хранят данные по столбцам, а не по строкам. CSV, TSV, JSON и Avro — традиционные строковые форматы файлов. Файл Parquet и ORC — это столбчатые форматы файлов.
Давайте проиллюстрируем различия между этими двумя концепциями, используя примеры некоторых данных и простой наглядный столбчатый формат файла, который я только что придумал.
Вот схема данных набора «люди». Она довольно проста:
{
id: Integer,
first_name: String,
last_name: String,
age: Integer,
cool: Boolean,
favorite_fruit: Array[String]
}
Данные в строковом формате строки
Мы могли бы представить этот набор данных в нескольких форматах, например, вот неструктурированный JSON-файл:
{"id": 1, "first_name": "Matthew", "last_name": "Rathbone", "age": 19, "cool": true, "favorite_fruit": ["bananas", "apples"]}
{"id": 2, "first_name": "Joe", "last_name": "Bloggs", "age": 102, "cool": true, "favorite_fruit": null}
Вот те же данные во всеми любимом формате CSV
1, Matthew, Rathbone, 19, True, ['bananas', 'apples']
2, Joe, Bloggs, 102, True,
В обоих этих форматах, каждая строчка файла содержит полную строку данных. Именно так люди представляют себе данные: аккуратные строки выстроены в линию, которые легко сканировать, легко редактировать в Excel, легко читать в терминале или текстовом редакторе.
Данные в столбчатом формате
В целях демонстрации я собираюсь ввести новый столбчатый (псевдо) формат файла. Назовем его CCSV (Столбчатый CSV).
Каждая строка нашего CCSV-файла имеет следующее содержимое:
Field Name/Field Type/Number of Characters:[data in csv format]
Вот те же данные представленные в CCSV:
ID/INT/3:1,2
FIRST_NAME/STRING/11:Matthew,Joe
LAST_NAME/STRING/15:Rathbone,Bloggs
AGE/INT/6:19,102
COOL/BOOL/3:1,1
FAVORITE_FRUIT/ARRAY[STRING]/19:[bananas,apples],[]
Обратите внимание, что все имена, возраст и любимые фрукты хранятся рядом друг с другом, а не вместе с другими данными из той же записи. Чтобы каждый раздел столбца не становился слишком большим, CCSV будет повторять этот паттерн каждые 1000 записей. Таким образом, файл из 10 000 записей будет содержать 10 разделов сгруппированных столбцовых данных.
Могут ли люди легко читать CCSV-файлы? В принципе да, но вам будет сложно составить целостное представление о данных, если вы откроете их в Excel. Однако CCSV имеет несколько полезных свойств, которые делают его предпочтительнее для компьютеров, и сейчас я о них расскажу.
Преимущества столбчатых форматов
Оптимизация чтения
Представим, что я хочу выполнить SQL-запрос к этим данным, например:
SELECT COUNT(1) from people where last_name = "Rathbone"
С обычным CSV-файлом SQL-движку пришлось бы сканировать каждую строку, анализировать каждый столбец, извлекать значение last_name
, а затем пересчитать все значения Rathbone
, которые он увидит.
В CCSV SQL-движок может смело пропустить первые два поля и просто просканировать третью строку, которая содержит все доступные значения фамилий.
Почему это хорошо? Теперь SQL-движок обрабатывает только около 1/6 данных, т.е. CCSV только что обеспечил (теоретическое и совершенно необоснованное) увеличение производительности на 600% по сравнению с обычными CSV-файлами.
Представьте себе такой же выигрыш на наборе данных петабайтного масштаба. Нетрудно оценить оптимизацию столбчатых форматов файлов, позволяющую сэкономить массу вычислительной мощности (и денег) по сравнению с обычными наборами данных в JSON. Это основная ценность столбчатых форматов файлов.
Конечно, на самом деле CCSV необходимо проделать еще немалый путь, чтобы стать жизнеспособным файловым форматом, но это немного уводит нас от темы, поэтому я не буду здесь на этом заостряться.
Улучшения сжатия
Совместное хранение однотипных данных также сулит преимущества для кодеков сжатия. Многие кодеки сжатия (включая GZIP и Snappy) имеют более высокий коэффициент сжатия при сжатии последовательностей схожих данных. Сохраняя записи столбец за столбцом, во многих случаях каждый раздел данных столбца будет содержать похожие значения, что делает крайне пригодным для сжатия. Фактически, каждый столбец можно сжать независимо от других для дальнейшей оптимизации.
Недостатки столбчатых форматов
Самый большой недостаток столбчатых форматов состоит в том, что восстановление полной записи происходит медленнее и требует чтения сегментов из каждой строки, один за другим. Именно по этой причине столбчатые форматы файлов изначально подходят для рабочих процессов аналитики, а не для рабочих процессов в стиле Map/Reduce, которые по умолчанию работают с целыми строками данных за раз.
Для реальных столбчатых форматов файлов (например, Parquet) этот недостаток сводится к минимуму с помощью некоторых хитрых приемов, таких как разбиение файла на «группы строк» и создание обширных метаданных, хотя для особенно широких наборов данных (например, 200+ столбцов) влияние на скорость может быть значительным.
Другой недостаток состоит в том, что они требуют больше ресурсов ЦП и оперативной памяти для записи, поскольку средство записи файлов должно собрать целую кучу метаданных и реорганизовать строки, прежде чем он сможет записать файл.
Попутно замечу, что я почти всегда рекомендую использовать столбчатый формат файла, если это возможно, чтобы иметь возможность быстро заглянуть в файл и собрать некоторые простые показатели.
Реальные столбчатые форматы файлов
Теперь, когда вы знаете, чего ожидать, давайте быстро рассмотрим реальный формат файла — Parquet. Есть гораздо более подробные руководства по parquet, и я рекомендую вам прочитать официальную документацию parquet, в частности, чтобы понять, как все это работает.
Вот диаграмма из документации Parquet, показывающая структуру Parquet-файла. Она немного ошеломляет, но я думаю, что ключевым выводом является важность организации данных и метаданных. Я приведу здесь только общую схему, ведь документация являются исчерпывающим и в то же время достаточно доступными источником, если хотя бы в какой-то степени понимаете, что происходит (а вы, вероятно, к этому моменту уже понимаете!).
Выводы
Для Spark, Spark SQL, Hive, Impala и других подобных технологий столбчатое хранение данных может дать 100-кратное, а иногда и 1000-кратное повышение производительности, особенно для разреженных запросов к очень широким наборам данных. Несмотря на свою сложность, файлы оптимизированы для компьютеров, и хотя это затрудняет их чтение человеком, они действительно кажутся большим шагом вперед по сравнению с такими форматами, как JSON или Avro.
Ого, вы дочитали аж до сюда?
Спасибо, что дочитали до самого конца! Полагаю, вы глубоко увлечены работой с big data, если добрались до конца. Если вам когда-нибудь понадобится поделиться идеями или получить совет по поводу того, над чем вы работаете, не стесняйтесь отправить мне электронное письмо — matthew (at) rathbonelabs (dot com). Я люблю говорить о big data с умными людьми.
Всех, кому интересен курс «Data Engineer» приглашаем посетить бесплатный демо-урок курса на тему «ML в Spark». На уроке участники узнают об особенностях ML в Spark, рассмотрят процесс разработки моделей и научатся переводить обученные модели в production.