Redis数据库内存满了,会不会崩溃?答案是:不会满。在使用Redis的时候,我们需要配置Redis可以使用的最大内存大小,存储到一定的容量。有时候还有Redis的内存淘汰策略,淘汰的LRU算法等等。..一起来讨论一下,Redis的内存淘汰策略。Redis占用内存大小我们知道Redis是一个基于内存的key-value数据库,因为系统内存大小是有限的,所以我们在使用Redis的时候可以配置Redis可以使用的最大内存大小。1、通过配置文件进行配置。在Redis安装目录下的redis.conf配置文件中添加如下配置设置内存大小conf文件,启动redis服务时,可以传一个参数指定redis的配置文件2.通过命令修改Redis,支持运行时通过命令动态修改内存大小//设置Redis的最大内存大小为100M`127.0.0.1:6379>configsetmaxmemory100mb`//获取Redis可以使用的最大内存大小`127.0.0.1:6379>configgetmaxmemory`如果不设置最大内存大小或者设置最大内存大小为0,它运行在64位系统下,内存大小没有限制,32位操作系统下最大可以使用3GB内存。Redis内存淘汰由于Redis占用的最大内存大小是可以设置的,所以配置的内存用完了就会用完。那么当内存耗尽的时候,如果继续向Redis中添加数据,不就没有可用的内存了吗?其实Redis定义了几种策略来处理这种情况:noeviction(默认策略):不再为写请求提供服务,直接返回错误(DEL请求和一些特殊请求除外)allkeys-lru:使用LRU算法进行对所有key进行淘汰volatile-lru:使用LRU算法对有过期时间的key进行淘汰allkeys-random:对所有key使用LRU算法进行淘汰随机淘汰key中的数据volatile-random:对具有expirationtimesetvolatile-ttl:在设置了过期时间的key中,根据key的过期时间进行淘汰,过期时间越早的,在使用volatile-lru的三种策略时优先淘汰,volatile-random和volatile-ttl,如果没有key可以淘汰,会报错类似noeviction-policy通过配置文件设置淘汰策略(修改redis.conffile):maxmemory-policyallkeys-lru通过命令修改淘汰策略:127.0.0.1:6379>configsetmaxmemory-policyallkeys-lru`LRU算法什么是LRU?上面提到的Redis可以在最大内存用完的时候,使用LRU算法进行内存淘汰,那么什么是LRU算法呢?LRU(LeastRecentlyUsed),即最近最少使用,是一种缓存替换算法。当使用内存作为缓存时,缓存的大小一般是固定的。当缓存满了,此时如果继续向缓存中添加数据,就需要剔除一些旧的数据,释放内存空间来存放新的数据。这时候就可以使用LRU算法了。其核心思想是:如果一条数据在最近一段时间内没有被使用,那么以后被使用的可能性很小,所以可以淘汰。Redis中LRU的实现近似LRU算法Redis使用近似LRU算法,与常规的LRU算法不同。近似LRU算法通过随机抽样的方式淘汰数据,每次随机选择5个(默认)key,从中淘汰最近最少使用的key。可以通过maxmemory-samples参数修改样本个数:例子:maxmemory-samples10maxmemory-samples配置越大,淘汰的结果越接近严格LRU算法。Redis为了实现近似LRU算法,对每个key进行了额外的增加。一个24位的字段用于存储最后一次访问密钥的时间。Redis3.0优化了近似LRURedis3.0优化了近似LRU算法。新算法会维护一个候选池(大小为16),池中的数据按照访问时间排序,第一次随机选择的key放入池中,每次随机选择的key只会当访问时间小于池中被选中的最小时间时,将被放入池中,直到候选池被填满。当满的时候,如果有新的key需要放入,则移除pool中最后访问时间最大的(最近访问过的)。当需要淘汰时,只需从池中选择最近访问时间最小(未访问时间最长)的key淘汰即可。LRU算法的比较我们可以通过一个实验来比较各个LRU算法的准确率。先向Redis中添加一定数量的数据n,使Redis的可用内存耗尽,然后向Redis中添加n/2个新数据。这时候,需要剔除一部分数据。按照严格的LRU算法,应该先加入的n/2条数据应该被淘汰掉。生成如下各个LRU算法的对比图,可以看到图中有三个不同颜色的点:浅灰色是被淘汰的数据,灰色是没有被淘汰的旧数据,绿色是新加入的数据。我们可以看到Redis3.0的采样数为10产生了一个最接近严格LRU的图。而且同样使用5个样本,Redis3.0比Redis2.8好。LFU算法LFU算法是Redis4.0中新增的淘汰策略。它的全称是LeastFrequentlyUsed,其核心思想是根据key最近的访问频率来淘汰key。那些很少被访问的先被淘汰,那些被访问较多的被保留。LFU算法可以更好地表示被访问的密钥的流行度。如果你用的是LRU算法,一个key很长时间没有被访问过,只是偶尔访问过一次,那么它就被认为是热点数据,不会被淘汰,有些key很可能会在一段时间内被访问到未来被淘汰。如果使用LFU算法就不会出现这种情况,因为使用一次不会使一个键成为热数据。LFU有两种策略:volatile-lfu:使用LFU算法淘汰keys中有过期时间的keysallkeys-lfu:使用LFU算法淘汰所有keys中的数据设置使用这两种淘汰策略如上所述,但是,需要注意的是两周政策只能在Redis4.0及以上设置。如果设置在Redis4.0以下,会报错,最后会有一个小问题。可能有人注意到文章没有解释为什么Redis使用ApproximateLRU算法而不使用exactLRU算法,可以一起讨论学习。
