加入收藏 | 设为首页 | 会员中心 | 我要投稿 温州站长网 (https://www.0577zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 交互 > 正文

redis lru实现策略

发布时间:2016-10-29 17:12:05 所属栏目:交互 来源:站长网
导读:副标题#e# 在使用redis作为缓存的场景下,内存淘汰策略决定的redis的内存使用效率。在大部分场景下,我们会采用LRU(Least Recently Used)来作为redis的淘汰策略。本文将由浅入深的介绍redislru策略的具体实现。 首先我们来科普下,什么是LRU ?(以下来自维

点击(此处)折叠或打开

  1. server.lruclock = getLRUClock();
  2. getLRUClock函数如下:
  3. #define LRU_CLOCK_RESOLUTION 1000 /* LRU clock resolution in ms */
  4. #define LRU_BITS 24
  5. #define LRU_CLOCK_MAX ((1<lru */
  6. /* Return the LRU clock, based on the clock resolution. This is a time
  7.  * in a reduced-bits format that can be used to set and check the
  8.  * object->lru field of redisObject structures. */

  9.   unsigned int getLRUClock(void) {
  10.         return (mstime()/LRU_CLOCK_RESOLUTION) & LRU_CLOCK_MAX;
  11.   }
因此lrulock最大能到(2**24-1)/3600/24 = 194天,如果超过了这个时间,lrulock重新开始。 对于redis server来说,server.lrulock表示的是一个全局的lrulock,那么对于每个redisObject都有一个自己的lrulock。这样每redisObject就可以根据自己的lrulock和全局的server.lrulock比较,来确定是否能够被淘汰掉。
redis key对应的value的存放对象:

点击(此处)折叠或打开

  1. typedef struct redisObject {
  2.      unsigned type:4;
  3.      unsigned encoding:4;
  4.      unsigned lru:LRU_BITS; /* LRU time (relative to server.lruclock) or
  5.                              * LFU data (least significant 8 bits frequency
  6.                              * and most significant 16 bits decreas time). */
  7.      int refcount;
  8.      void *ptr;
  9.      } robj
 
那么什么时候,lru会被更新呢 ?访问该key,lru都会被更新,这样该key就能及时的被移动到lru头部,从而避免从lru中淘汰。下面是这一部分的实现:

点击(此处)折叠或打开

  1. /* Low level key lookup API, not actually called directly from commands
  2. * implementations that should instead rely on lookupKeyRead(),
  3. * lookupKeyWrite() and lookupKeyReadWithFlags(). */
  4.   robj *lookupKey(redisDb *db, robj *key, int flags) {
  5.   dictEntry *de = dictFind(db->dict,key->ptr);
  6.   if (de) {
  7.      robj *val = dictGetVal(de);

  8. /* Update the access time for the ageing algorithm.
  9. * Don't do it if we have a saving child, as this will trigger
  10. * a copy on write madness. */
  11. if (server.rdb_child_pid == -1 &&
  12.     server.aof_child_pid == -1 &&
  13.     !(flags & LOOKUP_NOTOUCH))
  14.    {
  15.    if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
  16.    unsigned long ldt = val->lru >> 8;
  17.    unsigned long counter = LFULogIncr(val->lru & 255);
  18.    val->lru = (ldt << 8) | counter;
  19.    } else {
  20.    val->lru = LRU_CLOCK();
  21.   }
  22.   }
  23.    return val;
  24.   } else {
  25.   return NULL;
  26.  }
  27.  }
 
接下来,我们在来分析,key的lru淘汰策略如何实现,分别有哪几种:

(编辑:温州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读