搜索
首页数据库Redisredis中设置lru算法的方法

redis中设置lru算法的方法

May 23, 2020 am 08:58 AM
redis

redis中设置lru算法的方法

1、设置Redis使用LRU算法

LRU(Least Recently Used)最近最少使用算法是众多置换算法中的一种。 
Redis中有一个maxmemory概念,主要是为了将使用的内存限定在一个固定的大小。Redis用到的LRU 算法,是一种近似的LRU算法。

(1)设置maxmemory

上面已经说过maxmemory是为了限定Redis最大内存使用量。有多种方法设定它的大小。其中一种方法是通过CONFIG SET设定,如下:

127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "0"
127.0.0.1:6379> CONFIG SET maxmemory 100MB
OK
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "104857600"

另一种方法是修改配置文件redis.conf:

maxmemory 100mb

注意,在64bit系统下,maxmemory设置为0表示不限制Redis内存使用,在32bit系统下,maxmemory隐式不能超过3GB。 
当Redis内存使用达到指定的限制时,就需要选择一个置换的策略。

(2)置换策略

当Redis内存使用达到maxmemory时,需要选择设置好的maxmemory-policy进行对老数据的置换。 
下面是可以选择的置换策略:

  • noeviction: 不进行置换,表示即使内存达到上限也不进行置换,所有能引起内存增加的命令都会返回error

  • allkeys-lru: 优先删除掉最近最不经常使用的key,用以保存新数据

  • volatile-lru: 只从设置失效(expire set)的key中选择最近最不经常使用的key进行删除,用以保存新数据

  • allkeys-random: 随机从all-keys中选择一些key进行删除,用以保存新数据

  • volatile-random: 只从设置失效(expire set)的key中,选择一些key进行删除,用以保存新数据

  • volatile-ttl: 只从设置失效(expire set)的key中,选出存活时间(TTL)最短的key进行删除,用以保存新数据

需要注意的是:

(1)设置maxmemory-policy的方法和设置maxmemory方法类似,通过redis.conf或是通过CONFIG SET动态修改。

(2)如果没有匹配到可以删除的key,那么volatile-lru、volatile-random和volatile-ttl策略和noeviction替换策略一样——不对任何key进行置换。

(3)选择合适的置换策略是很重要的,这主要取决于你的应用的访问模式,当然你也可以动态的修改置换策略,并通过用Redis命令——INFO去输出cache的命中率情况,进而可以对置换策略进行调优。

一般来说,有这样一些常用的经验:

  • 在所有的key都是最近最经常使用,那么就需要选择allkeys-lru进行置换最近最不经常使用的key,如果你不确定使用哪种策略,那么推荐使用allkeys-lru。

  • 如果所有的key的访问概率都是差不多的,那么可以选用allkeys-random策略去置换数据。

  • 如果对数据有足够的了解,能够为key指定hint(通过expire/ttl指定),那么可以选择volatile-ttl进行置换。

volatile-lru 和 volatile-random经常在一个Redis实例既做cache又做持久化的情况下用到,然而,更好的选择使用两个Redis实例来解决这个问题。

设置是失效时间expire会占用一些内存,而采用allkeys-lru就没有必要设置失效时间,进而更有效的利用内存。

(3)置换策略是如何工作的

理解置换策略的执行方式是非常重要的,比如:

  1. 客户端执行一条新命令,导致数据库需要增加数据(比如set key value)

  2. Redis会检查内存使用,如果内存使用超过maxmemory,就会按照置换策略删除一些key

  3. 新的命令执行成功

我们持续的写数据会导致内存达到或超出上限maxmemory,但是置换策略会将内存使用降低到上限以下。

如果一次需要使用很多的内存(比如一次写入一个很大的set),那么,Redis的内存使用可能超出最大内存限制一段时间。

(4)近似LRU算法

Redis中的LRU不是严格意义上的LRU算法实现,是一种近似的LRU实现,主要是为了节约内存占用以及提升性能。Redis有这样一个配置——maxmemory-samples,Redis的LRU是取出配置的数目的key,然后从中选择一个最近最不经常使用的key进行置换,默认的5,如下:

