2013-12-11 52 views
6

我在一個Java應用程序中使用Redis,在這裏我正在讀取日誌文件,在Redis中爲每個日誌存儲/檢索一些信息。密鑰是我的日誌文件中的IP地址,這意味着它們始終是新聞密鑰,即使它們經常出現也是如此。Redis充滿並驅逐密鑰時,速度有多慢? (LRU算法)

在某些時候,Redis達到其最大內存大小(在我的情況下爲3GB),並開始驅逐一些密鑰。我使用「allkeys-lru」設置,因爲我想保留最新的按鍵。

整個應用程序然後減慢了很多,採取比開始時延長了5倍。 所以我有三個問題:

  • 有這樣一個戲劇性的放緩(5倍長)是正常嗎?有人經歷過這種放緩嗎?如果沒有,我可能會在我的代碼中出現另一個問題(不太可能,因爲在Redis達到極限時出現減速)
  • 我可以改進我的配置嗎?我試圖改變maxmemory-samples設置沒有太大的成功
  • 我應該考慮替代我的特定問題嗎?有沒有一個內存數據庫可以處理更好的性能的驅逐鍵?我可能會考慮純Java對象(HashMap ...),即使它看起來不是一個好的設計。

編輯1: 我們使用2個DBS在Redis的

編輯2: 我們使用Redis的2.2.12(Ubuntu的12.04 LTS)。進一步的調查解釋了這個問題:我們在redis中使用db0和db1。 db1的使用遠少於db0,而且鍵完全不同。當Redis達到最大內存(並且LRU算法開始逐出密鑰)時,redis確實會刪除幾乎所有的db1密鑰,這會顯着降低所有調用的速度。這是一種奇怪的行爲,可能不尋常,也可能與我們的應用程序有關。我們通過轉移到另一個(更好的)內存機制來解決db1中加載的密鑰問題。

的感謝!

回答

8

我不相信Redis是您的用例的最佳選擇。

Redis「LRU」只是一個盡力而爲的算法(即距離精確的LRU很遠)。 Redis跟蹤內存分配並知道何時需要釋放內存。在執行每個命令之前檢查它。在allkeys-lru模式下驅逐密鑰的機制在於選擇maxmemory-samples隨機密鑰,比較它們的空閒時間,並選擇最空閒的密鑰。 Redis重複這些操作,直到使用的內存低於maxmemory。

maxmemory-samples越高,CPU消耗越多,但結果更準確。

如果您沒有明確使用EXPIRE命令,則沒有其他開銷與關鍵驅逐相關聯。

的吞吐量運行在我的機器結果的快速測試與Redis的風向標:

  • 145芭斯/秒時,沒有驅逐發生
  • 125芭斯時50%驅逐發生/秒(即1個關鍵超過2被驅逐)。

我無法重現您經歷過的5倍因素。

減少驅逐開銷的明顯建議是減少maxmemory-samples,但這也意味着準確性的急劇下降。

我的建議是試試memcached。 LRU機制是不同的。它仍然不準確(它僅適用於每個平板),但它可能會給這個用例上的Redis更好的結果。

+0

感謝德羅巴。我們仍在調查這個問題,但似乎還有其他事情導致這種放緩。我們實際上在redis中使用了2個DB,並且在達到最大內存時似乎有一種奇怪的行爲。我們會在發佈後發佈更多細節。我會等待其他可能的答案並驗證您的回覆。 – Pixou

+0

@Pixou,這方面的更新? – Ashish

+3

@Ashish通常,我們發現LRU機制可以在兩個數據庫上工作,這樣一來,如果你有一個大型數據庫和一個小型數據庫,那麼小型數據庫很快就會被LRU「吸」。例如,當mamemory-sample爲3時,LRU似乎從大型DB中獲得2個樣本,而從小型DBU中獲得1個樣本,即使它小了10000倍。再次,我們通過在redis實例中只有一個數據庫來解決這個問題。 – Pixou

0

您使用的是哪個版本的Redis? 2.8版本(相當新的)改進了到期算法,如果你使用的是2.6,你可以嘗試一下。

http://download.redis.io/redis-stable/00-RELEASENOTES

+0

這是非常真實的,但請注意關鍵到期和驅逐是兩回事。 –

+0

你完全正確 –