最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis中鍵的過期刪除策略深入講解

 更新時間:2018年09月09日 15:50:06   作者:Chown  
這篇文章主要給大家介紹了關(guān)于Redis中鍵的過期刪除策略的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

如果一個鍵過期了,那么它什么時候會被刪除呢?

這個問題有三種可能的答案,它們分別代表了三種不同的刪除策略:

  • 定時刪除:在設(shè)置鍵的過期時間的同時,創(chuàng)建一個定時器( timer ). 讓定時器在鍵的過期時間來臨時,立即執(zhí)行對鍵的刪除操作。
  • 惰性刪除:放任鍵過期不管,但是每次從鍵空間中獲取鍵時,都檢查取得的鍵是否過期,如果過期的話,就刪除該鍵;如果沒有過期,就返回該鍵。
  • 定期刪除: 每隔一段時間,程序就對數(shù)據(jù)庫進行一次檢查,刪除里面的過期鍵。至于要刪除多少過期鍵,以及要檢查多少個數(shù)據(jù)庫, 則由算法決定。

在這三種策略中,第一種和第三種為主動刪除策略, 而第二種則為被動刪除策略。

前言

使用Redis時我們可以使用EXPIRE或EXPIREAT命令給key設(shè)置過期刪除時間,結(jié)構(gòu)體redisDb中的expires字典保存了所有key的過期時間,這個字典(dict)的key是一個指針,指向redis中的某個key對象,過期字典的value是一個保存過期時間的整數(shù)。

/* Redis database representation. There are multiple databases identified
 * by integers from 0 (the default database) up to the max configured
 * database. The database number is the 'id' field in the structure. */
typedef struct redisDb {
 dict *dict;     /* The keyspace for this DB */
 dict *expires;    /* 過期字典*/
 dict *blocking_keys;  /* Keys with clients waiting for data (BLPOP) */
 dict *ready_keys;   /* Blocked keys that received a PUSH */
 dict *watched_keys;   /* WATCHED keys for MULTI/EXEC CAS */
 struct evictionPoolEntry *eviction_pool; /* Eviction pool of keys */
 int id;      /* Database ID */
 long long avg_ttl;   /* Average TTL, just for stats */
} redisDb;

設(shè)置過期時間

不論是EXPIRE,EXPIREAT,還是PEXPIRE,PEXPIREAT,底層的具體實現(xiàn)是一樣的。在Redis的key空間中找到要設(shè)置過期時間的這個key,然后將這個entry(key的指針,過期時間)加入到過期字典中。

void setExpire(redisDb *db, robj *key, long long when) {
 dictEntry *kde, *de;

 /* Reuse the sds from the main dict in the expire dict */
 kde = dictFind(db->dict,key->ptr);
 redisAssertWithInfo(NULL,key,kde != NULL);
 de = dictReplaceRaw(db->expires,dictGetKey(kde));
 dictSetSignedIntegerVal(de,when);
}

過期刪除策略

如果一個key過期了,何時會被刪除呢?在Redis中有兩種過期刪除策略:(1)惰性過期刪除;(2)定期刪除。接下來具體看看。

惰性過期刪除

Redis在執(zhí)行任何讀寫命令時都會先找到這個key,惰性刪除就作為一個切入點放在查找key之前,如果key過期了就刪除這個key。


robj *lookupKeyRead(redisDb *db, robj *key) {
 robj *val;

 expireIfNeeded(db,key); // 切入點
 val = lookupKey(db,key);
 if (val == NULL)
  server.stat_keyspace_misses++;
 else
  server.stat_keyspace_hits++;
 return val;
}

定期刪除

key的定期刪除會在Redis的周期性執(zhí)行任務(serverCron,默認每100ms執(zhí)行一次)中進行,而且是發(fā)生Redis的master節(jié)點,因為slave節(jié)點會通過主節(jié)點的DEL命令同步過來達到刪除key的目的。


依次遍歷每個db(默認配置數(shù)是16),針對每個db,每次循環(huán)隨機選擇20個(ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP)key判斷是否過期,如果一輪所選的key少于25%過期,則終止迭次,此外在迭代過程中如果超過了一定的時間限制則終止過期刪除這一過程。

