Сейчас у хранилища данных гораздо больше функций, чем просто хранение данных для отчетов, – например, оно может выступать источником данных для обучения ML-моделей. Данные можно хранить не только в базе данных, но и в виде файлов, как делает Hadoop.
С моей точки зрения, хранилища данных:
1) являются цифровым архивом компании;
2) являются копией данных в источнике;
3) не изменяемы;
4) хранятся в виде, максимально приближенном к данным в источнике;
5) позволяют объединят данные из разных источников.
Относитесь к хранилищу как к архиву компании [34], ведь там хранятся данные с момента ее создания. Часть данных вы уже нигде не найдете, так как источники периодически чистятся. В Retail Rocket, например, мы периодически архивируем все данные: товарные базы интернет-магазинов (они изменяются со временем), их структуры каталога, сами рекомендации. Ни в каких источниках их уже нет, но они есть в нашем хранилище и помогают решать важные задачи: искать причины проблем и моделировать новые алгоритмы рекомендаций.
Напрямую с источником данных не стоит работать по двум основным причинам. Во-первых, запросы к данным на чтение оказывают очень большую нагрузку на диски и увеличивают время ответа рабочих машин, и клиенты получают ответы ваших систем с задержкой. Во-вторых, может быть нарушена конфиденциальность данных, хранящихся в источниках. Не все данные нужно забирать оттуда в исходном виде, чувствительную информацию клиентов лучше не трогать или шифровать при загрузке в хранилище. Само хранилище проводит незримую границу между вашей рабочей системой, которая должна работать надежно, и данными, которые будут использованы для анализа. В Ozon.ru у меня был один раз случай, когда мой сотрудник, обращаясь напрямую к источнику данных, повредил данные клиента – разработчики тогда очень разозлились.
Неизменяемость уже загруженных данных в хранилище гарантирует, что ваши аналитические отчеты не будут меняться. Я буду лукавить, если скажу, что так не бывает. Бывает, но обычно из-за технических ошибок или расширения перечня хранимых данных. Такие инциденты нужно минимизировать по двум причинам. Во-первых, перезагрузка данных бывает очень длительной и блокирующей аналитическую систему. Например, у нас в Retail Rocket такая операция между Hadoop и Clickhouse могла занимать дни и даже недели. Во-вторых, доверие пользователей к вашей системе будет подорвано из-за изменения данных, а значит, отчетов и решений, которые были сделаны на их основе. Легко ли вам будет доверять данным, которые изменяются задним числом?
Я всегда стараюсь хранить данные в том виде, в котором они хранятся в источнике. Есть другой подход – делать преобразование данных при их копировании в хранилище. С моей точки зрения, второй подход имеет существенный недостаток: никто не может гарантировать, что преобразование или фильтрация пройдут без ошибок. Как минимум, данные в источнике изменятся, и преобразование «устареет». В какой-то момент вы заметите, что данные расходятся. Вам придется лезть в источник, возможно, скачивать их (а их может быть очень много) и построчно сравнивать. Такие ошибки крайне сложно искать. Поэтому удобно, когда исходные данные хранятся в сыром виде. Безусловно, преобразования нужны, но хранить измененные данные лучше в отдельных таблицах или файлах (в отдельном слое хранилища). Тогда сверка с источником будет заключаться лишь в сравнении числа строк между таблицами, а ошибки преобразований легко отыщутся внутри самого хранилища, так как исходники у вас имеются. Этот вывод был сделан мной на основе инцидентов по исправлению данных во всех компаниях, на которые я работал. Да, данных в хранилище может стать чуть ли не в два раза больше, но, учитывая сегодняшнюю низкую стоимость хранения и принцип «много данных не бывает», это все окупится.
В главе 5 я уже писал про связность данных, что самые интересные инсайты находятся на стыке их разных источников. Данные объединяются через ключи. Сама операция называется соединением данных (join). Она очень ресурсоемкая, разработчики баз данных постоянно работают над ее ускорением. На одной из лекций в компании Microsoft я услышал, что для больших данных количество таких операций нужно минимизировать, а для этого нужно сразу соединить данные в хранилище и в таком виде хранить. Это было около десяти лет назад. Сейчас уже есть системы, которые это могут делать лучше традиционных баз данных, об этом позже в этой главе.
Однажды у меня был разговор с разработчиком из компании Netflix. Я рассказывал ему про хранилища данных, а он остановил меня и сказал: «А не проще ли восстановить базу из бэкапа и с ней работать?» Во-первых, если вы не пользуетесь облачными сервисами, как это делает Netflix, то восстанавливать данные из бэкапа не так легко. Во-вторых, хранилища часто содержат свои агрегаты (о них расскажу позже), которые нужно поддерживать. В-третьих, если источников несколько и это разные базы данных или хранилища файлов, то будет невозможно делать запросы с соединением этих источников.
Слои хранилища данных
Само хранилище может состоять из нескольких слоев (рис. 6.1) [34]:
• Данные из источников «как есть» (Первичный слой данных), или по-другому – сырых данных. Как я уже писал выше, лучше их хранить в виде, максимально совпадающем с источником.
• Данные, приведенные в целостную форму, независимую от источника (Центральный слой). Это означает, что мы уже можем работать с логической схемой, человеко-понятными терминами. Аналитику не придется думать, как соотносятся термины в разных источниках, все уже сделано в этом слое.
• Данные, представленные в виде витрин для определенного круга пользователей (Витрины данных). Деление происходит по предметной области: маркетинг, продажи, склад… Лучшим примером будет подготовка данных для OLAP-кубов. Данные для них приходится специально готовить. Подробней об этом поговорим в следующей главе об инструментах анализа данных.
Рис. 6.1. Слои хранилища данных
Эти слои – логические, и они весьма условны; физически они могут размещаться как в разных системах, так и в одной.
В Retail Rocket я много работал с данными активности пользователей. Данные приходят в кластер в режиме реального времени в формате JSON и складируются в одну папку. Это первый слой – сырые данные. Сразу же делаем преобразование данных, чтобы было удобно работать с ними в формате CSV, складируем их во вторую папку. Это второй слой. Далее данные из второго слоя отправляются в аналитическую базу данных ClickHouse, где уже построены специальные таблицы для каких-либо задач – например, для отслеживания эффективности алгоритмов рекомендаций. Это третий слой витрины данных.
Какие бывают хранилища
Если распределить все созданные хранилища по популярности использования, то я бы их расставил так: