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

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

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

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

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

13 ответов

4 просмотра

Гипотетически, можно ещё во что-то вроде 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

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

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

Ребята, всем привет, у меня такой вопрос, заказчику нужно чтобы бот собирал данные о количестве просмотров на определенных постах, уже все перерыл, как то можно реализовать та...
AdmM
3
'frakturBold' => ['𝖆', '𝖇', '𝖈', '𝖉', '𝖊', '𝖋', '𝖌', '𝖍', '𝖎', '𝖏', '𝖐', '𝖑', '𝖒', '𝖓', '𝖔', '𝖕', '𝖖', '𝖗', '𝖘', '𝖙', '𝖚', '𝖛', '𝖜', '𝖝', '𝖞', '𝖟', '𝕬', '𝕭', '𝕮', '𝕯'...
Roma
4
Всем привет. Подскажите, почему не меняется значение поля при переключении сайта?
Alexander Peterikov
11
Можно ли загрузить скрипт py в бота чтобы он работал по нему? как это сделать?
huskadam #RCC Фанат? @hitlerpvp
13
Добрый день, не подскажите, если в OC-V3 поменять страндартную директорию /storage/ на /storage2/ - не будет сильно много проблем ?
Max Dubovsky
32
Ребят, а за скок можно впарить анон чат с апишкой и веб админкой ?
Eugene Неелов
15
Каким то образом можно определить ширину экрана пользователя перед загрузкой partial-а? Надо рассчитать ширину кадров слайдера для ресайза картинок для container-fluid.
Point 111
22
Ты просто гитлеровскую эстетику плохо понимаешь. Он же всё под Цезаря делал. А это как бы запрещённый приём в политике. Пиджаки они зачем все носят? Чтобы показать что они тип...
Ivan Kropotkin
4
Приветствую друзья, подскажите сколько в среднем стоит на данный момент создать тг бота который будет как магазин? Показывать ассортименты доставлять заказы и тд? Все по станд...
Eugene
3
привет, а расскажите как бэкапите свой vault raft cluster CE? я немного почитал и понял, что нужно как-то выполнять vault operator raft snapshot save backup.snapshot подсовыва...
[DBST] Dmitry Knyazev
5
Карта сайта