2017-04-15 11 views
1

左右的時間內每個元素最新的入門,我有一個卡桑德拉CQL聲明,看起來像這樣:卡桑德拉獲得包含在條款

SELECT * FROM DATA WHERE APPLICATION_ID = ? AND PARTNER_ID = ? AND LOCATION_ID = ? AND DEVICE_ID = ? AND DATA_SCHEMA = ? 

此表由一個時間戳列進行排序。

該功能由REST API控制,並且可以指定其中一個篩選參數以獲取最近的行,然後在CQL語句的末尾添加「LIMIT 1」,因爲它是由時間戳列按降序排列。我想要做的是讓他們指定多個設備ID來獲取最新的條目。所以,我的問題是,有沒有辦法做這樣的事情在卡桑德拉:

SELECT * FROM DATA WHERE APPLICATION_ID = ? AND PARTNER_ID = ? AND LOCATION_ID = ? AND DEVICE_ID IN ? AND DATA_SCHEMA = ? 

,仍然使用類似「LIMIT 1」只拿回了最新的行中每一個設備ID?或者,我是否只需要爲每個設備執行一個單獨的CQL語句就可以獲得每個設備的最新行?

FWIW,該表的複合鍵是這樣的:當有很多的它和它使請求數到多個分區反正引擎蓋下的參數,不建議

PRIMARY KEY ((application_id, partner_id, location_id, device_id, data_schema), activity_timestamp) 
) WITH CLUSTERING ORDER BY (activity_timestamp DESC); 

回答

1

IN,它的投入協調節點上的壓力。

不是你不能做到這一點。這是完全合法的,但大多數時候它不是高性能的,也沒有建議。如果你指定限制,那就是整個語句,基本上你不能從分區中選擇第一項。最簡單的選擇是向集羣發出多個查詢(IN中的每個元素都將成爲一個查詢),並將limit 1放在每個元素上。

說實話,這是我在很多項目中的解決方案,它工作得很好。基本上協調員將引擎蓋下到多個節點無論如何也必須工作更適合你來你的所有要求,可能會遇到超時等

總之它遠遠更好地爲集羣和更好的性能如果客戶多次詢問(使用多個協調員,請求較小),而不是讓單個協調員對所有工作進行檢查。

這是在所有情況下,你不能承受更多的磁盤空間,爲您集羣

平時卡桑德拉解決方案

數據在Cassandra是建議以備查詢(查詢第一)。所以基本上你必須有一個額外的表,它們會擁有與現在相同的分區鍵,並且你將不得不放棄集羣列activity_timestamp。即

PRIMARY KEY ((application_id, partner_id, location_id, device_id, data_schema)) 

double (())是故意的。

每當你寫信給你的表時,你也會寫數據到latest_entry(表沒有activity_timestamp)然後你可以指定你需要的查詢,這個表包含最新的條目,所以你不必使用限制1,因爲每個分區鍵只有一個條目......這將是cassandra中的常用解決方案。

如果你害怕額外的寫入,不要擔心,它們是廉價的和cpu綁定。隨着卡桑德拉它總是「帶來的寫」我猜:)

基本上它是由你:

  1. 多個查詢 - 有點重構的,沒有額外的空間成本
  2. 新模式 - 額外的刀片當寫入時,額外的空間成本
+0

謝謝領域!這幾乎是我想的,但我對Cassandra來說還是個新手,所以只是想確保我沒有錯過任何東西。我已經對另外一個跟蹤其他東西的表進行了額外的寫入操作,所以如果只有一個只記錄最新條目的表,可能不會有什麼大不了的。我認爲這將有助於提高性能,而且性能肯定比它將消耗的一點點空間更重要:) – cloudwalker

+0

好吧,那麼你們都很好;那麼這個項目看起來非常有趣:)哦,什麼是頻率與設備寫入。考慮使用bucketing,如果它是更經常寫的東西,讓我們說每隔幾秒鐘或更多時間我可以給出一些建議;)只是說頻率 –

+0

我必須看看 - 我沒有聽說過bucketing。寫入頻率當前每個「容器」每5秒鐘一次,並且容器的數量有望繼續快速增長,因此每5秒會有x次寫入,這可能是一大堆。 – cloudwalker

1

您的表定義不適合IN子句的這種用法。事實上,它支持主密鑰的最後一個字段或聚類密鑰的最後一個字段。所以,你可以:

  • 交換你的最後兩個主鍵
  • 使用一個查詢的每個設備ID