for (j = 0; j < dbs_per_call; j++) {
 int expired;
 redisDb *db = server.db+(current_db % server.dbnum);

 /* Increment the DB now so we are sure if we run out of time
  * in the current DB we'll restart from the next. This allows to
  * distribute the time evenly across DBs. */
 current_db++;

 /* Continue to expire if at the end of the cycle more than 25%
  * of the keys were expired. */
 do {
  unsigned long num, slots;
  long long now, ttl_sum;
  int ttl_samples;

  /* 如果該db沒有設(shè)置過期key,則繼續(xù)看下個db*/
  if ((num = dictSize(db->expires)) == 0) {
   db->avg_ttl = 0;
   break;
  }
  slots = dictSlots(db->expires);
  now = mstime();

  /* When there are less than 1% filled slots getting random
   * keys is expensive, so stop here waiting for better times...
   * The dictionary will be resized asap. */
  if (num && slots > DICT_HT_INITIAL_SIZE &&
   (num*100/slots < 1)) break;

  /* The main collection cycle. Sample random keys among keys
   * with an expire set, checking for expired ones. */
  expired = 0;
  ttl_sum = 0;
  ttl_samples = 0;

  if (num > ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP)
   num = ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP;// 20

  while (num--) {
   dictEntry *de;
   long long ttl;

   if ((de = dictGetRandomKey(db->expires)) == NULL) break;
   ttl = dictGetSignedIntegerVal(de)-now;
   if (activeExpireCycleTryExpire(db,de,now)) expired++;
   if (ttl > 0) {
    /* We want the average TTL of keys yet not expired. */
    ttl_sum += ttl;
    ttl_samples++;
   }
  }

  /* Update the average TTL stats for this database. */
  if (ttl_samples) {
   long long avg_ttl = ttl_sum/ttl_samples;

   /* Do a simple running average with a few samples.
    * We just use the current estimate with a weight of 2%
    * and the previous estimate with a weight of 98%. */
   if (db->avg_ttl == 0) db->avg_ttl = avg_ttl;
   db->avg_ttl = (db->avg_ttl/50)*49 + (avg_ttl/50);
  }

  /* We can't block forever here even if there are many keys to
   * expire. So after a given amount of milliseconds return to the
   * caller waiting for the other active expire cycle. */
  iteration++;
  if ((iteration & 0xf) == 0) { /* 每迭代16次檢查一次 */
   long long elapsed = ustime()-start;

   latencyAddSampleIfNeeded("expire-cycle",elapsed/1000);
   if (elapsed > timelimit) timelimit_exit = 1;
  }
 // 超過時間限制則退出
  if (timelimit_exit) return;
  /* 在當前db中,如果少于25%的key過期,則停止繼續(xù)刪除過期key */
 } while (expired > ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP/4);
}

總結(jié)

惰性刪除:讀寫之前判斷key是否過期

定期刪除:定期抽樣key,判斷是否過期

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • redis通過6379端口無法連接服務器(redis-server.exe閃退)

    redis通過6379端口無法連接服務器(redis-server.exe閃退)

    這篇文章主要介紹了redis通過6379端口無法連接服務器(redis-server.exe閃退),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • Redis高性能的原因及說明

    Redis高性能的原因及說明

    這篇文章主要介紹了Redis高性能的原因及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 分布式使用Redis實現(xiàn)數(shù)據(jù)庫對象自增主鍵ID

    分布式使用Redis實現(xiàn)數(shù)據(jù)庫對象自增主鍵ID

    本文介紹在分布式項目中使用Redis生成對象的自增主鍵ID,通過Redis的INCR等命令實現(xiàn)計數(shù)器功能,具有一定的參考價值,感興趣的可以了解一下
    2024-12-12
  • 淺談Redis中LFU算法源碼解析

    淺談Redis中LFU算法源碼解析

    Redis的LFU淘汰算法主要用于?maxmemory-policy?設(shè)置為allkeys-lfu或volatile-lfu時,以最少使用頻率的鍵進行淘汰,本文主要介紹了淺談Redis中LFU算法源碼解析,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2025-04-04
  • Redis主從復制實現(xiàn)原理分析

    Redis主從復制實現(xiàn)原理分析

    Redis主從復制通過Sync和CommandPropagate階段實現(xiàn)數(shù)據(jù)同步,2.8版本后引入Psync指令,根據(jù)復制偏移量進行全量或部分同步,優(yōu)化了數(shù)據(jù)傳輸效率
    2025-01-01
  • RediSearch加RedisJSON大于Elasticsearch的搜索存儲引擎

    RediSearch加RedisJSON大于Elasticsearch的搜索存儲引擎

    這篇文章主要為大家介紹了RediSearch加RedisJSON大于Elasticsearch的王炸使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • CentOS6.4 安裝Redis 教程詳解

    CentOS6.4 安裝Redis 教程詳解

    這篇文章主要介紹了CentOS6.4 安裝Redis 教程詳解,需要的朋友可以參考下
    2017-05-05
  • redis?哨兵集群搭建的實現(xiàn)

    redis?哨兵集群搭建的實現(xiàn)

    本文主要介紹了redis?哨兵集群搭建的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • Redis分布式鎖解決超賣問題

    Redis分布式鎖解決超賣問題

    超賣問題是典型的多線程安全問題,本文就來介紹一下Redis分布式鎖解決超賣問題,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • 詳談redis優(yōu)化配置和redis.conf說明(推薦)

    詳談redis優(yōu)化配置和redis.conf說明(推薦)

    下面小編就為大家?guī)硪黄斦剅edis優(yōu)化配置和redis.conf說明(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03

最新評論

马关县| 桃园市| 尚义县| 澄城县| 游戏| 万全县| 潞城市| 霍州市| 齐齐哈尔市| 南投市| 营山县| 淮滨县| 三门县| 夏河县| 册亨县| 洛宁县| 余江县| 景东| 体育| 彭州市| 六安市| 辰溪县| 武义县| 青铜峡市| 陇西县| 罗定市| 唐山市| 新津县| 青河县| 鞍山市| 新化县| 贵南县| 天镇县| 抚州市| 于都县| 大冶市| 建始县| 理塘县| 保亭| 颍上县| 响水县|