redis 需要设置最大占用内存,最大占用内存一般不超过物理机内存的3/4;防止out of max memory。
配置位置:redis.conf
设置maxmemory参数,maxmemory是bytes字节类型,注意转换。修改如下所示:
Redis使用超过设置的最大值
打开debug模式下的页面,提示错误:OOM command not allowed when used memory > ‘maxmemory’.
可以通过设置LRU算法来删除部分key,释放空间。默认是按照过期时间的,如果set时候没有加上过期时间就会导致数据写满maxmemory。
如果不设置maxmemory或者设置为0,64位系统不限制内存,32位系统最多使用3GB内存。
如果设置了maxmemory,一般都要设置过期策略。打开Redis的配置文件有如下描述,Redis有八种过期策略(之前5种):
# volatile-lru -> Evict using approximated LRU among the keys with an expire set. 从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。 # allkeys-lru -> Evict any key using approximated LRU. # volatile-lfu -> Evict using approximated LFU among the keys with an expire set. 从已设置过期时间的数据集挑选使用频率最低的数据淘汰。 # allkeys-lfu -> Evict any key using approximated LFU. 从数据集中挑选使用频率最低的数据淘汰。 # volatile-random -> Remove a random key among the ones with an expire set. 从已设置过期时间的数据集中任意选择数据淘汰。 # allkeys-random -> Remove a random key, any key. 从数据集(server.db[i].dict)中任意选择数据淘汰 # volatile-ttl -> Remove the key with the nearest expire time (minor TTL). 已设置过期时间的数据集中挑选将要过期的数据淘汰。
# noeviction -> Don't evict anything, just return an error on write operations.(驱逐)禁止驱逐数据,这也是默认策略。意思是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失。
这八种大体上可以分为4中,lru、lfu、random、ttl。
二、淘汰机制的实现
定期删除(积极方法)
redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的 key。
Redis 默认会每秒进行十次过期扫描(100ms一次),过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。
1.从过期字典中随机 20 个 key;
2.删除这 20 个 key 中已经过期的 key;
3.如果过期的 key 比率超过 1/4,那就重复步骤 1;
redis默认是每隔 100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载。
惰性删除(消极方法)
所谓惰性策略就是在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。
定期删除可能会导致很多过期key到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期 key,靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓的惰性删除,即当你主动去查过期的key时,如果发现key过期了,就立即进行删除,不返回任何东西.