maxmemory-samples 5

可以通过调整样本数量来取得LRU置换算法的速度或是精确性方面的优势。

Redis不采用真正的LRU实现的原因是为了节约内存使用。虽然不是真正的LRU实现,但是它们在应用上几乎是等价的。下图是Redis的近似LRU实现和理论LRU实现的对比:

1.jpg

测试开始首先在Redis中导入一定数目的key,然后从第一个key依次访问到最后一个key,因此根据LRU算法第一个被访问的key应该最新被置换,之后再增加50%数目的key,导致50%的老的key被替换出去。 

在上图中你可以看到三种类型的点,组成三种不同的区域:

  1. 淡灰色的是被置换出去的key

  2. 灰色的是没有被置换出去的key

  3. 绿色的是新增加的key

理论LRU实现就像我们期待的那样,最旧的50%数目的key被置换出去,Redis的LRU将一定比例的旧key置换出去。

可以看到在样本数为5的情况下,Redis3.0要比Redis2.8做的好很多,Redis2.8中有很多应该被置换出去的数据没有置换出去。在样本数为10的情况下,Redis3.0很接近真正的LRU实现。

LRU是一个预测未来我们会访问哪些数据的模型,如果我们访问数据的形式接近我们预想——幂律,那么近似LRU算法实现将能处理的很好。

在模拟测试中我们可以发现,在幂律访问模式下,理论LRU和Redis近似LRU的差距很小或者就不存在差距。

如果你将maxmemory-samples设置为10,那么Redis将会增加额外的CPU开销以保证接近真正的LRU性能,可以通过检查命中率来查看有什么不同。

通过CONFIG SET maxmemory-samples 570b78fce6f4d82c6d7725059f1f48f1动态调整样本数大小,做一些测试验证你的猜想。

2、LRU的实现

<?php
/**
 * LRU是最近最少使用页面置换算法(Least Recently Used),也就是首先淘汰最长时间未被使用的页面
 */
class LRU_Cache
{

    private $array_lru = array();
    private $max_size = 0;

    function __construct($size)
    {
        // 缓存最大存储
        $this->max_size = $size;
    }

    public function set_value($key, $value)
    {
        // 如果存在,则向队尾移动,先删除,后追加
        // array_key_exists() 函数检查某个数组中是否存在指定的键名,如果键名存在则返回true,如果键名不存在则返回false。
        if (array_key_exists($key, $this->array_lru)) {
            // unset() 销毁指定的变量。
            unset($this->array_lru[$key]);
        }
        // 长度检查,超长则删除首元素
        if (count($this->array_lru) > $this->max_size) {
            // array_shift() 函数删除数组中第一个元素,并返回被删除元素的值。
            array_shift($this->array_lru);
        }
        // 队尾追加元素
        $this->array_lru[$key] = $value;
    }

    public function get_value($key)
    {
        $ret_value = false;

        if (array_key_exists($key, $this->array_lru)) {
            $ret_value = $this->array_lru[$key];
            // 移动到队尾
            unset($this->array_lru[$key]);
            $this->array_lru[$key] = $ret_value;
        }

        return $ret_value;
    }

    public function vardump_cache()
    {
        echo "<br>";
        var_dump($this->array_lru);
    }
}

$cache = new LRU_Cache(5);                          // 指定了最大空间 6
$cache->set_value("01", "01");
$cache->set_value("02", "02");
$cache->set_value("03", "03");
$cache->set_value("04", "04");
$cache->set_value("05", "05");
$cache->vardump_cache();
echo "<br>";

$cache->set_value("06", "06");
$cache->vardump_cache();
echo "<br>";

$cache->set_value("03", "03");
$cache->vardump_cache();
echo "<br>";

$cache->set_value("07", "07");
$cache->vardump_cache();
echo "<br>";

$cache->set_value("01", "01");
$cache->vardump_cache();
echo "<br>";

