2017-01-14 4 views
10

Это вопрос оптимизации, это мой текущий (рабочий) ситуация:Спарк, оптимизировать генерацию метрик от DF

  • Искра работает в автономном режиме с использованием искрового-jobserver;
  • У меня есть файл паркета с ~ 3М строк, кэшированных в памяти в виде таблицы;
  • Таблица представляет собой совокупность всех данных с сайта электронной торговли, каждая строка представляет пользователя, но пользователь может иметь больше строк;

запрос клиента выполнить запрос 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 секунд для извлечения данных из запроса без параметров (поэтому из всех данных в файле паркета).

Я решил использовать агрегацию, потому что для их статистического анализа они требовали множественных перспектив: некоторые показатели должны учитываться с помощью ключа пользователя, другого по имени пользователя (для сайта ...), а другое по ключу продукта , Используя этот метод, мне пришлось циклически перебирать результат только один раз, но я не знаю, является ли это лучшим подходом ...

Это лучший подход или существует какой-то другой (более быстрый) метод для получения такой же результат?

Что касается вопроса о вычислении метрик заранее, запросы, которые они могут выполнять в наборе данных, не связаны, поэтому я не знаю, возможно ли это или нет ... Не могли бы вы привести мне пример?

Отвечая на вопросы

+3

Можете ли вы предоставить немного больше информации об агрегировании? В принципе, есть причина, по которой вы возвращаетесь к rdd вместо работы на уровне dataframe/SQL? –

+0

Можете ли вы предварительно вычислить показатели? –

ответ

0

Один путь данных в таких случаях, очевидно, лучше, чем иметь несколько циклов, в тех случаях, вы хотите, чтобы ответить на несколько запросов для одного запроса.

Может быть более эффективным, хотя и не взаимодействовать с искровым сердечником.

Например, если ваша схема DF выглядит следующим образом:

root 
-- age 
-- country 

Тогда вы можете попробовать сделать следующее псевдо базовый запрос:

Select 
CASE WHEN (age BETWEEN 18 AND 22) THEN '18-22' 
    WHEN (age BETWEEN 22 AND 30) THEN '22-30' 
    ELSE 'Other' as age_group, 
country 
from metrics_df 

Вы могли бы также рассмотреть возможность использования UDF для возрастная группа. Как упоминалось в @ assaf-mendelson, здесь больше информации.

Смежные вопросы