【93期】經(jīng)典面試題:Redis 內(nèi)存滿了怎么辦?
閱讀本文大概需要 6 分鐘。
來自:juejin.im/post/5d674ac2e51d4557ca7fdd70
Redis占用內(nèi)存大小
1、通過配置文件配置
//設(shè)置Redis最大占用內(nèi)存大小為100M
maxmemory?100mb
2、通過命令修改
//設(shè)置Redis最大占用內(nèi)存大小為100M
127.0.0.1:6379>?config?set?maxmemory?100mb
//獲取設(shè)置的Redis能使用的最大內(nèi)存大小
127.0.0.1:6379>?config?get?maxmemory
Redis的內(nèi)存淘汰
noeviction(默認策略):對于寫請求不再提供服務(wù),直接返回錯誤(DEL請求和部分特殊請求除外)
allkeys-lru:從所有key中使用LRU算法進行淘汰
volatile-lru:從設(shè)置了過期時間的key中使用LRU算法進行淘汰
allkeys-random:從所有key中隨機淘汰數(shù)據(jù)
volatile-random:從設(shè)置了過期時間的key中隨機淘汰
volatile-ttl:在設(shè)置了過期時間的key中,根據(jù)key的過期時間進行淘汰,越早過期的越優(yōu)先被淘汰
如何獲取及設(shè)置內(nèi)存淘汰策略
127.0.0.1:6379>?config?get?maxmemory-policy
maxmemory-policy?allkeys-lru
127.0.0.1:6379>?config?set?maxmemory-policy?allkeys-lru
LRU算法
什么是LRU?
public?class?LRUCache<k,?v>?{
????//容量
????private?int?capacity;
????//當(dāng)前有多少節(jié)點的統(tǒng)計
????private?int?count;
????//緩存節(jié)點
????private?Map>?nodeMap;
????private?Node?head;
????private?Node?tail;
????public?LRUCache(int?capacity)?{
????????if?(capacity?1)?{
????????????throw?new?IllegalArgumentException(String.valueOf(capacity));
????????}
????????this.capacity?=?capacity;
????????this.nodeMap?=?new?HashMap<>();
????????//初始化頭節(jié)點和尾節(jié)點,利用哨兵模式減少判斷頭結(jié)點和尾節(jié)點為空的代碼
????????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?node?=?nodeMap.get(key);
????????if?(node?==?null)?{
????????????if?(count?>=?capacity)?{
????????????????//先移除一個節(jié)點
????????????????removeNode();
????????????}
????????????node?=?new?Node<>(key,?value);
????????????//添加節(jié)點
????????????addNode(node);
????????}?else?{
????????????//移動節(jié)點到頭節(jié)點
????????????moveNodeToHead(node);
????????}
????}
????public?Node?get(k?key)? {
????????Node?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?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?node) ?{
????????//添加節(jié)點到頭部
????????addToHead(node);
????????nodeMap.put(node.key,?node);
????????count++;
????}
????private?void?addToHead(Node?node) ?{
????????Node?next?=?head.next;
????????next.pre?=?node;
????????node.next?=?next;
????????node.pre?=?head;
????????head.next?=?node;
????}
????public?void?moveNodeToHead(Node?node) ?{
????????//從鏈表里面移除
????????removeFromList(node);
????????//添加節(jié)點到頭部
????????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;
????????}
????}
}
LRU在Redis中的實現(xiàn)
近似LRU算法
maxmemory-samples 10Redis3.0對近似LRU的優(yōu)化
LRU算法的對比

淺灰色是被淘汰的數(shù)據(jù)
灰色是沒有被淘汰掉的老數(shù)據(jù)
綠色是新加入的數(shù)據(jù)
LFU算法
volatile-lfu:在設(shè)置了過期時間的key中使用LFU算法淘汰key
allkeys-lfu:在所有的key中使用LFU算法淘汰數(shù)據(jù)
問題
推薦閱讀:
【92期】面試官:你說你精通Java并發(fā),那給我講講J.U.C吧
【91期】面試官:Spring 用了哪些設(shè)計模式?說三種即可
【90期】面試官:說一下使用 Redis 實現(xiàn)大規(guī)模的帖子瀏覽計數(shù)的思路
微信掃描二維碼,關(guān)注我的公眾號
朕已閱?
評論
圖片
表情

