redis一段利用server空闲时间进行hash重整的代码

本文介绍了一种在不影响服务的前提下优化 Redis HashTable 的方法。通过将耗时的 hash 重整任务拆分成多个小步骤,并在每个服务器空闲时间段执行一小部分,确保了服务器响应速度的同时完成了重整任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先出个题目:
有server1,
其处理能力为 qps = 10000,
当前运行中的qps=1000,
server1中有一个hashtable 为 h1,
目前h1的hash冲突情况很严重,需要进行hash重整,
此时如何处理才能在不影响server服务的情况下完成优化重整任务?

 

答案就在下面:

 

今天看redis源码,看到一段代码,对写server的同学有借鉴简直。

 

我们知道,Server里面一般是一个死循环,然后就是get_msg, handle_msg, send_response, 而如果没有获取到消息,则一般是在进行usleep(x)。 而redis里面则把这个本来要进行usleep的时间利用起来,他把一个例行工作按时间片进行严格拆分,比如拆分为多个1ms的执行段。

 

如下面代码,rehash是一个hashtable重整的操作,一般比较耗时,这里便用dictRehashMilliseconds将这个操作拆成多个时间片区完成,

从而在完成重整任务的同时也保证了server的及时响应。

 

 

/* Rehash for an amount of time between ms milliseconds and ms+1 milliseconds */
int dictRehashMilliseconds(dict *d, int ms) {
    long long start = timeInMilliseconds();
    int rehashes = 0;

    while(dictRehash(d,100)) {
        rehashes += 100;
        if (timeInMilliseconds()-start > ms) break;
    }
    return rehashes;
}

 

 

rehash支持将整个hashtable重整分为每次N步的片段执行。

 

/* Performs N steps of incremental rehashing. Returns 1 if there are still
 * keys to move from the old to the new hash table, otherwise 0 is returned.
 * Note that a rehashing step consists in moving a bucket (that may have more
 * thank one key as we use chaining) from the old to the new hash table. */
int dictRehash(dict *d, int n) {
    if (!dictIsRehashing(d)) return 0;

    while(n--) {
        dictEntry *de, *nextde;

        /* Check if we already rehashed the whole table... */
        if (d->ht[0].used == 0) {
            _dictFree(d->ht[0].table);
            d->ht[0] = d->ht[1];
            _dictReset(&d->ht[1]);
            d->rehashidx = -1;
            return 0;
        }

        /* Note that rehashidx can't overflow as we are sure there are more
         * elements because ht[0].used != 0 */
        while(d->ht[0].table[d->rehashidx] == NULL) d->rehashidx++;
        de = d->ht[0].table[d->rehashidx];
        /* Move all the keys in this bucket from the old to the new hash HT */
        while(de) {
            unsigned int h;

            nextde = de->next;
            /* Get the index in the new hash table */
            h = dictHashKey(d, de->key) & d->ht[1].sizemask;
            de->next = d->ht[1].table[h];
            d->ht[1].table[h] = de;
            d->ht[0].used--;
            d->ht[1].used++;
            de = nextde;
        }
        d->ht[0].table[d->rehashidx] = NULL;
        d->rehashidx++;
    }
    return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值