// n 表示一次最多转移的数组中索引数量(索引表示对应的整个链表) intdictRehash(dict *d, int n) { int empty_visits = n*10; /* 查找不为空的索引的最大查找数量 */ if (!dictIsRehashing(d)) return0; // 如果已经在进行rehash则直接返回
/* This function handles 'background' operations we are required to do * incrementally in Redis databases, such as active key expiring, resizing, * rehashing. */ // 大意就是:这个函数用来处理后台操作,比如过期key, resizing, rehashing // 这里删掉一部分暂时不关注的代码 voiddatabasesCron(void) { if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) {
/* Rehash */ // 上一步只是分配了空间,打开标志为,真正转移数据的部分在下面代码中进行 if (server.activerehashing) { for (j = 0; j < dbs_per_call; j++) { // 开始rehash转移数据!!! int work_done = incrementallyRehash(rehash_db); if (work_done) { /* If the function did some work, stop here, we'll do * more at the next cron loop. */ break; } else { /* If this db didn't need rehash, we'll try the next one. */ rehash_db++; rehash_db %= server.dbnum; } } } } }
intincrementallyRehash(int dbid) { /* Keys dictionary */ // 由于之前resize时已经将标志位打开,所以执行if中的函数 if (dictIsRehashing(server.db[dbid].dict)) { // 使用 1ms 进行rehash dictRehashMilliseconds(server.db[dbid].dict,1); return1; /* already used our millisecond for this loop... */ } // 省略过期key的代码处理 return0; }
intdictRehashMilliseconds(dict *d, int ms) { longlong start = timeInMilliseconds(); int rehashes = 0; // 每次移动 100个数组中的索引,如果用时不到之前指定的1ms则进行进行,否则不再执行 while(dictRehash(d,100)) { rehashes += 100; if (timeInMilliseconds()-start > ms) break; } return rehashes; }