2017-01-14 3 views
10

Dies ist eine Optimierung Frage, dies ist mein Strom (Arbeits-) Situation:Spark, optimieren Metriken Generation von DF

  • Spark im Stand-alone-Modus mit Funken Job Server ausgeführt wird;
  • Ich habe eine Parkett-Datei mit ~ 3M Reihen im Speicher als Tabelle zwischengespeichert;
  • Die Tabelle umfasst alle Daten einer E-Commerce-Site. Jede Zeile repräsentiert einen Benutzer, aber ein Benutzer kann mehrere Zeilen haben.

Die Client-Anforderung ist eine SQL-Abfrage auszuführen, und hat die auf einer Webseite in einigen Tabellen angezeigten Ergebnisse, ein jeder eine Metrik mit einem Zähler darstellt, wie:

Alter => 18-20 : 15 Benutzer, 21-35: 42 Benutzer, ...

Land => USA: 22 Benutzer, GB: 0 Benutzer, ...

Und so weiter. Wenn wir alle Tabellen zählen (zusammen mit einigen Informationen über die Sitzung der Benutzer, die basierend auf Aktivität, Zeitraum und Jahr generiert werden), haben wir derzeit ca. 200 Metriken.

das letzte frei System in Produktion verwendet (df als Datenrahmen aus SQL-Abfrage resultierenden Berücksichtigung) zu extrahieren und aggregierte Daten aus der Zeile

df.rdd.aggregate(metricsMap) (

     (acc: MetricsMap, r:Row) => { 
     acc.analyzeRow(r) 
     acc 
     }, 

     (acc1: MetricsMap, acc2: MetricsMap) => { 
     acc1.merge(acc2) 
     acc1 
     } 
    ) 

Wo MetricsMap verwendete ein Objekt ist.

Diese Operation ist sehr CPU-intensiv, und auf dem Server dauert es ~ 20 Sekunden, um die Daten aus einer Abfrage ohne Parameter (also aus allen Daten in der Parkett-Datei) zu extrahieren.

Ich habe mich entschieden, Aggregation zu verwenden, weil sie für ihre statistische Analyse mehrere Prospectives wollten: einige Metriken sollten nach Benutzerschlüssel gezählt werden, ein anderer nach Benutzername (für die Site ...) und der andere nach Produktschlüssel . Bei dieser Methode musste ich das Ergebnis nur einmal durchlaufen, aber ich weiß nicht, ob es der bessere Ansatz ist ...

Ist dies der bessere Ansatz, oder es existiert eine andere (schnellere) Methode, um die zu erhalten Das gleiche Ergebnis?

In Bezug auf die Frage zu berechnen Metriken im Voraus, die Abfragen, die sie auf den Datensatz tun können, sind nicht gebunden, so dass ich nicht weiß, ob dies möglich ist oder nicht ... Könnten Sie mir bitte ein Beispiel geben?

Beantwortung einiger Fragen

+3

Können Sie ein wenig mehr Informationen zur Aggregation bereitstellen? Gibt es einen Grund, warum Sie zurück zu rdd statt in Datenrahmen/SQL-Ebene arbeiten? –

+0

Können Sie die Messwerte vorab berechnen? –

Antwort

0

Ein Weg der Daten in solchen Fällen offensichtlich besser ist als mehrere Zyklen haben, in Fällen Sie mehrere Anfragen für die gleiche Anfrage beantworten möchten.

Könnte effizienter sein, aber nicht mit Funkenkern interop.

Zum Beispiel, wenn Ihr DF-Schema wie folgt:

root 
-- age 
-- country 

Dann versuchen Sie möglicherweise die folgende Pseudo-Basisabfrage zu tun:

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 

Sie auch für die Verwendung eines UDF könnte in Erwägung ziehen Altersgruppe. Wie @ assaf-mendelson erwähnt, wäre hier mehr Info nützlich.

Verwandte Themen