2012-11-10 92 views
1

我使用一個存儲桶來存儲消息列表,使用UUID作爲鍵和json消息作爲值。這工作正常。在不知道密鑰的情況下從存儲桶中獲取對象

我需要的是一種有效的方式得到桶一個消息不知道它的關鍵,在這兩種情況中的至少一方:

  1. 獲得最後插入的對象(這是我的首選方法)。
  2. 從桶中獲取一個隨機對象(如果第一個替代方法不可行)。

是否有任何有效的方法來實現呢?

我認爲一個替代方案可能是檢索存儲桶中的密鑰,然後獲取第一個。但是這意味着做兩次調用riak,一次獲得所有的關鍵字(僅丟棄一個關鍵字),另一個獲取對象。看起來效率不高。

回答

2

由於Riak是一個鍵值存儲,所以檢索數據的最有效方式是通過鍵。列出或檢索存儲桶中的所有密鑰(即使最終只使用首先返回的密鑰)是可以執行的最低效率操作之一,因爲它會導致Riak掃描系統中的所有密鑰(而不僅僅是存儲桶),並且通常建議不要在生產系統上使用它。

獲取最後插入對象的最有效方法可能是將ID存儲在不同存儲桶中單獨的已知記錄中。但是,這會要求您在每次插入時執行兩次寫入操作,對於每次讀取操作都要執行兩次讀取操作,但會以最有效的方式執行操作。您可能可能在包含消息的存儲桶中實現一個提交後掛鉤(必須在Erlang中,因爲目前不能使用JavaScript函數編寫記錄)以使系統爲您執行更新,這將刪除需要上次寫入。

如果向包含消息的存儲區寫入大量數據,則可能需要調整單獨的存儲區,以便它不允許多個值,並且最後一個值獲勝。通過這種方式,您可以降低由於系統中頻繁更新此單個記錄而導致創建大量兄弟姐妹的風險。這總是會給你最後一次寫入記錄,但不一定是最後一次寫入記錄(尤其是如果你經常向數據庫寫消息的話),因爲Riak不支持任何類型的原子性,並且是最終一致的數據庫。

如果您使用leveldb後端,您也可以創建一個或多個二級索引,並使用它將掃描限制爲僅限於最近的記錄,這比掃描所有的鍵更有效。然後,您可以選擇最近的密鑰或通過mapreduce選擇一個隨機密鑰,但這會比之前描述的方法效率低得多。

我想不出任何有效的方法來從Riak中檢索一個桶中的隨機記錄,除非你知道你所插入的鍵的範圍,並且可以在客戶端隨機決定哪一個得到。一種方法是按順序生成所有密鑰,而不是使用UUID,但在高度併發的分佈式系統中這當然不是一個好主意。

+0

謝謝。我將你的答案標記爲接受,因爲這是一個很好的解釋,說明爲什麼riak不是用作隊列的最佳工具,或者一般來說,用未知鍵的對象進行操作。 –

0

一號的任務是很容易實現:

  • 添加post-commit hook將最後插入鑰匙寫一些預先定義的鍵/桶的地方
  • 獲取從預定義的鍵/桶的關鍵,併發出GET使用它們的查詢

它仍然是兩個操作,但都只是得到快速。再加上額外的開銷,但也沒有太重。

第二個方案也很容易,但它是太低效而不能實際應用:

  • 獲取所有鍵(極其昂貴的操作)
  • 選擇隨機
  • 問題得到
+0

謝謝伊萬。第一個任務不是那麼容易,因爲當最後一個插入的鍵被恢復時,我必須刪除這個對象,並且一個新的鍵應該佔據它的位置,作爲「新的最後插入的鍵」。我打算使用這個桶或多或少像一個隊列。 –

0

我已經想出了相同的場景。在我的場景中,我必須保存用戶。爲此我需要一個自動增量Id。所以我做的是,我把最後一個插入的鍵放在一個單獨的桶中,​​就像「Christian Dahlqvist」所提到的那樣,每次我想插入新記錄時,都會從該關鍵桶中獲取最後一個插入的鍵。在這裏,我們只有一個關鍵值爲「LastKey」的值,這個值總是爲我們所知。我基於提取的密鑰增加了密鑰,並再次更新密鑰桶。因此,密鑰桶總是包含最新的密鑰。

相關問題