2012-04-06 154 views
3

如果redis獲取超載,我可以配置它以放棄設置請求嗎?我有一個應用程序,實時更新大量項目的數據(每個項目每秒10-15次)。這些值很快就過時了,我不需要任何形式的一致性。當redis重載時會發生什麼?

我也想計算實時寫入的值的並行總和。這裏最好的選擇是什麼? LUA在redis中執行?使用UNIX套接字與redis位於同一個盒子中的小應用程序?

回答

1

當Redis變得過載時,它只會減慢其客戶端速度。對於大多數命令,協議本身是同步的。

儘管Redis支持流水線,但客戶端無法取消仍在流水線中的流量,但尚未被服務器確認。 Redis本身並不真正排隊傳入的流量,TCP堆棧就是這樣做的。

因此,無法配置Redis服務器以放棄設置的請求。但是,它可以實現對客戶端的最後一個值隊列:

  • 隊列實際上是一個由2張地圖由您的項目(每個項目只存儲一個值)索引表示。主要地圖將被應用程序使用。輔映射將被特定的線程使用。 2個地圖內容可以以原子方式交換。

  • 當主映射爲空時,特定線程將被阻塞。如果不是,則交換兩個映射的內容,使用主動流水線和可變參數命令將輔助映射的內容異步發送到Redis。它也收到Redis的確認。

  • 當線程與輔助地圖一起工作時,應用程序仍然可以填充主地圖。如果Redis速度太慢,應用程序將只會累積主映射中的最後一個值。

這個策略可以在C中用hiredis和你選擇的事件循環來實現。

然而,這不是微不足道的實施,所以我會首先檢查Redis對全部的性能是否不足以達到我的目的。這些日子裏Redis以超過500K的操作系統(使用單核)進行基準測試並不罕見。如果需要,沒有什麼能阻止你在多個Redis實例上分割你的數據。

您可能會在Redis服務器的CPU之前飽和網絡鏈接。這就是爲什麼最好在客戶端而不是服務器端實現最後一個值隊列(如果需要的話)。

關於總和計算,我會盡量計算和實時維護它。例如,GETSET命令可用於在返回前一個值時設置新值。

而不是隻需設置你的價值觀,你可以這樣做:

[old value] = GETSET item <new value> 
INCRBY mysum [new value] - [old value] 

的mysum鍵將包含值的總和在任何時候的所有項目。使用Redis 2.6,您可以使用Lua來安裝此計算以節省往返時間。

運行一個大批量計算現有數據的統計數據(這是我理解你的「並行」總和)並不真的適合Redis。它不是爲計算映射/減少而設計的。

+0

是的,它不是我擔心的CPU,而是網絡鏈接。我將在雲託管環境中運行這個應用程序,銷售代表告訴我他們的雲實例只有100MB/s,這似乎可憐。 – jz87 2012-04-07 02:41:57

+0

對於同步協議,我認爲客戶端的最後一個值隊列是您建議的最佳選項。我擔心這個協議會是異步的,在這種情況下這會更困難。 – jz87 2012-04-07 02:43:32

相關問題