昨天请假面试,第一个问题就被面试官问道这个问题,面试管是看我这个自己的博客来问里面的一些问题。受宠若惊啊。tips:感谢帅哥给我面试机会。(长城车联网)
Redis提供了5种数据淘汰策略: 

volatile-lru:使用LRU算法进行数据淘汰(淘汰上次使用时间最早的,且使用次数最少的key),只淘汰设定了有效期的key

allkeys-lru:使用LRU算法进行数据淘汰,所有的key都可以被淘汰

volatile-random:随机淘汰数据,只淘汰设定了有效期的key

allkeys-random:随机淘汰数据,所有的key都可以被淘汰

volatile-ttl:淘汰剩余有效期最短的key

最好为Redis指定一种有效的数据淘汰策略以配合maxmemory设置,避免在内存使用满后发生写入失败的情况。

一般来说,推荐使用的策略是volatile-lru,并辨识Redis中保存的数据的重要性。对于那些重要的,绝对不能丢弃的数据(如配置类数据等),应不设置有效期,这样Redis就永远不会淘汰这些数据。对于那些相对不是那么重要的,并且能够热加载的数据(比如缓存最近登录的用户信息,当在Redis中找不到时,程序会去DB中读取),可以设置上有效期,这样在内存不够时Redis就会淘汰这部分数据。

配置方法:

1.在线更新配置 /apps/svr/redis-3.2.0/bin/redis-cli -p 6921 config set maxmemory-policy volatile-lru 
2.修改配置文件 maxmemory-policy volatile-lru   #默认是noeviction,即不进行数据淘汰

我们使用的:

#/apps/svr/redis/bin/redis-cli -p 6921 config get maxmemory-policy

  1. "maxmemory-policy"
  2. "noeviction"

不进行淘汰: noevition: 不会剔除任何数据,拒绝所有写入操作并返回客户端错误信息,此时,Redis只响应读操作

扫描大key:

/apps/svr/redis-3.2.0/bin/redis-cli -h 10.10.10.10 -p 6956 --bigkeys -i 0.1

其实在⼤家熟悉的LinkedHashMap中也实现了Lru算法的,实现如下:

final Map<Long,TimeInfoHolder> timeoutInfoHandlers =
	Collections.synchronizedMap(new HashMap<Long,TimeoutInfoHolder>(100,0.75,true){
	@Override
	protected boolean removeEldstEntry(Map.Entry eldest){
	return size()>100;
}
	
});

当容量超过100时,开始执⾏LRU策略:将最近最少未使⽤的 TimeoutInfoHolder 对象 evict 掉。

Redis的配置淘汰

  1. 找到配置文件,配置 maxmemory 大小(单位字节)
  2. 配置maxmemory-policy 淘汰策略

volatile-lru -> remove the key with an expire set using an LRU algorithm  在所有的key中删除最近最少使用的key

allkeys-lru -> remove any key according to the LRU algorithm 在设置了过期时间的key中删除最近最少使用的key

volatile-random -> remove a random key with an expire set  随机删除设置了过期时间的key

allkeys-random -> remove a random key, any key  在所有的key中随机删除

volatile-ttl -> remove the key with the nearest expire time (minor TTL)  删除设置了过期时间并且最接近过期时间的key

noeviction -> don't expire at all, just return an error on write operations  不删除,直接抛出异常( OOM command not allowed when used memory > 'maxmemory')

image.png