Redis使用SET命令覆盖旧值后,旧值是同步还是异步删除?

背景

  • 最近调研了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。

你可能感兴趣的:(credis)