2011-01-12 5 views
6

Poszukuję dobrej metody przechowywania danych związanych z zakresem czasowym, aby móc ją później wydajniej odzyskać.Przechowywanie zakresów czasowych w kassandra

Każdy wpis danych można uprościć jako (start time, end time, value). Będę musiał później odzyskać wszystkie wpisy, które mieszczą się w zakresie (x, y). W SQL kwerenda byłoby coś

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

można zaproponować strukturę danych w Cassandry, które pozwoliłyby mi skutecznie wykonywać takie pytania?

Odpowiedz

6

To niezwykle dziwna zabawa w modelowanie.

Myślę, że korzystanie z wtórnych indeksów Cassandry (wraz z nieaktywną indeksowaną wartością, która jest w tej chwili niestety wciąż potrzebna) jest najlepszą opcją. Musisz użyć jednego wiersza na zdarzenie z co najmniej trzema kolumnami: "start", "koniec" i "manekin". Utwórz dodatkowy indeks na każdym z nich. Pierwsze dwa mogą być typu LongType, a ostatnie może być BytesType. Aby uzyskać więcej informacji, patrz this post on using secondary indexes. Ponieważ musisz użyć wyrażenia EQ w co najmniej jednej kolumnie dla dodatkowego indeksu zapytania (niefortunne wymaganie, o którym wspomniałem), EQ będzie na "manekinie", który zawsze może być ustawiony na 0. (Oznacza to, że wyrażenie indeksu EQ dopasuje każdy wiersz i zasadniczo nie będzie opcją.) Możesz przechowywać pozostałe dane zdarzenia w rzędzie obok początku, końca i manekina.

W pycassa klient Python Cassandra, zapytanie będzie wyglądać następująco:

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 

Nie powinno być coś podobnego w innych klientów.

Alternatywą, którą rozważałem jako pierwszą, jest OrderPreservingPartitioner, która prawie zawsze jest złą rzeczą. W przypadku indeksu jako czasu początkowego należy podać czas początkowy jako klucz wiersza, a czas zakończenia jako nazwę kolumny. Następnie można wykonać wycinek zakresu za pomocą klawiszy start_key = start_time i column_finish = finish_time. Spowoduje to przeszukanie każdego wiersza po czasie rozpoczęcia i zwróci tylko te kolumny z wartościami przed metą_czasu. Niezbyt wydajne, i trzeba zrobić duży multiget itp. Wbudowane podejście do indeksów wtórnych jest lepsze, ponieważ węzły będą indeksować tylko dane lokalne, a większość kodu indeksowania jest obsługiwana.