2011-08-24 30 views
2

我在建造類似延遲線的東西:一個進程RPUSHes對象到列表中,另一個LPOP按照相同的順序排列它們。如何在Redis中實現條件流行併發友好?

訣竅是對象只能在添加後一小時從列表中彈出。我可以用這個時間戳。所有項目的延遲是相同的,永遠不會改變。

現在我該如何以併發友好的方式實現彈出窗口(以便在幾個工作人員訪問該列表時仍能正常工作)?我可以拿出一個項目,檢查時間戳,如果還爲時過早,就把它放回列表中。但是如果有幾個工人同時做這件事,它可能會混淆物品的順序。我可以檢查第一個項目,只有當它到期時纔會彈出。但另一名工作人員可能會彈出它,所以我彈出錯誤的。

我應該使用WATCH命令嗎?怎麼樣?我應該使用排序集而不是列表嗎?幫助讚賞!

回答

1

檢查後將項目放回列表中不會混淆足夠重要的排序 - 通過使用任何類型的併發性,您都會接受訂單不會被嚴格定義。但是,這種方法不會特別有效,因爲如果沒有對項目進行某些處理,您就無法檢查時間戳。

通過腳本編譯,您可以爲排序集實現條件彈出命令,但我不認爲這是最簡單的解決方案。

有一對夫婦的方式使用多個列表來實現基本的調度:

  • 任務添加到有序集合,並有專人負責從有序集合移動它們到一個列表,多工存取一個工人與流行音樂。
  • 每個分鐘都有一個列表,並讓工作人員從過去的列表中讀取。您可以通過使用跟蹤最早的非空隊列的另一個密鑰來最小化檢查的列表數量。
+0

搞砸了訂單在這種情況下,如果到期的物品與尚未到期的物品進行交換,那麼這很重要。在最壞的情況下,它可能會延遲一小時。 但是,每分鐘清單的想法聽起來很有趣。我會更多地考慮這個 – travelboy

+0

的確如此,但是如果你有足夠的物品被加入需要多個工人,那麼最壞的情況是不太可能的。如有必要,您可以使用LRANGE和LPOP的組合來檢查是否有任何到期的項目,然後再刪除一個進行處理。 –

6

我建議使用排序集。條目以標準標識符作爲關鍵字和Unix樣式時間戳作爲分數進入zset。使時間戳成爲每個條目準備好解析之後的日期+時間。工人做一個ZPOP,這不是一個內置的,但可以與模擬:

MULTI 
ZRANGE <key> 0 0 WITHSCORES 
ZREMRANGEBYRANK <key> 0 0 
EXEC 

ZRANGE的結果,你必須與當時的得分最低的元素,已經從集合中移除,以其得分。如果它還沒有生效,請將它歸還ZADD <key> <score> <item>

+0

好主意。它可以處理大量的併發請求嗎?例如:zrange和zremrangebyrank會像事務一樣被執行,而沒有來自它們之間的併發請求的命令,從而導致它返回一個密鑰並刪除另一個密鑰。 –

+1

是的,它會工作。這是MULTI和EXEC的全部目的。他們基本上將命令封裝在一個事務中 –