2016-10-10 63 views
0

我想查詢我的表的完整分區。 我的複合分區密鑰由(id, date, hour_of_timestamp)組成。 iddate是字符串,hour_of_timestamp是一個整數。Cassandra - IN或TOKEN查詢查詢整個分區?

我需要添加hour_of_timestamp字段到我的分區鍵因爲熱點,而攝取數據。

現在我想知道什麼是最有效的方式來查詢我的數據的完整分區? 根據this blog,使用SELECT * from mytable WHERE id = 'x' AND date = '10-10-2016' AND hour_of_timestamp IN (0,1,...23);在協調器節點上造成大量開銷。

使用TOKEN函數並用兩個令牌查詢分區更好嗎?如SELECT * from mytable WHERE TOKEN(id,date,hour_of_timestamp) >= TOKEN('x','10-10-2016',0) AND TOKEN(id,date,hour_of_timestamp) <= TOKEN('x','10-10-2016',23);

所以我的問題是: 我應該使用INTOKEN查詢查詢我的數據的整個分區?或者我應該使用23個查詢(hour_of_timestamp的每個值),然後讓司機完成剩下的工作?

我使用Cassandra 3.0.8和最新的Datastax Java驅動程序連接到6節點羣集。

+0

你可以發佈你的整個PRIMARY KEY定義嗎? – Aaron

+0

@Aaron PRIMARY KEY((log_creator,date,hour),ts,log_id)是實際的定義。我已經調整了問題中的字段名稱,使其更加「通用」...... ts'的類型是'timestamp','log_id'是另一個字符串。 – j9dy

回答

1

你說:

現在,我不知道什麼是查詢我的數據的完整 分區的最有效方法是什麼?根據這個博客,使用SELECT * from mytable WHERE id ='x'AND date = '10-10-2016'AND hour_of_timestamp IN(0,1,... 23);在協調器節點上造成大量開銷。

但實際上你會查詢24個分區。

您可能的意思是,您有一個設計,其中一個分區是現在由24個分區組成的,因爲您在數據攝入期間添加小時以避免熱點。他指出,在這兩種模式(舊有熱點和新的)數據仍然通過時間戳排序,你有兩個選擇:

  1. 運行在時間1個查詢。
  2. 第一次運行2查詢,然後一次查詢「預取」結果。
  3. 並行運行24個查詢。

CASE 1

如果處理數據順序,該第一選擇是爲小時0運行查詢,處理該數據,並且在完成時,運行查詢爲每小時1等在...這是一個簡單的實現,我認爲它不值得比這更多。

CASE 2

如果查詢需要更多的時間比你的數據處理,你可以「預取」的一些數據。因此,您第一次可以並行運行2個查詢來獲取小時0和1的數據,並開始處理小時0的數據。與此同時,小時1的數據到達,所以當您完成小時0的數據處理時,您可以預取小時2的數據並開始處理小時1的數據。依此類推......以這種方式,您可以加速數據處理。當然,根據您的計時(數據處理和查詢時間),您應該優化「預取」查詢的數量。

另請注意,Java驅動程序會自動爲您分頁,並且根據檢索到的分區的大小,您可能希望禁用該功能以避免阻止數據處理,或者可能希望以某種方式搶先獲取更多數據像this

ResultSet rs = session.execute("your query"); 
for (Row row : rs) { 
    if (rs.getAvailableWithoutFetching() == 100 && !rs.isFullyFetched()) 
     rs.fetchMoreResults(); // this is asynchronous 
    // Process the row ... 
} 

在那裏你可以調整該rs.getAvailableWithoutFetching() == 100,以更好地滿足您的預取的要求。

您可能還想第一次預取多個分區,以確保您的處理不會等待任何數據提取部分。

CASE 3

如果您需要處理來自不同分區的數據一起,例如,你需要爲每小時3和6兩個數據,那麼你可以通過「依賴」試組數據(例如查詢兩小時3和6並聯)。

如果你需要所有這些,那麼應該並行運行24個查詢,然後在應用程序級別加入它們(你已經知道爲什麼你應該避免在多個分區中使用IN)。請記住,您的數據是已訂購,所以您的應用程序級別的工作量將非常小。