Redis作为最常用的开源内存数据库,性能非常高。根据官方数据,Redis的读取速度为11万次/s,写入速度为81000次/s。而且Redis支持数据持久化、多种数据结构存储、主从模式数据备份等功能。但是如果长期使用Redis作为缓存,难免会遇到内存空间存储瓶颈。当Redis内存超过物理内存限制时,内存数据会频繁与磁盘交换,导致Redis性能急剧下降。这时候,如何剔除无用的数据,腾出空间,存储新的数据就显得尤为重要。对此,Redis在生产环境中使用配置参数maxmemory来限制内存大小。当实际存储内存超过maxmemory参数的值时,开发者可以通过这些方法——Redis内存淘汰策略——来决定如何释放新的空间来继续支持读写。那么Redis的内存淘汰策略是如何工作的呢?首先,客户端会发起申请,申请更多的内存;其次,Redis检查内存使用情况。如果实际使用的内存已经超过maxmemory,Redis会根据用户配置的淘汰策略进行选择。无用的钥匙;***,确认选择的数据没有问题,成功执行淘汰任务。目前Redis3.0版本支持6种淘汰策略:1.volatile-lru:从数据集(server.db[i].expires)中选择最近最少使用的数据,设置了过期时间进行淘汰.没有过期时间的key不会被淘汰,这样在增加内存空间的同时也不会丢失需要持久化的数据。2.volatile-ttl:除淘汰机制采用LRU外,策略与volatile-lru基本相似。将过期的数据是从数据集(server.db[i].expires)中选出的,过期时间设置为淘汰。ttl值越大,越优先淘汰。3.volatile-random:从数据集(server.db[i].expires)中随机选择数据淘汰,设置了过期时间。当内存达到限制,无法写入非过期时间的数据集时,可以通过这种淘汰策略从主键空间中随机删除一个键。4.allkeys-lru:从数据集(server.db[i].dict)中选择最近最少使用的数据进行淘汰。该策略要淘汰的密钥是针对所有密钥集的,而不是过期密钥集。5.allkeys-random:从数据集(server.db[i].dict)中选择任意数据进行淘汰。6.no-enviction:禁止数据逐出,即当内存不足以容纳新的数据时,新的写操作会报错,请求可以继续,在线任务不能继续。no-enviction策略可以保证数据不丢失,这也是系统默认的淘汰策略。以上就是Redis的6种淘汰策略。关于这6种策略的使用,开发者还需要根据自己的系统特点正确选择或修改驱逐。在Redis中,当数据的一部分被频繁访问而其余部分访问频率较低,或者无法预测数据使用频率时,设置allkeys-lru比较合适。如果所有的数据访问概率大致相等,可以选择allkeys-random。如果开发者需要通过设置不同的ttl来确定数据过期的顺序,可以选择volatile-ttl策略。如果希望有些数据可以长期保存,有些数据可以淘汰,那么选择volatile-lru或者volatile-random比较好。由于设置expire会额外消耗内存,如果打算避免Redis内存在这一项上的浪费,可以选择allkeys-lru策略,这样就可以不再设置过期时间,高效使用内存。Redis缓存功能由edis.c文件中的freeMemoryIfNeeded函数实现。如果设置了maxmemory,那么每次执行该命令时,都会调用该函数判断内存是否充足,释放内存,并返回错误。如果内存不足,程序的主逻辑会阻止设置了REDIS_COM_DENYOOM标志的命令的执行,并返回commandnotallowedwhenusedmemory>‘maxmemory’的错误信息。为了区分不同的淘汰策略,选择不同的key,Redis的淘汰策略主要分为三种机制:LRU淘汰、TTL淘汰和随机淘汰。LRU淘汰LRU(Leastrecentlyused,最近最少使用)算法根据数据的历史访问记录来淘汰数据。其核心思想是“如果数据最近被访问过,那么未来被访问的概率也更高”。lru计数器server.lrulock保存在服务器配置中,会定时更新(redis定时程序serverCorn())。server.lrulock的值根据server.unixtime计算排序,然后选择最近使用的数据进行处理。删除。另外从structredisObject可以发现,每个redis对象都会设置对应的lru。每次访问数据时,都会更新对应的redisObject.lru。在Redis中,LRU算法是一种近似算法。默认情况下,Redis会随机选择5个key,选择一个最长时间没有被使用的key进行淘汰。在配置文件中,根据maxmemory-samples选项进行配置。选项配置越大,消耗时间越长,但结构越准确。TTL去掉了Redis数据集数据结构中存储键值对过期时间的表,即redisDb.expires。与LRU数据淘汰机制类似,在TTL数据淘汰机制中,从过期时间表中随机选取若干键值对,删除带有ttl***的键值对。同理,TTL淘汰策略也不是表中所有过期时间最快的过期键值对,而是随机选取的几个键值对。随机淘汰在随机淘汰场景下,获取待删除的键值对,随机找到hashbucket,对指定位置的dictEntry再次进行hash。Redis中的淘汰机制几乎是通过算法来实现的。它主要是基于性能和可靠性之间的平衡,所以并不是完全可靠的。因此,开发者在充分了解Redis淘汰策略后,应在平时主动设置或更新。Key过期时间,主动删除无价值数据,提高Redis的整体性能和空间。
