redis淘汰策略的几种实现

 更新时间:2024年05月22日 11:29:06   作者:云养猫v2  
redis内存数据数据集大小升到一定大的时候,就会实行数据淘汰策略,本文主要介绍了redis淘汰策略的几种实现,具有一定的参考价值,感兴趣的可以了解一下

redis内存数据数据集大小升到一定大的时候,就会实行数据淘汰策略(回收策略)。

1,volatile-lru:从已设置过期时间的哈希表(server.db[i].expires)中随机挑选多个key,然后在选到的key中用lru算法淘汰最近最少使用的数据

2,allkey-lru:从所有key的哈希表(server.db[i].dict)中随机挑选多个key,然后再选到的key中利用lru算法淘汰最近最少使用的数据

3,volatile-ttl:从已设置过期时间的哈希表(server.db[i].expires)中随机挑选多个key,然后在选到的key中选择过期时间最小的数据淘汰掉。

4,volatile-random:从已设置过期时间的哈希表(server.db[i].expires)中随机挑选key淘汰掉。

5,allkey-random:从所有的key的哈希表(server.db[i].dict)中随机挑数据淘汰

6,no-eviction(驱逐):内存达到上限,不淘汰数据。

redis确认驱逐某个键值对后,会删除这个数据,并将这个数据变更消息发布到本地(AOF持久化)和从机(主从连接)。

 LRU数据淘汰机制是这样的:在数据集中随机挑选几个键值对,去除其中最近最少使用的键值对淘汰。所以Redis并不是保证取得所有数据集中最少最少使用的键值对,而只是在随机挑选的几个键值对中。

TTL数据淘汰机制:从国企时间redisDB.expires表中随机挑选几个键值对,取出其中最快过期的键值对淘汰。所以Redis并不保证取得所有过期时间表中最快过期的键值对,而是随机挑选的几个键值对中。

无论是什么机制,都是从所有的键值对中挑选合适的淘汰。

在哪里开始淘汰数据

Redis服务器每执行一次命令的时候,会检测使用的内存是否超额。如果超额,即进行数据淘汰。

int freeMemoryIfNeeded(void) {
    /**
     * noeviction 不淘汰数据,什么都不做
     */
    if (server.maxmemory_policy == MAXMEMORY_NO_EVICTION)
        return C_ERR;
    while (mem_freed < mem_tofree) {
        int j, k, keys_freed = 0;
        for (j = 0; j < server.dbnum; j++) {
            /**
             * 选择操作的哈希表,Redis另外维护着一个保存过期时间的key=>expire关联的哈希表
             */
            if (server.maxmemory_policy == MAXMEMORY_ALLKEYS_LRU ||
                server.maxmemory_policy == MAXMEMORY_ALLKEYS_RANDOM)
            {
                dict = server.db[j].dict;
            } else {
                dict = server.db[j].expires;
            }
            /**
             * 分支一:全局哈希表随机或者过期时间哈希表中,随机淘汰一个key
             */
            if (server.maxmemory_policy == MAXMEMORY_ALLKEYS_RANDOM ||
                server.maxmemory_policy == MAXMEMORY_VOLATILE_RANDOM)
            {
                de = dictGetRandomKey(dict);
                bestkey = dictGetKey(de);
            }
            /**
             * 分支二:全局哈希表随机或者过期时间哈希表中,随机采样多个数据,再运用lru算法挑选一个淘汰
             */
            else if (server.maxmemory_policy == MAXMEMORY_ALLKEYS_LRU ||
                server.maxmemory_policy == MAXMEMORY_VOLATILE_LRU)
            {
                /* 样本集 */
                struct evictionPoolEntry *pool = db->eviction_pool;
                while(bestkey == NULL) {
                    /* 
                     * 采样,更新和维护样本集;
                     * 样本集开始是空的,每次操作完并不会清空样本集;
                     * 而且每次采样,都会采集多个数据,同时和样本集中已有的数据进行比较,新增或者更新样本集;
                     */ 
                    evictionPoolPopulate(dict, db->dict, db->eviction_pool);
                    /**
                     * 开始对样本集使用lru算法,淘汰样本集中访问时间最晚的key
                     */
                    for (k = MAXMEMORY_EVICTION_POOL_SIZE-1; k >= 0; k--) {
                        if (pool[k].key == NULL) continue;
                        de = dictFind(dict,pool[k].key);
                        /* 把选取到的key从样本集中移除 */
                        sdsfree(pool[k].key);
                        memmove(pool+k,pool+k+1,
                            sizeof(pool[0])*(MAXMEMORY_EVICTION_POOL_SIZE-k-1));
                        pool[MAXMEMORY_EVICTION_POOL_SIZE-1].key = NULL;
                        pool[MAXMEMORY_EVICTION_POOL_SIZE-1].idle = 0;
                        /* pool样本集内的key,只是样本,不一定和db内保持一致,也不必,可能在db中已经被删除的,所以要作判断 */
                        if (de) {
                            bestkey = dictGetKey(de);
                            break;
                        } else {
                            /* Ghost... */
                            continue;
                        }
                    }
                }
            }
            /**
             * 分支三:在设置了过期时间的哈希表里面随机选择多个key,在挑选到的key中选择过期时间最小的一个淘汰掉
             */
            else if (server.maxmemory_policy == MAXMEMORY_VOLATILE_TTL) {
                for (k = 0; k < server.maxmemory_samples; k++) {
                    sds thiskey;
                    long thisval;
                    de = dictGetRandomKey(dict);
                    thiskey = dictGetKey(de);
                    thisval = (long) dictGetVal(de);
                    if (bestkey == NULL || thisval < bestval) {
                        bestkey = thiskey;
                        bestval = thisval;
                    }
                }
            }
            if (bestkey) {
                long long delta;
                robj *keyobj = createStringObject(bestkey,sdslen(bestkey));
                // 命令扩散,把删除key的命令同步到所有从库slave
                propagateExpire(db,keyobj);
                // 删除key
                dbDelete(db,keyobj);
            }
        }
    }
    return C_OK;
}

