2017-02-27 74 views
0

我的基於Cassandra的應用程序需要讀取自上次讀取後更改的行。當它被更改的標記 - 爲此,我們計劃有一個表changed_rows將包含兩列 -以小時間塊查詢cassandra的最有效方法

  1. ID - 更改的行的ID和
  2. Updated_Time。

什麼是讀取這樣的表的最佳方式,以便它讀取按時間排序的小組行。 例如:如果該表是:

ID Updated_Time 
foo 1000 
bar 1200 
abc 2000 
pqr 2500 
zyx 2900 
... 
xyz 901000 
... 

我已示出的ID是簡單的3個字母的鍵,實際上它們是的UUID。 此外,爲簡單起見,上面顯示的時間顯示爲整數,但其實際Cassandra時間戳(或Java日期)。 Updated_Time列是單調遞增的列。

如果我查詢這個數據:

SELECT * FROM changed_rows WHERE Updated_Time < toTimestamp(now()) 

我得到以下錯誤:

Cannot execute this query as it might involve data filtering and 
thus may have unpredictable performance... Use Allow Filtering 

但我認爲在這種情況下會殺死的性能Allow Filtering。 Cassandra索引頁面警告避免高基數列的索引,上面的Updated_Time確實看起來像是高基數。

因爲查詢的目的是要知道給定時間間隔之間更新的ID,所以我不知道ID列。

然後在這種情況下查詢Cassandra的最佳方法是什麼?
是否可以更改我的表以某種方式更有效地運行時間塊查詢?

注:這應該聽起來有點類似於Cassandra-CDC feature,但我們不能用一樣的,因爲我們的解決方案應該爲所有卡桑德拉版本

回答

2

工作假設你知道你要查詢的時間間隔,你需要創建另一個表像下面這樣:

CREATE TABLE modified_records (
    timeslot timestamp, 
    updatedtime timestamp, 
    recordid timeuuid, 
    PRIMARY KEY (timeslot, updatedtime) 
); 

現在你可以將「更新的記錄日誌」爲時間段,例如1個小時,並填寫像這樣的表:

INSERT INTO modified_records (timeslot, updatedtime, recordid) VALUES ('2017-02-27 09:00:00', '2017-02-27 09:36:00', 123); 
INSERT INTO modified_records (timeslot, updatedtime, recordid) VALUES ('2017-02-27 09:00:00', '2017-02-27 09:56:00', 456); 
INSERT INTO modified_records (timeslot, updatedtime, recordid) VALUES ('2017-02-27 10:00:00', '2017-02-27 10:00:13', 789); 

其中您使用updatedtime時間戳的一部分作爲分區鍵,例如,在這種情況下,您輪到整數小時。然後,通過僅指定時隙,查詢例如:

SELECT * FROM modified_records WHERE timeslot = '2017-02-27 09:00:00'; 
SELECT * FROM modified_records WHERE timeslot = '2017-02-27 10:00:00'; 

根據你的記錄得到更新的頻率,你可以用較小或較大的時間段,例如每6小時,或每天1次,或每15去分鐘。這個結構非常靈活。你只需要知道你想查詢的時隙。如果您需要跨越多個時隙,則需要執行多個查詢。

+0

爲什麼不是「PRIMARY KEY(時隙)」?據我所知,隨着時間段和更新時間成爲分區鍵的一部分,你的SELECT將無法工作。 – starikoff

+0

@starikoff:它們都是*主鍵*的一部分,但實際上只有'timeslot'是*分區鍵*,'updatedtime'是集羣鍵。 – xmas79

+0

我的不好,自從我看到圍繞分區鍵的關鍵規範沒有明確的括號,這是一段時間,所以我認爲(錯誤地)如果沒有它們,所有部分形成複合分區鍵。 – starikoff