Это вопрос оптимизации, это моя текущая (рабочая) ситуация:
- Spark работает в автономном режиме с использованием spark-jobserver;
- У меня есть файл паркета с ~ 3M строк, кэшированных в памяти в виде таблицы;
- Таблица представляет собой совокупность всех данных с сайта электронной торговли, каждая строка представляет пользователя, но пользователь может иметь больше строк;
Клиентский запрос должен выполнять SQL-запрос и показывать результаты на веб-странице в некоторых таблицах, каждый из которых представляет метрику с помощью счетчика, например:
Возраст = > 18-20: 15 пользователей, 21-35: 42 пользователей,...
Страна = > США: 22 пользователя, GB: 0 пользователей,...
И так далее. Подсчитывая все таблицы (вместе с некоторыми сеансами пользователей, которые генерируются на основе активности, периода и года), мы имеем в настоящее время ~ 200 показателей.
Последняя выпущенная система в производстве использует (учитывая df как DataFrame в результате SQL-запроса):
df.rdd.aggregate(metricsMap) (
(acc: MetricsMap, r:Row) => {
acc.analyzeRow(r)
acc
},
(acc1: MetricsMap, acc2: MetricsMap) => {
acc1.merge(acc2)
acc1
}
)
Где MetricsMap - это объект, используемый для извлечения и агрегирования данных из строки.
Эта операция очень интенсивна для процессора, а на сервере требуется ~ 20 секунд, чтобы извлекать данные из запроса без параметров (поэтому из всех данных в файле паркета).
Я решил использовать агрегацию, потому что для их статистического анализа им нужны несколько перспектив: некоторые показатели должны подсчитываться с помощью ключа пользователя, другого по имени пользователя (для сайта...), а другое - по ключу продукта. Используя этот метод, мне пришлось циклически перебирать результат только один раз, но я не знаю, подходит ли ему лучший подход...
Это лучший подход или существует какой-то другой (более быстрый) метод для получения того же результата?
Что касается вопроса о вычислении метрик заранее, запросы, которые они могут делать в наборе данных, не связаны, поэтому я не знаю, возможно ли это или нет... Не могли бы вы привести пример?
Отвечая на некоторые вопросы