到此这篇关于redis淘汰策略的几种实现的文章就介绍到这了,更多相关redis淘汰策略内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Redis为什么快如何实现高可用及持久化

    Redis为什么快如何实现高可用及持久化

    这篇文章主要介绍了Redis为什么快如何实现高可用及持久化,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • Redis IP地址的绑定的实现

    Redis IP地址的绑定的实现

    这篇文章主要介绍了Redis IP地址的绑定的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • 详解Redis中Lua脚本的应用和实践

    详解Redis中Lua脚本的应用和实践

    这篇文章主要介绍了详解Redis中Lua脚本的应用和实践,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • redis-trib.rb命令详解

    redis-trib.rb命令详解

    redis-trib.rb是官方提供的Redis Cluster的管理工具,无需额外下载,默认位于源码包的src目录下,但因该工具是用ruby开发的,所以需要准备相关的依赖环境,这篇文章主要介绍了redis-trib.rb命令详解,需要的朋友可以参考下
    2023-10-10
  • Redisson分布式锁之加解锁详解

    Redisson分布式锁之加解锁详解

    这篇文章主要为大家介绍了Redisson分布式锁加解锁的详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Redis 键值设计使用总结

    Redis 键值设计使用总结

    这篇文章主要介绍了Redis键值设计的使用总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • redis中事务机制及乐观锁的实现

    redis中事务机制及乐观锁的实现

    这篇文章主要介绍了redis中事务机制及乐观锁的相关内容,通过事务的执行分析Redis乐观锁,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • redis哈希和集合_动力节点Java学院整理

    redis哈希和集合_动力节点Java学院整理

    这篇文章主要为大家详细介绍了redis哈希和集合的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • Redis底层类型之json命令使用

    Redis底层类型之json命令使用

    这篇文章主要为大家介绍了Redis底层类型之json命令使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • SpringBoot整合Redis实现序列化存储Java对象的操作方法

    SpringBoot整合Redis实现序列化存储Java对象的操作方法

    这篇文章主要介绍了SpringBoot整合Redis实现序列化存储Java对象,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03

最新评论