2011-01-12 10 views
6

Estoy buscando una buena manera de almacenar datos asociados con un rango de tiempo, para poder recuperarlos de manera eficiente más adelante.Rangos de tiempo de almacenamiento en cassandra

Cada entrada de datos se puede simplificar como (start time, end time, value). Necesitaré recuperar más tarde todas las entradas que caen dentro de un rango de (x, y). En SQL, la consulta sería algo así como

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

¿Puede sugerir una estructura para los datos de Cassandra que me permita realizar tales consultas de manera eficiente?

Respuesta

6

Esto es una cosa extrañamente difícil de modelar eficientemente.

Creo que el uso de los índices secundarios de Cassandra (junto con un valor indexado ficticio que por desgracia todavía se necesita en este momento) es su mejor opción. Tendrá que usar una fila por evento con al menos tres columnas: 'inicio', 'final' y 'ficticio'. Crea un índice secundario en cada uno de estos. Los primeros dos pueden ser LongType y el último puede ser BytesType. Vea this post on using secondary indexes para más detalles. Como debe usar una expresión de ecualización en al menos una columna para una consulta de índice secundaria (el desafortunado requisito que mencioné), el ecualizador estará en "ficticio", que siempre puede establecerse en 0. (Esto significa que la expresión de índice de ecualización coincidirá con cada fila y esencialmente será no operativa). Puede almacenar el resto de los datos del evento en la fila junto con el inicio, el final y el maniquí.

En pycassa, un cliente Python Cassandra, su consulta se vería así:

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 

Debe haber algo similar en otros clientes.

La alternativa que consideré involucró en primer lugar a OrderPreservingPartitioner, que casi siempre es una mala cosa. Para el índice, usaría la hora de inicio como la clave de la fila y la hora de finalización como el nombre de la columna. A continuación, puede realizar un segmento de rango con start_key = start_time y column_finish = finish_time. Esto escaneará cada fila después de la hora de inicio y solo devolverá aquellas con columnas antes de finish_time. No es muy eficiente, y tiene que hacer un gran multigrado, etc. El enfoque del índice secundario integrado es mejor porque los nodos solo indexarán los datos locales y la mayoría del código de indexación se maneja por usted.

Cuestiones relacionadas