[МУЗЫКА]
[МУЗЫКА] В этом
уроке мы поговорим о системах хранения данных.
Для того чтобы анализировать данные, их необходимо как-то хранить, причем систему
хранения желательно выбирать под конкретную задачу, исходя из ее специфики.
Прежде всего нужно ответить на вопросы о свойствах нашего хранилища.
Какой будет объем данных?
Может быть, для работы нам будет достаточно обычного табличного процессора
вроде Microsoft Excel, или же без массивного кластера нам не обойтись.
Нужен ли нам случайный доступ к данным,
или данные будут обрабатываться последовательно?
Как эти данные организованы?
Это фиксированный набор полей или разреженное множество атрибутов?
Каково отношение отклика системы,
так называемой latency, к пропускной способности, throughput.
Рассмотрим некоторые подходы к хранению данных.
Простейший вариант — это обычная файловая система, на которой можно хранить
любые неструктурированные наборы бинарных данных, например,
изображения, аудио- или видеофайлы.
В первом приближении мы можем использовать как обычную файловую систему на
настольном компьютере, так и распределенную,
где физически информация хранится на наборе компьютеров, объединенных в сеть.
К примерам распределенной файловой системы, подходящей, в частности,
для поточной обработки данных, является система HDFS,
от английского Hadoop Distributed File System.
Эта система специально спроектирована для хранения петабайт данных в пригодном
для обработки виде.
При этом гарантируется определенный уровень надежности и избыточности,
когда один и тот же набор данных может находиться на физически
разных компьютерах.
Для конечного пользователя HDFS отличается
от локальной системы лишь в деталях, хотя, безусловно, существуют мощные
инструменты для использования всех преимуществ распределенности.
На данный момент это выходит за рамки нашего курса,
но вы легко можете найти такую информацию.
Но самым популярным на сегодняшний день и классическим видом
хранения данных является реляционная база данных.
Такие, как, например, упомянутые системы Oracle или PostgreSQL.
Они имеют под собой мощную теоретическую базу и длинную историю.
Нереляционные базы данных, или, как их часто называют, NoSQL
или no SQL еще — это системы, в которых не используется реляционная модель.
Об этом семействе данных мы поговорим немного позже.
В определенном смысле особняком стоят графовые базы данных,
где информация организована в графы и подобные иерархические структуры.
Самый простой пример для применения таких систем — хранение данных социальной сети,
где вершины — это пользователи с атрибутами,
а ребра — это связи между ними.
Подобные базы данных позволяют быстро получать доступ к атрибутам и связям между
объектами, существенно более эффективно, чем это делают иные базы данных.
Очень важно с самого начала правильно сформулировать требования к хранилищу.
Резюмируем их еще раз.
На встраиваемость, то есть способность работать внутри
приложения без использования внешних зависимостей или компонентов,
имеет смысл обратить внимание тогда, когда требуется высокая переносимость.
С другой стороны, если переносимость не важна, но при этом данных очень много,
то имеет смысл обратить внимание на распределенные системы.
Требование транзакционности накладывается, когда
важны гарантии сохранения целостности данных при любом режиме работы с ними.
И, наконец, проблемы с производительностью могут подтолкнуть исследователя к
выбору систем, которые хранят все данные в памяти, так называемые In-Memory Storages.
Теперь остановимся подробнее на реляционных базах данных.
Как было сказано выше, это классические и проверенные временем решения.
Их основная идея в том, что данные организованы в виде
таблиц с фиксированным количество типизированных колонок или столбцов.
«Типизированных» означает то, что в этой колонке могут храниться
значения только определенного типа, например, строки, числа.
При этом таблицы могут быть связаны между собой по колонкам, когда колонка в
одной таблице имеет некую семантическую связь с колонкой в другой таблице.
Большинство промышленных баз данных являются большими,
сложными и трудноконфигурируемыми приложениями.
К ним относятся упомянутые Oracle и Microsoft SQL Server.
Некоммерческие решения в этом смысле не сильно лучше.
Единственное их преимущество — то, что они бесплатные.
Что касается упомянутых встраиваемых систем,
то самым ярким представителем из класса реляционных систем является SQLite.
Именно ее, кстати, мы будем использовать в нашем курсе для учебных заданий.
Наряду с понятными достоинствами реляционных баз данных, такими,
как, например, надежность, существуют, конечно, и недостатки.
Главным недостатком, как ни странно, является сама реляционная модель.
Дело в том, что при исследованиях в области науки о данных мы очень часто
имеем дело с нефиксированным количеством атрибутов.
По этой причине использование реляционных баз данных для нас является не
самым лучшим выбором.
Давайте рассмотрим пример.
Обратимся к слайду.
Пусть мы собираем данные о приложениях на платформе Android.
Для каждого приложения у нас есть информация о его названии, версии,
авторе и дате последнего обновления.
Логически данные можно представить в виде таблицы с четырьмя столбцами.
Для получения выборки данных по определенным условиям в реляционных базах
данных часто используют унифицированный и стандартизированный язык
— так называемый SEQUEL, или SQL.
В данном примере запроса из нашей таблицы,
которая называется app_table, мы выбираем две колонки: item и author.
То есть мы выбираем все приложения,
которые были обновлены после 1 июня 2017 года
и содержат в поле author слово Michelin.
Как вы видите, лаконичность и простота — это все-таки отличительная
особенность реляционных баз данных.
Далее идет большой набор нереляционных баз данных.
Их действительно очень большое количество,
они имеют абсолютно разные принципы организации и архитектуру.
Выделим основные типы.
Первый — это хранилище типа ключ-значение, или по-английски Key-Value Storages.
Они предназначены для доступа по одному ключу.
В качестве примера можно взять ситуацию,
когда мы хотим записывать в такое хранилище посещения пользователя.
Ключом в данном случае может быть его имя или какой-то иной идентификатор,
а значением — время последнего посещения.
Эти базы данных достаточно просты и очень часто используются в качестве
кэш-серверов.
Далее у нас идут документо-ориентированные базы данных,
где единицей хранения являются так называемые документы,
или же сложно организованные иерархические наборы данных.
Типичным примером применения этих систем является,
например, хранение досье на пользователя.
В этом случае мы будем хранить достаточно большое количество разнородной
и по-разному структурированной информации.
Например, его ник, время последнего захода в систему,
какие-то другие служебные данные.
И в данном случае, конечно, нам лучше иметь дело с документами.
Сейчас на рынке можно найти довольно большое количество коммерческих и
некоммерческих документо-ориентированных баз данных.
Самыми популярными из них являются, например, MongoDB и CouchDB.
Далее в нашем обзоре идут колоночные базы данных, которые логически могут быть
представлены как таблицы, но на самом деле, в отличие от традиционного подхода,
данные в них хранятся не по строкам, а по колонкам.
Как всегда,
это накладывает определенные ограничения и дает определенные преимущества.
Самым главным преимуществом таким систем является то,
что они очень хорошо подходят для распределенного хранения информации.
В качестве примера,
который вы можете найти на рынке сейчас — это система Cassandra.
Теперь мы поговорим о форматах хранения данных.
Мы остановимся на самых популярных: текстовых и бинарных форматах.
Первый из них — JSON — это текстовый формат
хранения сложных иерархических структур.
Формат этот произошел от языка программирования JavaScript
и обрел существенную популярность в последнее время.
Он часто используется организациями для взаимодействия различных сетевых ресурсов.
Это очень простой формат, под который существует огромное
количество библиотек практически во всех популярных языках программирования.
Давайте вновь рассмотрим пример и обратимся к слайду.
В данном случае мы будем рассматривать информацию о приложении в JSON-файле.
Файл состоит из пар ключ-значение или же списка элементов.
При этом значения могут образовывать иерархию.
В данном случае на первом уровне имеется шесть ключей: item_name,
version, contacts, updated, author и last_rates.
Согласитесь, это выглядит понятно и компактно.
Но проблема может возникнуть в том случае, если этот файл станет очень
большим и просто физически не поместится в оперативную память.
В этой ситуации мы не сможем получить доступ к каким-либо полям произвольным
образом, и работать таким образом с JSON-документом нам будет неудобно.
Следующий не менее распространенный формат — это формат CSV,
или же «значения, разделенные запятой».
Это происходит от английской аббревиатуры Comma-Separated Values,
то есть значения, разделенные запятыми.
На соревнованиях по машинному обучению, таких,
как Kaggle, это самый распространенный формат, в котором выдаются данные.
По факту, это просто текстовый формат для хранения табличных данных,
своеобразный упрощенный вариант Microsoft Excel.
Каждый объект в таком файле представляется строкой,
а его атрибуты — просто строками, разделенными запятыми.
Согласитесь, это тоже очень простой и легко читаемый формат.
Кроме того, опять же в любом современном языке программирования есть
библиотеки для работы с этим.
Далее рассмотрим более сложные форматы — бинарные.
Они не предназначены для чтения человеком,
но при этом позволяют хранить информацию в гораздо более компактном и удобном виде.
Первый из них — это Apache Parquet.
Он изначально был разработан как очередное
колоночно-ориентированное хранилище для экосистемы Hadoop.
Тем не менее его стало удобно использовать для обычного хранения.
Если сильно упростить,
то это оптимизированный и сжатый Comma-Separated Value формат,
с дополнительными преимуществами в виде типизации — данные в нем имеют
одну и ту же схему, что часто ограждает от потенциальных
ошибок — и готовность к распределенной обработке.
С этим форматом умеет работать система для поточной обработки данных Apache Spark,
а также большинство языков программирования поддерживают чтение и
запись в этот формат.
Естественно, мы можем это сделать из языков R и Python.
Следующий наш пример — это HDF5, файловая система, по сути,
спрятанная в одном файле.
Каждый набор данных имеет свой путь и предполагает как последовательный,
так и случайный доступ.
Этот формат поддерживает индексирование и позволяет работать с очень большими
данными, которые не помещаются в оперативную память компьютера.