2016-02-04 14 views
5

Attualmente stiamo utilizzando Cassandra (http://cassandra.apache.org/) per i dati della serie storica. Cassandra è molto veloce sulle letture, ma dobbiamo eseguire una serie di calcoli sui nostri dati prima di presentarli (effettivamente stiamo imitando le funzionalità SUM e GROUP BY di SQL - Qualcosa che Cassandra non supporta immediatamente)Grandi set di dati web in Python: come gestire array molto grandi?

Siamo familiarità con Python (ad un grado) e abbiamo deciso di costruire uno script per interrogare il nostro gruppo Cassandra e di eseguire la matematica e presentare il risultato in un formato JSON:

query = (
    "SELECT query here...") 

startTimeQuery = time.time() 

# Executes cassandra query 
rslt = cassession.execute(query) 

print("--- %s seconds to query ---" % (time.time() - startTimeQuery)) 

tally = {} 

startTimeCalcs = time.time() 
for row in rslt: 
    userid = row.site_user_id 

    revenue = (int(row.revenue) - int(row.reversals_revenue or 0)) 
    accepted = int(row.accepted or 0) 
    reversals_revenue = int(row.reversals_revenue or 0) 
    error = int(row.error or 0) 
    impressions_negative = int(row.impressions_negative or 0) 
    impressions_positive = int(row.impressions_positive or 0) 
    rejected = int(row.rejected or 0) 
    reversals_rejected = int(row.reversals_rejected or 0) 

    if tally.has_key(userid): 
     tally[userid]["revenue"] += revenue 
     tally[userid]["accepted"] += accepted 
     tally[userid]["reversals_revenue"] += reversals_revenue 
     tally[userid]["error"] += error 
     tally[userid]["impressions_negative"] += impressions_negative 
     tally[userid]["impressions_positive"] += impressions_positive 
     tally[userid]["rejected"] += rejected 
     tally[userid]["reversals_rejected"] += reversals_rejected 
    else: 
     tally[userid] = { 
      "accepted": accepted, 
      "error": error, 
      "impressions_negative": impressions_negative, 
      "impressions_positive": impressions_positive, 
      "rejected": rejected, 
      "revenue": revenue, 
      "reversals_rejected": reversals_rejected, 
      "reversals_revenue": reversals_revenue 
     } 


print("--- %s seconds to calculate results ---" % (time.time() - startTimeCalcs)) 

startTimeJson = time.time() 
jsonOutput =json.dumps(tally) 
print("--- %s seconds for json dump ---" % (time.time() - startTimeJson)) 

print("--- %s seconds total ---" % (time.time() - startTimeQuery)) 

print "Array Size: " + str(len(tally)) 

Questo è il tipo di uscita otteniamo:

--- 0.493520975113 seconds to query --- 
--- 23.1472680569 seconds to calculate results --- 
--- 0.546246051788 seconds for json dump --- 
--- 24.1871240139 seconds total --- 
Array Size: 198124 

Stiamo spendendo una grande quantità di tempo sui nostri calcoli, sappiamo che il problema non sono tanto le somme quanto il gruppo stesso: è solo la dimensione della matrice che è il problema.

Abbiamo sentito alcune cose positive su numpy, ma la natura dei nostri dati rende la dimensione della matrice uno sconosciuto.

Stiamo cercando suggerimenti su come affrontarlo. Compreso un approccio di programmazione completamente diverso.

+2

Il pacchetto goto python per i dati degli orari è 'pandas' che utilizza' numpy' sotto il cofano. Hai esaminato questo? –

+2

Inoltre, quanto è grande "grande"? –

+0

deserializzazione? –

risposta

0

Cassandra 2.2 e versioni successive consente agli utenti di definire funzioni di aggregazione. Puoi usarlo per eseguire la colculazione di colonne sul lato cassandra. Si prega di vedere DataStax article per datails su User Defined Aggregates

1

Ho eseguito un processo di elaborazione molto simile ed ero anche preoccupato dei tempi di elaborazione. Penso che tu non stia spiegando qualcosa di importante: l'oggetto risultato che ricevi da cassandra come restituzione della funzione execute() non contiene tutte le linee che vuoi. invece, contiene un risultato impaginato e otterrà linee mentre si scorre attraverso l'oggetto all'interno dell'elenco for. Ciò si basa sull'osservazione personale, tuttavia, non conosco ulteriori dettagli tecnici da fornire al riguardo.

suggerisco di isolare interrogazione ed elaborazione dei risultati con l'aggiunta di un semplice rslt = list(rslt) subito dopo il comando execute, che costringerebbe python a passare attraverso tutte le linee nel risultato prima di fare l'elaborazione, anche costringendo il conducente Cassandra di ottenere tutte le linee che vuoi prima di passare all'elaborazione.

Penso che scoprirai che gran parte del tempo di elaborazione che hai avuto era in realtà interrogativo ma è stato mascherato dal driver tramite un risultato impaginato.

Problemi correlati