加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

如履薄冰:Redis懒惰删除的庞大捐躯

发布时间:2018-12-14 13:40:37 所属栏目:编程 来源:老钱
导读:各人都知道 Redis 是单线程的,可是 Redis 4.0 增进了懒惰删除成果,懒惰删除必要行使异步线程对已删除的节点举办内存接纳,这意味着 Redis 底层着实并不是单线程,它内部尚有几个特另外鲜为人知的帮助线程。 这几个帮助线程在 Redis 内部有一个出格的名称

异步线程必要对使命行罗列办轮询处理赏罚,依次从链表表头摘取元素逐个处理赏罚。摘取元素的时辰也必要加锁,摘出来之后再解锁。假如一个元素都没有,它必要守候,直到主线程来叫醒它继承事变。

  1. // 异步线程执行逻辑  
  2. void *bioProcessBackgroundJobs(void *arg) {  
  3. ...  
  4.     pthread_mutex_lock(&bio_mutex[type]); // 先加锁  
  5.     ...  
  6.     // 轮回处理赏罚  
  7.     while(1) {  
  8.         listNode *ln;  
  9.         /* The loop always starts with the lock hold. */  
  10.         if (listLength(bio_jobs[type]) == 0) {  
  11.             // 对列空,那就睡觉吧  
  12.             pthread_cond_wait(&bio_newjob_cond[type],&bio_mutex[type]);  
  13.             continue;  
  14.         }  
  15.         /* Pop the job from the queue. */  
  16.         ln = listFirst(bio_jobs[type]); // 获取行列头元素  
  17.         job = ln->value;  
  18.         /* It is now possible to unlock the background system as we know have  
  19.          * a stand alone job structure to process.*/  
  20.         pthread_mutex_unlock(&bio_mutex[type]); // 开释锁  
  21.         // 这里是处理赏罚进程,为了省纸,就略去了  
  22.         ...  
  23.         // 开释使命工具  
  24.         zfree(job);  
  25.         ...  
  26.         // 再次加锁继承处理赏罚下一个元素  
  27.         pthread_mutex_lock(&bio_mutex[type]);  
  28.         // 由于使命已经处理赏罚完了,可以安心从链表中删除节点了  
  29.         listDelNode(bio_jobs[type],ln);  
  30.         bio_pending[type]--; // 计数减 1  
  31.     } 

研究完这些加锁解锁的代码后,笔者开始有点担忧主线程的机能。我们都知道加锁解锁是一个相比拟力耗时的操纵,尤其是气馁锁最为耗时。假如删除很频仍,主线程岂不是要频仍加锁解锁。

以是这里必定尚有优化空间,Java 的 ConcurrentLinkQueue 就没有行使这样粗粒度的气馁锁,它优先行使 cas 来节制并发。那就让我们就等候 Redis 在将来的版本里对它进一步改革优化吧!

(编辑:湖南网)

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

热点阅读