2017-07-25 74 views
0

卡桑德拉新手在這裏。 Cassandra v 3.9。卡桑德拉日期範圍建模

我正在模擬旅客航班簽到數據。

我的主要查詢標準是搜索具有日期範圍(最多7天窗口)的旅客。

以下是我對Cassandra的有限曝光。

create table IF NOT EXISTS travellers_checkin (checkinDay text, checkinTimestamp bigint, travellerName text, travellerPassportNo text, flightNumber text, from text, to text, bookingClass text, PRIMARY KEY (checkinDay, checkinTimestamp)) WITH CLUSTERING ORDER BY (checkinTimestamp DESC) 

每天,我預計高達一百萬條記錄 - 導致分區有一百萬條記錄。

現在我的用戶需要搜索日期窗口是必需的(最大一週窗口)。在這種情況下,我應該使用跨越多個分區的IN子句嗎?這是正確的方式還是應該考慮重新建模數據?或者,我也想知道是否發佈7個查詢(每天)併合並響應將是有效的。

+1

嗯,哦。您將每天將所有簽入放在一個分區上 - 這將成爲羣集中的一個臨時熱點,並且不會很好地擴展。您可以將任何限制放入分區鍵 - 可能是應該預先定義的航班號? – Mandraenke

+0

將您的結果合併到客戶端形成一堆異步較小的查詢將會提供良好的性能,因爲工作將分佈在您的羣集中。 – Mandraenke

+0

我可以將更多字段添加到分區鍵以減少行數。但在最糟糕的情況下,用戶可能只是通過在UI上不提供任何過濾器來進行搜索,這使我回到了原始問題空間。只有日期範圍是默認強制的。每個分區1M是業務預期的。這個數字太大了,無法成爲熱點嗎? – user1189332

回答

2

您的數據模型看起來不錯。但如果您可以添加更多字段到分區鍵,它將很好地擴展。你應該使用executeAsync分離查詢

如果你使用in子句,這意味着你在等待這個單一的協調器節點給你一個響應,它將所有的查詢和它們的響應保存在堆中,如果這些查詢的一個發生故障,或協調失敗,你必須重試整個事情

enter image description here

來源:https://lostechies.com/ryansvihla/2014/09/22/cassandra-query-patterns-not-using-the-in-query-for-multiple-partitions/

而不是使用IN子句中,每天使用的單獨的查詢和執行它與executeAsy NC。

Java示例:

PreparedStatement statement = session.prepare("SELECT * FROM travellers_checkin where checkinDay = ? and checkinTimestamp >= ? and checkinTimestamp <= ?"); 

List<ResultSetFuture> futures = new ArrayList<>(); 
for (int i = 1; i < 4; i++) { 
    ResultSetFuture resultSetFuture = session.executeAsync(statement.bind(i, i)); 
    futures.add(resultSetFuture); 
} 

for (ResultSetFuture future : futures){ 
    ResultSet rows = future.getUninterruptibly(); 
    //You get the result set of each query, merge them here 
}