Добрый день, коллеги Посоветуйте, пожалуйста, какой архитектурный подход может быть приемлем

в данной ситуации.

Дано: есть S3, куда в виде паркетных файлов выкладываются данные, E-com сайта или группы сайтов.
Дальнейший процессинг данных осуществляется с помощью Spark.
Нужно сохранять лог событий в один или несколько паркетных файлов.
Вопрос, как правильно организовать структуру хранения.
Проблема в том, что есть разные типы событий. У разных типов событий может быть разный набор дополнительных атрибутов.
Причем продаваться могут очень разные типы айтемов, с совершенно разными атрибутами.
Для каких-то событий, например, хватит
- userId
- itemId
- eventType
- timestamp
Для каких-то нужно добавить дополнительные атрибуты. Например (но не суть важно)
- Price
- Discount
- Quantity
- ...
Теоретически, мы ожидаем, что время от времени у нас могут добавляться новые типы событий, которые могут приносить с собой новые атрибуты.

Предполагаемые варианты:
1. Хранить все события в одной табличной структуре с полным списком полей. Недостатки:
------>дополнительные поля, которые актуальны только для некоторых типов событий, будут висеть с null'ами и при занимать место в памяти при чтении
------->добавление нового типа события с доп. атрибутами приводит к добавлению столбцов-атрибутов сразу для всех событий в источнике (и видимо для всей истории). Кажется, что это больновато или нужно думать, как это делать
2. Группировка типов событий с более-менее однородным атрибутным составом и раскладывание в разные таблицы. Проблема: нулевая гибкость и масштабируемость на новые источники и типы событий.
3. Есть основная таблица с событиями, где хранится минимум атрибутов, которые общие для всех. У каждого события есть ключ. Дополнительные атрибуты хранятся в отдельных "выносных" таблицах с join'ом по ключу. Недостаток: обилие тех самых join'ов при обработке данных
4. Есть основная таблица с событиями, где хранится минимум атрибутов, общих для всех. Доп. атрибуты хранятся во вложенной json-подобной структуре. И там уже кому сколько чего надо
5. Каждый тип события складывается в свой отдельный паркетный файл (файлы) со своим атрибутным составом. ИД типа события - часть названия файла. Если нужно выбрать определенный набор типов событий, формируется условие по маске файлов. (Меня лично от этого варианта сильно коробит, но его мне активно предлагают. Тут варианта 2, либо я пойму, что я неправильно смотрю на мир, и это на самом деле окей :), либо накоплю побольше аргументов, почему это нехорошо :) )
6. ... может быть, есть другие классные идеи? Наверняка, проблема известная и 10 раз решенная, просто нужно знать стандартные рецепты, а мне эрудиции не хватает...

В общем, прошу прощения за лонгрид и заранее спасибо за идеи и мнения

13 ответов

18 просмотров

Гипотетически, можно ещё во что-то вроде hbase положить, тогда не придется перебивать из-за того, что схема разная и скачет. Но это от паттерна использования данных зависит.

(5) с разделением по s3 prefix будет ок, скорее всего s3://bucket-name/data/structured/source_type=... /event_type=... /day=2021-02-22/..

Я бы максимально пытался выделить общие колонки таблицы, далее сделать колонку data, которая map(string, string). Эту таблицу положил бы в raw(bronze) слой, а на ружу, для пользования сделал бы отдельную таблицу, где схема подведена к читаему виду

Vladimir-Litvinyuk Автор вопроса
Almaz Murzabekov
Я бы максимально пытался выделить общие колонки та...

А какие варианты по схеме таблицы для пользования?

Vladimir-Litvinyuk Автор вопроса

Ну тогда это превращается в вариант 1, кажется?

Vladimir Litvinyuk
Ну тогда это превращается в вариант 1, кажется?

Таблица на запись похоже на ваш 4й вариант, таблица на чтение это больше похоже на промежуточные витрины

Vladimir-Litvinyuk Автор вопроса
Сиплый
(5) с разделением по s3 prefix будет ок, скорее вс...

А насколько ок запросу на несколько событий? Фильтрация типов событий с помощью файловой маски как-то не очень красиво выглядит. Или я драматизирую?

Vladimir-Litvinyuk Автор вопроса
Almaz Murzabekov
Таблица на запись похоже на ваш 4й вариант, таблиц...

Вот я пытаюсь представить себе на что похожа таблица на чтение. И получается, что она похожа на вариант 1. Чем она отличается?

Вообще можно было б не заморачиваться, отдать на чтение таблицу в которой есть колонка data (с мапой), но тогда спарку будет тяжелее

Vladimir-Litvinyuk Автор вопроса
Almaz Murzabekov
Вообще можно было б не заморачиваться, отдать на ч...

Тут расчёт на то, что для 70%+ запросов атрибуты в мапе не нужны. Но все равно, не уверен, насколько это хорошее решение

Vladimir Litvinyuk
А насколько ок запросу на несколько событий? Фильт...

не совсем. для диапазона дат у вас будет чтение с WHERE event_type IN (..) но если типов событий > 30, то будет очень много партиций, а это тоже неприятно но вообще, для разных типов запросов совершенно нормально материализовывать одну и ту же дату по-разному сколько даты в 1 день в сжатом виде приходит сейчас?

Vladimir-Litvinyuk Автор вопроса

Может, я не совсем понял, но если разные события в разных источниках с разным s3 prefix, какой where in? Или мы всегда читаем весь каталог?

Vladimir Litvinyuk
Может, я не совсем понял, но если разные события в...

весь каталог не читаем никогда, если прокидываем partition filter по event_type

Похожие вопросы

Обсуждают сегодня

Ребята, всем привет. Подскажите, пожалуйста, можно ли как-то через бота понять, что этого бота добавили в группу\канал и выдали ему права администратора?
Artem Stormageddon
9
Это переведённый текст с английского. Я не говорю на русском, но могу использовать переводчик Телеграм. Приветствую! Я начинающий веб-разработчик и все еще учусь. В настояще...
𐩱𐩪𐩣𐩱𐩲𐩺𐩡
3
А не хотим ли мы развлечься? 😉 Но так чтобы с пользой для наших профессиональных навыков?? 👨‍🎓👩‍🎓 Предлагаю на октябрь запланировать тестовый запуск новой командной игры "Игр...
Andrii Kurdiumov
2
Привет всем! Почему этот код не срабатывает при добавлении или удалении пользователя из чата? bot.on('chat_member', async (ctx) => { console.log(ctx); }) bot.launch({allo...
Alexander
5
у кого сколько оперативы на базе данных ?
АДИЛЬБЕК
4
Через бот апи возможно получить ID стикерпака? Не ссылку.
Vexylon [АФК до 09.09]
5
Привет Хочу сделать аналог iCloud’а для своих проектов, чтобы пользовательская информация хранилась в облаке, была доступна во всех сервисах, её можно было подсасывать везде)...
Виталий
9
В тг можно спарсить всех кто пишет в группе? Если список участников скрыт
S
3
код Event::listen('cms.page.display', function (&$content, $slug, $page, $html) { if (is_object($content)) { dump($content); } else { dump($s...
Point 111
3
Всем привет. Не понимаю, в чём тут шутка юмора. Убирается только разрешение на send_messages. А send_media_messages остаётся. Как сделать, чтобы оба убирались? await b...
Alexander
2
Карта сайта