在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 大數(shù)據(jù)/ 使用 Redis 作為 LRU 緩存
使用 Redis 實現(xiàn) Twitter(上)
集群(下)
使用 Redis 實現(xiàn) Twitter(下)
使用 Redis 作為 LRU 緩存
高可用(上)
高可用客戶端指引
集群(中)
高可用(下)
持久化
Redis 介紹
集中插入
集群(上)
從入門到精通(上)
從入門到精通(下)
從入門到精通(中)
分片
數(shù)據(jù)類型初探
復(fù)制

使用 Redis 作為 LRU 緩存

當 Redis 作為緩存使用時,當你添加新的數(shù)據(jù)時,有時候很方便使 Redis 自動回收老的數(shù)據(jù)。這種行為在開發(fā)者社區(qū)中眾所周知,因為這是流行的 memcached 系統(tǒng)的默認行為。

LRU 實際上是被唯一支持的數(shù)據(jù)移除方法。本文內(nèi)容將包含 Redis 的 maxmemory 指令,用于限制內(nèi)存使用到一個固定的容量,也包含深入探討 Redis 使用的 LRU 算法,一個近似準確的 LRU。

maxmemory 配置指令(configuration directive)

maxmemory 配置指令是用來配置 Redis 為數(shù)據(jù)集使用指定的內(nèi)存容量大小??梢允褂?redis.conf 文件來設(shè)置配置指令,或者之后在運行時使用 CONFIG SET 命令。

例如,為了配置內(nèi)存限制為 100MB,可以在 redis.conf 文件中使用以下指令

maxmemory 100mb  

設(shè)置 maxmemory 為 0,表示沒有內(nèi)存限制。這是 64 位系統(tǒng)的默認行為,32 位的系統(tǒng)則使用 3G 大小作為隱式的內(nèi)存限制。

當指定的內(nèi)存容量到達時,需要選擇不同的行為,即策略。Redis 可以只為命令返回錯誤,這樣將占用更多的內(nèi)存,或者每次添加新數(shù)據(jù)時,回收掉一些舊的數(shù)據(jù)以避免內(nèi)存限制。

回收策略(Eviction policies)

當 maxmemory 限制到達的時候,Redis 將采取的準確行為是由 maxmemory-policy 配置指令配置的。

以下策略可用:

  • noeviction:當?shù)竭_內(nèi)存限制時返回錯誤。當客戶端嘗試執(zhí)行命令時會導(dǎo)致更多內(nèi)存占用(大多數(shù)寫命令,除了 DEL 和一些例外)。
  • allkeys-lru:回收最近最少使用(LRU)的鍵,為新數(shù)據(jù)騰出空間。
  • volatile-lru:回收最近最少使用(LRU)的鍵,但是只回收有設(shè)置過期的鍵,為新數(shù)據(jù)騰出空間。
  • allkeys-random:回收隨機的鍵,為新數(shù)據(jù)騰出空間。
  • volatile-random:回收隨機的鍵,但是只回收有設(shè)置過期的鍵,為新數(shù)據(jù)騰出空間。
  • volatile-ttl:回收有設(shè)置過期的鍵,嘗試先回收離 TTL 最短時間的鍵,為新數(shù)據(jù)騰出空間。

當沒有滿足前提條件的話,volatile-lru,volatile-random 和 volatile-ttl 策略就表現(xiàn)得和 noeviction 一樣了。

選擇正確的回收策略是很重要的,取決于你的應(yīng)用程序的訪問模式,但是,你可以在程序運行時重新配置策略,使用 INFO 輸出來監(jiān)控緩存命中和錯過的次數(shù),以調(diào)優(yōu)你的設(shè)置。

一般經(jīng)驗規(guī)則:

  • M 如果你期待你的用戶請求呈現(xiàn)冪律分布(power-law distribution),也就是,你期待一部分子集元素被訪問得遠比其他元素多,可以使用 allkeys-lru 策略。在你不確定時這是一個好的選擇。
  • 如果你是循環(huán)周期的訪問,所有的鍵被連續(xù)掃描,或者你期待請求正常分布(每個元素以相同的概率被訪問),可以使用 allkeys-random 策略。
  • 如果你想能給 Redis 提供建議,通過使用你創(chuàng)建緩存對象的時候設(shè)置的 TTL 值,確定哪些對象應(yīng)該被過期,你可以使用 volatile-ttl 策略。

