背景

  • 最近调研了redis大key的同步和异步删除形式,大key同步删除会造成主线程长时间阻塞。
  • set命令笼罩旧值时,旧值的开释是同步还是异步执行的呢?

查看源码

  • 在原key已有值时,set命令对应的操作函数为:
  • /* Overwrite an existing key with a new value. Incrementing the reference * count of the new value is up to the caller. * This function does not modify the expire time of the existing key. * * The program is aborted if the key was not already present. */void dbOverwrite(redisDb *db, robj *key, robj *val) {  dictEntry *de = dictFind(db->dict,key->ptr);  serverAssertWithInfo(NULL,key,de != NULL);  dictEntry auxentry = *de;  robj *old = dictGetVal(de);  if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {      val->lru = old->lru;  }  dictSetVal(db->dict, de, val);  if (server.lazyfree_lazy_server_del) {      /**       * 异步删除旧值       */      freeObjAsync(old);      /**       * 将以后须要开释的旧值auxentry的值指针设置为NULL       * 这样做是为了防止下一步的dictFreeVal操作执行实在的开释操作       */      dictSetVal(db->dict, &auxentry, NULL);  }  /**   * 执行开释操作   */  dictFreeVal(db->dict, &auxentry);}
  • 能够看到,在服务器参数lazyfree_lazy_server_del为true时,redis服务器会采纳异步删除的形式,否则同步删除。

配置项

  • lazyfree_lazy_server_del参数能够通过配置文件中的lazyfree-lazy-server-del来进行管制,其值为yes或no。

论断

  • 当lazyfree-lazy-server-del配置项的值为no时,redis的set操作采纳同步的形式开释旧值;值为yes时,采纳异步的形式开释旧值。
  • lazyfree-lazy-server-del的默认值为no。