Некоторое время назад мы решили, что следует расширить спектр задач, реализуемых в рамках проектов, связанных с информационной безопасностью, включив в наш фокус сами события, регистрируемые средствами защиты. Ниже речь пойдёт об одной из составляющих нового для нас направления, связанного с технологиями BigData.
Исходная задача, которая стояла перед нашей командой, это анализ данных журналов регистрации и учёта с различных сетевых устройств и устройств систем информационной безопасности. Подобное оборудование генерирует события каждую секунду и в среднем могут выдавать более 1000 строк за 1 минуту своей работы. При этом генерируемые данные не подвергаются изменениям, т.е. данные только дополняются (append), но не изменяются (update).
Таким образом, у нас есть поток событий, подходящий под определение больших данных, которые не изменяются с течением времени, а их объем только увеличивается. Возник вопрос: как наилучшим образом эту информацию хранить с тем, чтобы с ней можно было бы работать в дальнейшем?
Все данные, которые так или иначе поступают и обрабатываются можно разбить по типам:
- Текстовые данные (text data) – журналы событий от серверов, web приложений, CSV файлы или неструктурированные данные такие, как электронные письма;
- Структурированные текстовые данные (structured text data) – данные представленные в виде XML или JSON и им подобных;
- Бинарные данные (binary data) – данные представленные в бинарном виде, например, изображения.
- Платформа для работы с большими данными на базе Hadoop поддерживает несколько форматов хранения данных и их сжатия. Каждый из форматов имеет как свои преимущества, так и недостатки.
Данные на основе файловых структур
К подобным форматам относят: SequenceFiles, MapFiles, SetFiles, ArrayFiles и BloomMapFiles. Данные форматы оптимизированы для работы с MapReduce, в том числе через запуск с помощью компонент Pig и Hive.
Наиболее часто используемым из данных форматов является SequenceFiles. В нём данные хранятся в виде пар бинарный ключ – значение и в свою очередь они могут иметь три разных вида:
- Баз сжатия (uncompressed) – данные представлены без сжатия;
- Сжатие по записям (record compression) – сжатие проводится по каждой записи по мере того, как они добавляются в файл;
- Сжатие по блокам (block-comression) – сжатие выполняется по мере того, как размер данных достигает установленного размера блока. В данном случае блок данных относится исключительно к формату SequenceFiles и не имеет ничего общего с блоками данных в HDFS.
Каждый SequenceFile содержит заголовок, в котором хранятся метаданные о файле, такие как: используемый кодек сжатия, ключ и значение, sync маркер, пользовательские метаданные.
За пределами экосистемы Hadoop формат SequenceFile поддерживается в Java. Наиболее часто данный формат применяют как контейнер для маленьких файлов, но применительно к HDFS системе подобный вариант крайне ресурсоёмок, поскольку возникает существенный расход оперативной памяти ввиду хранения метаданных по каждому из файлов. Другим негативным эффектом является высокий расход вычислительных ресурсов процессора, поскольку каждый файл требует отдельной задачи, а малый размер файлов ведёт к увеличению их общего количества. Пример SequenceFile с использованием блокового сжатия приведён ниже (Рис. 44).
Рис. 44
Форматы сериализации
Сериализация представляет собой процесс преобразования структур данных в поток байт для последующего хранения или передачи по сети. Обратный данному процесс именуется – десериализацией. В Hadoop применяются форматы сериализации такие как: Thrift, Protocol Buffers и Avro. Последний наиболее распространён ввиду того, что создавался для работы в Hadoop.
Avro - это не зависящая от языка программирования система сериализации данных, в которой данные описываются через схему (чаще всего JSON, но может применяться в т.ч. Avro IDL). Avro хранит схему в заголовке каждого файла, что позволяет использовать их в любой момент и оперировать для этого тем языком программирования, который необходим (он может быть отличен от того языка при помощи которого создавали файл). Файлы Avro могут быть легко сжаты и разделены, а содержимое схемы может быть дополнено или изменено в зависимости от потребностей. Схема хранится как часть метаданных файла в заголовке файла.
Заголовок файла содержит метаданные и уникальный sync маркер (аналогично SequenceFire данный маркер используется для разделения блоков в файле, позволяя разделять файлы на части). Помимо заголовка, Avro файл содержит непосредственно блоки данных, которые могут быть сжаты (поддерживаются алгоритмы Snappy и Deflate).
Пример Avro файла приведён на рис. 45.
Avro поддерживает следующие типы данных:
- примитивные - null, boolean, int (знаковое целое 32 бита), long (знаковое целое 64 бита), float, double, string (unicode строка), bytes (последовательность байт), fixed (последовательность байт с длиной, заданной в схеме);
- сложные составные - union (сумма), recod (произведение), enum (перечисление), array (массив/ список), map (ассоциативный массив);
- логические - decimal (число с фиксированной запятой), date (дата), time-millis (время с миллисекундной точностью), time-micros (время с микросекундной точностью), timestamp-millis (дата-время с миллисекундной точностью), timestamp-micros (дата-время с микросекундной точностью), uuid (universally unique identifier, универсальный уникальный идентификатор).
- Наличие схемы данных (что обеспечивает необходимую гибкость при работе и изменении);
- Построчное хранение (позволяет эффективно проводить чтение данных);
- Отсутствие внутреннего индекса (в отличии от MapFile).
- Низкая скорость при избирательном чтении данных (когда требуется получить только фрагмент строки);
- Большой расход дискового пространства при сравнении с колоночными форматами.
Рис. 45
Колоночные форматы
Hadoop поддерживает несколько колоночно-ориентированных форматов данных – RCFile, Hive format, Optimized Row Columnar (ORC) и Parquet.
Чаще всего в системах применяют именно Parquet. Apache Parquet – это бинарный, колоночно-ориентированный (столбцовый) формат хранения данных. Parquet является довольно сложным форматом по сравнению с тем же текстовым файлом с json внутри. Parquet использует архитектуру, основанную на «уровнях определения» (definition levels) и «уровнях повторения» (repetition levels), что позволяет довольно эффективно кодировать данные, а информация о схеме выносится в отдельные метаданные. При этом оптимально хранятся и пустые значения. По сути, Parquet, это просто файлы, а значит с ними легко работать, перемещать, резервировать и реплицировать.
Колончатый вид позволяет значительно ускорить работу аналитика, если ему не нужны все колонки сразу. Например, рассмотрим, как хранится одна и та же таблица в текстовом файле и в файле Parquet.
Исходная таблица:
При строковом хранении данных (txt, csv, Avro и т.д.) в файле наша таблица выглядит следующим образом:
В файле Parquet данные будут располагаться так:
На первый взгляд разница не велика, но суть в том, что когда речь заходит о размерах данных свыше нескольких миллионов строк, то кажущейся несущественной разница в чтении в 1 мс., превращается в часы ожидания. Теперь представьте:
- как быстро произойдет поиск и считывание разбросанных значений из столбца A при строковом хранении?
- как быстро произойдет поиск и считывание значений столбца A, хранящихся в одном месте, при колоночном формате?
Необходимо постоянно думать о схеме и типах данных, но данные журналов регистрации и учёта, как правило, с одного и того же оборудования генерируются по заданной схеме и с заданным форматом.
Данные, хранящиеся в Parquet, невозможно изменить и как следствие, они не поддерживают транзакции.
Выбор формата
В Hadoop предусмотрено несколько форматов хранения данных для последующей их обработки в системе. Для каждого из типов данных может быть более оптимальным один из возможных форматов хранения. Кроме того, на то, какой из типов данных выбрать существенно влияет то, какую задачу мы предполагаем решать, работая с данными (писать данные и их изменять/читать полную строку данных со всем содержимым/выборочно читать фрагмент данных и т.д.).
Сравнительная таблица ключевых параметров форматов данных представлена ниже (Табл. 2).
Таблица 2. Сравнение форматов файлов данных
Как видно из таблицы, наиболее интересные форматы это Avro и Parquet. Если сравнить их чуть более детально, то получится следующее (4 - макс. оценка, 0 - минимальная). (Табл. 3)
Таблица 3.Сравнение форматов Avro и Parquet
Учитывая вышесказанное и то, что наши данные с течением времени не меняются (а значит могут быть "жёстко" описаны) оптимальным форматом хранения данных для нас представляется формат Apache Parquet. С форматом хранения мы определились, возник вопрос – какой инструмент выбрать для того, чтобы эффективно с ним работать?
Выбор формата
Оттолкнувшись от того, что нам требуется скорость и удобство работы с хранимой информацией, желательно при помощи традиционных SQL-запросов, мы решили использовать компонент Impala.
Impala – это механизм SQL-запросов MPP (Massive Parallel Processing) для обработки больших объемов данных, хранящихся в кластере Hadoop. Impala – программное обеспечение с открытым исходным кодом, написанное на C++ и Java. Он обеспечивает высокую производительность и низкую задержку по сравнению с другими механизмами SQL для Hadoop. Другими словами, Impala – это высокопроизводительный механизм SQL, который обеспечивает быстрый способ доступа к данным, хранящимся в распределенной файловой системе Hadoop.
Impala объединяет поддержку SQL и многопользовательскую производительность традиционной аналитической базы данных с масштабируемостью и гибкостью Apache Hadoop, используя стандартные компоненты, такие как HDFS, HBase, Metastore, YARN и Sentry. С помощью Impala пользователи могут общаться с HDFS или HBase с помощью запросов SQL быстрее, по сравнению с другими механизмами SQL, такими как Hive. Impala может читать практически все форматы файлов, такие как Parquet, Avro, RCFile, используемые Hadoop.
Impala использует те же метаданные, синтаксис SQL (Hive SQL), драйвер ODBC и пользовательский интерфейс (HUE), обеспечивая знакомую и унифицированную платформу для пакетных запросов или запросов в реальном времени. В отличие от Apache Hive, Impala не основана на алгоритмах MapReduce. Он реализует распределенную архитектуру на основе процессов-демонов, которые отвечают за все аспекты выполнения запросов, выполняющихся на одних и тех же машинах. Таким образом, это уменьшает задержку использования MapReduce, и это делает Impala быстрее, чем Apache Hive.
Основные преимущества Impala:
- Impala поддерживает обработку данных в памяти, то есть она получает доступ и анализирует данные, которые хранятся на узлах данных Hadoop, без перемещения данных.
- Для доступа к данным используются традиционные SQL- запросы.
- Impala обеспечивает более быстрый доступ к данным в HDFS по сравнению с другими механизмами SQL, в т.ч. потому что не используются алгоритмы MapReduce.
- Используя Impala, есть возможность хранить данные в таких системах, как HDFS, Apache HBase, Amazon s3 и других. • Impala интегрируется с такими инструментами бизнес-аналитики, как Tableau, Pentaho, Zoom data и пр.
- Impala поддерживает различные форматы файлов, такие как LZO, Sequence File, Avro, RCFile и Parquet.
- Impala использует метаданные, драйвер ODBC и синтаксис SQL из Apache Hive.
Таким образом, мы определили для себя основной формат хранения и запросов к собираемым данным в создаваемой нами системе. Тестовые испытания показали более быструю скорость выполнения запросов к данным, хранимым в нашей системе, относительно тех же событий, хранящихся в SIEM системах на базе ArcSight, ArcSight Logger и ArcSight Vertica, что позволяет нам со сдержанным оптимизмом смотреть на нашу будущую архитектуру.