Redis占用内存大小
咱们知道Redis是依据内存的key-value数据库,因为系统的内存大小有限,所以咱们在运用Redis的时分能够装备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 {
//容量
private int capacity;
//当时有多少节点的核算
private int count;
//缓存节点
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<>();
//初始化头节点和尾节点,运用岗兵方法削减判断头结点和尾节点为空的代码
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) {
//先移除一个节点
removeNode();
}
node = new Node<>(key, value);
//添加节点
addNode(node);
} else {
//移动节点到头节点
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) {
//添加节点到头部
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);
//添加节点到头部
addToHead(node);
}
class Node {
k key;
v value;
Node pre;
Node next;
public Node(k key, v value) {
this.key = key;
this.value = value;
}
}
}
上面这段代码结束了一个简略的LUR算法,代码很简略,也加了注释,细心看一下很简略就看懂。
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算法的比照图(图片来历):
Redis内存主动选择
你能够看到图中有三种不同颜色的点:
浅灰色是被选择的数据
灰色是没有被选择掉的老数据
绿色是新参与的数据
咱们能看到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以下设置会报错
共同学习,写下你的评论
评论加载中...
作者其他优质文章