久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Redis內存滿了如何解決

211次閱讀
沒有評論

共計 4334 個字符,預計需要花費 11 分鐘才能閱讀完成。

Redis 內存滿了如何解決,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

1、通過配置文件配置

通過在 Redis 安裝目錄下面的 redis.conf 配置文件中添加以下配置設置內存大小。

// 設置 Redis 最大占用內存大小為 100M maxmemory 100mb

redis 的配置文件不一定使用的是安裝目錄下面的 redis.conf 文件,啟動 redis 服務的時候是可以傳一個參數指定 redis 的配置文件的。

2、通過命令修改

Redis 支持運行時通過命令動態修改內存大小

// 設置 Redis 最大占用內存大小為 100M 127.0.0.1:6379  config set maxmemory 100mb // 獲取設置的 Redis 能使用的最大內存大小  127.0.0.1:6379  config get maxmemory

如果不設置最大內存大小或者設置最大內存大小為 0,在 64 位操作系統下不限制內存大小,在 32 位操作系統下最多使用 3GB 內存

Redis 的內存淘汰

既然可以設置 Redis 最大占用內存大小,那么配置的內存就有用完的時候。那在內存用完的時候,還繼續往 Redis 里面添加數據不就沒內存可用了嗎?

實際上 Redis 定義了幾種策略用來處理這種情況:

 noeviction(默認策略):對于寫請求不再提供服務,直接返回錯誤(DEL 請求和部分特殊請求除外)

 allkeys-lru:從所有 key 中使用 LRU 算法進行淘汰

 volatile-lru:從設置了過期時間的 key 中使用 LRU 算法進行淘汰

 allkeys-random:從所有 key 中隨機淘汰數據

 volatile-random:從設置了過期時間的 key 中隨機淘汰

 volatile-ttl:在設置了過期時間的 key 中,根據 key 的過期時間進行淘汰,越早過期的越優先被淘汰

當使用 volatile-lru、volatile-random、volatile-ttl 這三種策略時,如果沒有 key 可以被淘汰,則和 noeviction 一樣返回錯誤。

如何獲取及設置內存淘汰策略

獲取當前內存淘汰策略:

127.0.0.1:6379  config get maxmemory-policy

通過配置文件設置淘汰策略(修改 redis.conf 文件):

maxmemory-policy allkeys-lru

通過命令修改淘汰策略:

127.0.0.1:6379  config set maxmemory-policy allkeys-lru

LRU 算法

什么是 LRU?

上面說到了 Redis 可使用最大內存使用完了,是可以使用 LRU 算法進行內存淘汰的,那么什么是 LRU 算法呢?

LRU(Least Recently Used),即最近最少使用,是一種緩存置換算法。在使用內存作為緩存的時候,緩存的大小一般是固定的。當緩存被占滿,這個時候繼續往緩存里面添加數據,就需要淘汰一部分老的數據,釋放內存空間用來存儲新的數據。

這個時候就可以使用 LRU 算法了。其核心思想是:如果一個數據在最近一段時間沒有被用到,那么將來被使用到的可能性也很小,所以就可以被淘汰掉。

使用 java 實現一個簡單的 LRU 算法。