當你想使用單個實例來實現(xiàn)緩存和持久化一些鍵,allkeys-lru 和 volatile-random 策略會很有用。但是,通常最好是運行兩個 Redis 實例來解決這個問題。

另外值得注意的是,為鍵設(shè)置過期時間需要消耗內(nèi)存,所以使用像 allkeys-lru 這樣的策略會更高效,因為在內(nèi)存壓力下沒有必要為鍵的回收設(shè)置過期時間。

回收過程 (Eviction process)

理解回收的過程是這么運作的非常的重要:

  • 一個客戶端運行一個新命令,添加了新數(shù)據(jù)。
  • Redis 檢查內(nèi)存使用情況,如果大于 maxmemory 限制,根據(jù)策略來回收鍵。
  • 一個新的命令被執(zhí)行,如此等等。

我們通過檢查,然后回收鍵以返回到限制以下,來連續(xù)不斷的穿越內(nèi)存限制的邊界。

如果一個命令導(dǎo)致大量的內(nèi)存被占用 (像一個很大的集合交集保存到一個新的鍵),一會功夫內(nèi)存限制就會被這個明顯的內(nèi)存量所超越。

近似的 LRU 算法(Approximated LRU algorithm)

Redis 的 LRU 算法不是一個精確的實現(xiàn)。這意味著 Redis 不能選擇最佳候選鍵來回收,也就是最久錢被訪問的那些鍵。相反,會嘗試運營一個近似的 LRU 算法,通過采樣一小部分鍵,然后在采樣鍵中回收最適合(擁有最久訪問時間)的那個。

然而,從 Redis3.0(當前還是 beta 版本)開始,算法被改進為持有回收候選鍵的一個池子。這改善了算法的性能,使得更接近于真實的 LRU 算法的行為

Redis 的 LRU 算法有一點很重要,你可以調(diào)整算法的精度,通過改變每次回收時檢查的采樣數(shù)量。這個參數(shù)可以通過如下配置指令:

maxmemory-samples 5  

Redis 沒有使用真實的 LRU 實現(xiàn)的原因,是因為這會消耗更多的內(nèi)存。然而,近似值對使用 Redis 的應(yīng)用來說基本上也是等價的。下面的圖形對比,為 Redis 使用的 LRU 近似值和真實 LRU 之間的比較。

用于測試生成上面圖像的 Redis 服務(wù)被填充了指定數(shù)量的鍵。鍵被從頭訪問到尾,所以第一個鍵是 LRU 算法的最佳候選回收鍵。然后,再新添加 50% 的鍵,強制一般的舊鍵被回收。

你可以從圖中看到三種不同的原點,形成三個不同的帶。

  • 淺灰色帶是被回收的對象
  • 灰色帶是沒有被回收的對象
  • 綠色帶是被添加的對象

在理論的 LRU 實現(xiàn)中,我們期待看到的是,在舊鍵中第一半會過期。而 Redis 的 LRU 算法則只是概率性的過期這些舊鍵。

你可以看到,同樣采用 5 個采樣,Redis 3.0 表現(xiàn)得比 Redis 2.8 要好,Redis 2.8 中最近被訪問的對象之間的對象仍然被保留。在 Redis 3.0 中使用 10 為采樣大小,近似值已經(jīng)非常接近理論性能。

注意,LRU 只是一個預(yù)言指定鍵在未來如何被訪問的模式。另外,如果你的數(shù)據(jù)訪問模式非常接近冪律,大多數(shù)的訪問都將集中在一個集合中,LRU 近似算法將能處理得很好。

在模擬實驗的過程中,我們發(fā)現(xiàn)使用冪律訪問模式,真實的 LRU 算法和 Redis 的近似算法之間的差異非常小,或者根本就沒有。

然而,你可以提高采樣大小到 10,這會消耗額外的 CPU,來更加近似于真實的 LRU 算法,看看這會不會使你的緩存錯失率有差異。

使用 CONFIG SET maxmemory-samples 命令在生產(chǎn)環(huán)境上試驗各種不同的采樣大小值是很簡單的。