设为首页 收藏本站
查看: 1174|回复: 0

[经验分享] redis源码笔记

[复制链接]
累计签到:3 天
连续签到:1 天
发表于 2015-7-21 07:31:06 | 显示全部楼层 |阅读模式
  redis允许对key设置超时时间,实现过期key的自动淘汰。这篇blog分析下,其自适应(adaptive)的淘汰机制。
  redis每隔100ms定时执行的循环(serverCron function)里有如下语句:



655     /* Expire a few keys per cycle, only if this is a master.
656      * On slaves we wait for DEL operations synthesized by the master
657      * in order to guarantee a strict consistency. */
658     if (server.masterhost == NULL) activeExpireCycle();
  正如文中注释所示,只有master执行expire cycle,slave会等候由master传递的DEL消息,保证master-slave在过期值处理上的一致性。(后边代码会看到,redis对过期值的选择是随机抽取的,master-slave完全可能抽取不同的值,因此要求master通过DEL消息实现同步,同时这种expire机制也是不可靠的expire,即key超时后有可能不会被删除)。
  activeExpireCycle函数如下:



477 /* Try to expire a few timed out keys. The algorithm used is adaptive and
478  * will use few CPU cycles if there are few expiring keys, otherwise
479  * it will get more aggressive to avoid that too much memory is used by
480  * keys that can be removed from the keyspace. */
481 void activeExpireCycle(void) {
482     int j;
483
484     for (j = 0; j < server.dbnum; j++) {
485         int expired;
486         redisDb *db = server.db+j;
487
488         /* Continue to expire if at the end of the cycle more than 25%
489          * of the keys were expired. */
490         do {
491             long num = dictSize(db->expires);
492             time_t now = time(NULL);
493
494             expired = 0;
495             if (num > REDIS_EXPIRELOOKUPS_PER_CRON)
496                 num = REDIS_EXPIRELOOKUPS_PER_CRON;
497             while (num--) {
498                 dictEntry *de;
499                 time_t t;
500
501                 if ((de = dictGetRandomKey(db->expires)) == NULL) break;
502                 t = (time_t) dictGetEntryVal(de);
503                 if (now > t) {
504                     sds key = dictGetEntryKey(de);
505                     robj *keyobj = createStringObject(key,sdslen(key));
506
507                     propagateExpire(db,keyobj);     //将删除操作传播给各个slaves,在此之前,还将del操作记录aof
508                     dbDelete(db,keyobj);   //这个函数先从db->expires中删除,然后删除db->dict
509                     decrRefCount(keyobj);
510                     expired++;
511                     server.stat_expiredkeys++;
512                 }
513             }
514         } while (expired > REDIS_EXPIRELOOKUPS_PER_CRON/4);
515     }
516 }
  ExpireCycle每次尝试处理10个key,如果10个key中有>2.5个超时,则继续处理10个key。其用意在于,如果超时的key比例很高,则一次迭代处理很多个,否则等待下次serverCron循环再随机抽取。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-88813-1-1.html 上篇帖子: openresty 下篇帖子: Java版的Redis
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表