public class LRUCache k, v  { // 容量  private int capacity; // 當前有多少節點的統計  private int count; // 緩存節點  private Map k, Node k, v  nodeMap; private Node k, v  head; private Node k, v  tail; public LRUCache(int capacity) { if (capacity   1) { throw new IllegalArgumentException(String.valueOf(capacity)); } this.capacity = capacity; this.nodeMap = new HashMap (); // 初始化頭節點和尾節點,利用哨兵模式減少判斷頭結點和尾節點為空的代碼  Node headNode = new Node(null, null); Node tailNode = new Node(null, null); headNode.next = tailNode; tailNode.pre = headNode; this.head = headNode; this.tail = tailNode; } public void put(k key, v value) { Node k, v  node = nodeMap.get(key); if (node == null) { if (count  = capacity) { // 先移除一個節點  removeNode(); } node = new Node (key, value); // 添加節點  addNode(node); } else { // 移動節點到頭節點  moveNodeToHead(node); } } public Node k, v  get(k key) { Node k, v  node = nodeMap.get(key); if (node != null) { moveNodeToHead(node); } return node; } private void removeNode() { Node node = tail.pre; // 從鏈表里面移除  removeFromList(node); nodeMap.remove(node.key); count--; } private void removeFromList(Node k, v  node) { Node pre = node.pre; Node next = node.next; pre.next = next; next.pre = pre; node.next = null; node.pre = null; } private void addNode(Node k, v  node) { // 添加節點到頭部  addToHead(node); nodeMap.put(node.key, node); count++; } private void addToHead(Node k, v  node) { Node next = head.next; next.pre = node; node.next = next; node.pre = head; head.next = node; } public void moveNodeToHead(Node k, v  node) { // 從鏈表里面移除  removeFromList(node); // 添加節點到頭部  addToHead(node); } class Node k, v  { k key; v value; Node pre; Node next; public Node(k key, v value) { this.key = key; this.value = value; } } }

上面這段代碼實現了一個簡單的 LUR 算法,代碼很簡單,也加了注釋,仔細看一下很容易就看懂。常用緩存淘汰算法(LFU、LRU、ARC、FIFO、MRU),這篇了解下。

LRU 在 Redis 中的實現

近似 LRU 算法

Redis 使用的是近似 LRU 算法,它跟常規的 LRU 算法還不太一樣。近似 LRU 算法通過隨機采樣法淘汰數據,每次隨機出 5(默認)個 key,從里面淘汰掉最近最少使用的 key。

可以通過 maxmemory-samples 參數修改采樣數量:

例:maxmemory-samples 10

maxmenory-samples 配置的越大,淘汰的結果越接近于嚴格的 LRU 算法

Redis 為了實現近似 LRU 算法,給每個 key 增加了一個額外增加了一個 24bit 的字段,用來存儲該 key 最后一次被訪問的時間。

Redis3.0 對近似 LRU 的優化

Redis3.0 對近似 LRU 算法進行了一些優化。新算法會維護一個候選池(大小為 16),池中的數據根據訪問時間進行排序,第一次隨機選取的 key 都會放入池中,隨后每次隨機選取的 key 只有在訪問時間小于池中最小的時間才會放入池中,直到候選池被放滿。當放滿后,如果有新的 key 需要放入,則將池中最后訪問時間最大(最近被訪問)的移除。

當需要淘汰的時候,則直接從池中選取最近訪問時間最小(最久沒被訪問)的 key 淘汰掉就行。

LRU 算法的對比

我們可以通過一個實驗對比各 LRU 算法的準確率,先往 Redis 里面添加一定數量的數據 n,使 Redis 可用內存用完,再往 Redis 里面添加 n / 2 的新數據,這個時候就需要淘汰掉一部分的數據,如果按照嚴格的 LRU 算法,應該淘汰掉的是最先加入的 n / 2 的數據。

生成如下各 LRU 算法的對比圖

圖片來源:segmentfault.com/a/1190000017555834

你可以看到圖中有三種不同顏色的點:

  淺灰色是被淘汰的數據

  灰色是沒有被淘汰掉的老數據

  綠色是新加入的數據

我們能看到 Redis3.0 采樣數是 10 生成的圖最接近于嚴格的 LRU。而同樣使用 5 個采樣數,Redis3.0 也要優于 Redis2.8。

LFU 算法

LFU 算法是 Redis4.0 里面新加的一種淘汰策略。它的全稱是 Least Frequently Used,它的核心思想是根據 key 的最近被訪問的頻率進行淘汰,很少被訪問的優先被淘汰,被訪問的多的則被留下來。

LFU 算法能更好的表示一個 key 被訪問的熱度。假如你使用的是 LRU 算法,一個 key 很久沒有被訪問到,只剛剛是偶爾被訪問了一次,那么它就被認為是熱點數據,不會被淘汰,而有些 key 將來是很有可能被訪問到的則被淘汰了。如果使用 LFU 算法則不會出現這種情況,因為使用一次并不會使一個 key 成為熱點數據。

LFU 一共有兩種策略:

 volatile-lfu:在設置了過期時間的 key 中使用 LFU 算法淘汰 key

 allkeys-lfu:在所有的 key 中使用 LFU 算法淘汰數據

設置使用這兩種淘汰策略跟前面講的一樣,不過要注意的一點是這兩周策略只能在 Redis4.0 及以上設置,如果在 Redis4.0 以下設置會報錯。

關于 Redis 內存滿了如何解決問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注丸趣 TV 行業資訊頻道了解更多相關知識。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-03發表,共計4334字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 扶风县| 紫金县| 莒南县| 九龙县| 抚顺县| 淄博市| 乌拉特前旗| 观塘区| 荥阳市| 平谷区| 平武县| 景洪市| 晋江市| 上虞市| 镇坪县| 永兴县| 云浮市| 花垣县| 全南县| 茌平县| 贞丰县| 西昌市| 鹤岗市| 台南县| 江山市| 贡嘎县| 南充市| 龙泉市| 新余市| 合作市| 嫩江县| 金湖县| 江山市| 南皮县| 通州区| 临武县| 长垣县| 平原县| 荆州市| 沂源县| 舟曲县|