2011-01-12 14 views
6

Sto cercando un buon modo per archiviare i dati associati a un intervallo di tempo, in modo da poterli recuperare in modo efficiente in un secondo momento.Memorizzazione degli intervalli di tempo in cassandra

Ogni immissione di dati può essere semplificata come (start time, end time, value). Avrò bisogno di recuperare in seguito tutte le voci che rientrano in un intervallo (x, y). In SQL, la query sarebbe qualcosa di simile

SELECT value FROM data WHERE starttime <= x AND endtime >= y

Potreste suggerire una struttura per i dati nel Cassandra che mi permettesse di eseguire in modo efficiente tali query?

risposta

6

Questa è una cosa stranamente difficile da modellare in modo efficiente.

Penso che utilizzare gli indici secondari di Cassandra (insieme a un valore indicizzato fittizio che purtroppo è ancora necessario al momento) sia la soluzione migliore. Dovrai utilizzare una riga per evento con almeno tre colonne: "start", "end" e "dummy". Crea un indice secondario su ciascuno di questi. I primi due possono essere LongType e l'ultimo può essere BytesType. Vedi this post on using secondary indexes per maggiori dettagli. Poiché è necessario utilizzare un'espressione EQ su almeno una colonna per una query di indice secondario (lo sfortunato requisito che ho menzionato), l'EQ sarà su "dummy", che può sempre essere impostato su 0. (Ciò significa che l'espressione dell'indice EQ corrisponderà ad ogni riga e sarà essenzialmente un no-op.) È possibile memorizzare il resto dei dati dell'evento nella riga accanto a inizio, fine e manichino.

In pycassa, un client Python Cassandra, la query sarebbe simile a questa:

from pycassa.index import * 
start_time = 12312312000 
end_time = 12312312300 
start_exp = create_index_expression('start', start_time, GT) 
end_exp = create_index_expression('end', end_time, LT) 
dummy_exp = create_index_expression('dummy', 0, EQ) 
clause = create_index_clause([start_exp, end_exp, dummy_exp], count=1000) 
for result in entries.get_indexed_slices(clause): 
    # do stuff with result 

Non ci dovrebbe essere qualcosa di simile in altri client.

L'alternativa che ho considerato prima riguardava OrderPreservingPartitioner, che è quasi sempre una brutta cosa. Per l'indice, si utilizzerà l'ora di inizio come il tasto della riga e il tempo di fine come nome della colonna. È quindi possibile eseguire una sezione dell'intervallo con start_key = start_time e column_finish = finish_time. Questo scandirebbe ogni riga dopo l'ora di inizio e restituirà solo quelli con colonne prima del finish_time. Non molto efficiente, e devi fare un grande multiget, ecc. L'approccio indice secondario integrato è migliore perché i nodi indicizzeranno solo i dati locali e la maggior parte del codice di indicizzazione boilerplate viene gestito per te.

Problemi correlati