$cache->get_value("04");
$cache->vardump_cache();
echo "<br>";

$cache->get_value("05");
$cache->vardump_cache();
echo "<br>";

$cache->get_value("10");
$cache->vardump_cache();
echo "<br>";

更多redis知识请关注redis入门教程栏目。

以上是redis中设置lru算法的方法的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:博客园。如有侵权,请联系admin@php.cn删除
REDIS与数据库:性能比较REDIS与数据库:性能比较May 14, 2025 am 12:11 AM

Redisoutperformstraditionaldatabasesinspeedforread/writeOperationsDuetoitsin-memorynature,niletraditionalditionalditionalditationaldatabasesexcelcelincomplexqueriessanddaintegrity.1)redisisisisideSidealForrealForreal-timeanalyticsanticanticanticanticanticantic.2)

我什么时候应该使用redis代替传统数据库?我什么时候应该使用redis代替传统数据库?May 13, 2025 pm 04:01 PM

用户edisinsteadofatraditionaldatabasewhenyourapplicationrequirespeedandreal-timedataprocorsing,sueAsAsforCaching,sessionmanagement,orrereal-timeanalytics.redisexcelsin:1)caching,缓存,减少载荷载量

REDIS:超越SQL- NOSQL的观点REDIS:超越SQL- NOSQL的观点May 08, 2025 am 12:25 AM

Redis超越SQL数据库的原因在于其高性能和灵活性。1)Redis通过内存存储实现极快的读写速度。2)它支持多种数据结构,如列表和集合,适用于复杂数据处理。3)单线程模型简化开发,但高并发时可能成瓶颈。

REDIS:与传统数据库服务器的比较REDIS:与传统数据库服务器的比较May 07, 2025 am 12:09 AM

Redis在高并发和低延迟场景下优于传统数据库,但不适合复杂查询和事务处理。1.Redis使用内存存储,读写速度快,适合高并发和低延迟需求。2.传统数据库基于磁盘,支持复杂查询和事务处理,数据一致性和持久性强。3.Redis适用于作为传统数据库的补充或替代,但需根据具体业务需求选择。

REDIS:功能强大的内存数据存储的简介REDIS:功能强大的内存数据存储的简介May 06, 2025 am 12:08 AM

Redisisahigh-performancein-memorydatastructurestorethatexcelsinspeedandversatility.1)Itsupportsvariousdatastructureslikestrings,lists,andsets.2)Redisisanin-memorydatabasewithpersistenceoptions,ensuringfastperformanceanddatasafety.3)Itoffersatomicoper

Redis主要是数据库吗?Redis主要是数据库吗?May 05, 2025 am 12:07 AM

Redis主要是一个数据库,但它不仅仅是数据库。1.作为数据库,Redis支持持久化,适合高性能需求。2.作为缓存,Redis提升应用响应速度。3.作为消息代理,Redis支持发布-订阅模式,适用于实时通信。

REDIS:数据库,服务器还是其他?REDIS:数据库,服务器还是其他?May 04, 2025 am 12:08 AM

redisisamultifaceTedToolThatServesAsAdatabase,server和more.itfunctionsasanin-memorydatastrustore,supportsvariousDataStructures,and CanbeusedAsacache,MessageBroker,sessionStorage,sessionStorage,sessionstorage,andford forderibedibedlocking。

REDIS:揭示其目的和关键应用程序REDIS:揭示其目的和关键应用程序May 03, 2025 am 12:11 AM

Redisisanopen-Source,内存内部的库雷斯塔氏菌,卡赫和梅斯吉级,excellingInsPeedAndVersatory.itiswidelysusedforcaching,Real-Timeanalytics,Session Management,Session Managements,and sessighterboarderboarderboardobboardotoitsssupportfortfortfortfortfortfortfortfortorvortfortfortfortfortfortforvortfortforvortforvortforvortfortforvortforvortforvortforvortdatastherctuct anddatataCcessandcessanddataaCces

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。