2011-01-12 28 views
6

我正在尋找一種很好的方式來存儲與時間範圍相關的數據,以便以後能夠有效地檢索它。在卡桑德拉存儲時間範圍

數據的每個條目可以簡化爲(start time, end time, value)。我將需要稍後檢索落入(x, y)範圍內的所有條目。在SQL中,查詢會像

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

您能否提供對Cassandra的數據,這將允許我以有效地執行這樣的查詢的結構?

回答

6

這是一個奇怪的困難的事情來建模效率。

我認爲使用Cassandra的二級索引(以及目前不幸仍然需要的虛擬索引值)是您的最佳選擇。您需要爲每個事件使用至少三列一行:'開始','結束'和'虛擬'。在每一個上創建一個二級索引。前兩個可以是LongType,最後一個可以是BytesType。有關更多詳細信息,請參見this post on using secondary indexes。由於您必須對至少一列的EQ表達式使用次要索引查詢(我提到的不幸要求),因此EQ將處於「虛擬」狀態,可以始終設置爲0.(這意味着EQ索引表達式將匹配每一行,實質上是一個空操作)。您可以將其餘的事件數據存儲在起始,結束和虛擬的行中。

pycassa,一個Python卡桑德拉的客戶,您的查詢應該是這樣的:

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 

應該有其他客戶類似的東西。

我首先考慮的替代方法涉及OrderPreservingPartitioner,它幾乎總是一件壞事。對於索引,您可以將開始時間用作行鍵,結束時間用作列名稱。然後,您可以使用start_key = start_time和column_finish = finish_time執行範圍切片。這將在開始時間後掃描每一行,並且只在finish_time之前返回那些列。效率不高,而且你必須做一個大型的multiget等等。內置的二級索引方法更好,因爲節點只會索引本地數據,並且大部分樣板索引代碼都是爲你處理的。