UNLINK 命令总是比 DEL 命令好吗?

Is the UNLINK command always better than DEL command?

在Redis 4.0中,有一个新命令UNLINK可以删除Redis内存中的key。

This command is very similar to DEL: it removes the specified keys. Just like DEL a key is ignored if it does not exist. However the command performs the actual memory reclaiming in a different thread, so it is not blocking, while DEL is. This is where the command name comes from: the command just unlinks the keys from the keyspace. The actual removal will happen later asynchronously.

所以总是可以(100% 次)使用 UNLINK 而不是 DEL,因为 UNLINK 是非阻塞的,不像 DEL,对吧?

是的。请阅读来自 antirez 的 Lazy Redis is better Redis。但原因并不是 unlink 是非阻塞命令。原因是 unlink 比 del 更聪明。

UNLINK is a smart command: it calculates the deallocation cost of an object, and if it is very small it will just do what DEL is supposed to do and free the object ASAP. Otherwise the object is sent to the background queue for processing.

此外,我认为更快的方法是我们为 redis 做决定:对小键使用 DEL,对大键(如大列表或集合)使用 UNLINK。我们可以减少redis不必要的计算。

在讨论哪个更好之前,让我们先看看这些命令之间的区别。 DELUNLINK 都在阻塞模式下释放关键部分。不同之处在于他们释放价值部分的方式。

DEL 总是在阻塞模式下释放值部分。但是,如果值太大,例如对于大 LISTHASH 的分配太多,它会长时间阻塞 Redis。 Redis为了解决这个问题,实现了UNLINK命令,即'non-blocking'删除

事实上,UNLINK 并不总是 non-blocking/async。如果值很小,例如LISTHASH 的大小小于 64,该值将被立即释放。这样一来,UNLINK就和DEL差不多了,只是比DEL多了几个函数调用而已。但是,如果值很大,Redis 会将值放入一个列表中,该值将由另一个线程释放,即非阻塞释放。这样一来,主线程就得和后台线程做一些同步,这也是有代价的。

总之,如果值小,DEL至少和UNLINK一样好。如果值非常大,例如LIST 有数千或数百万项,UNLINKDEL 好得多。您始终可以安全地将 DEL 替换为 UNLINK。但是,如果你发现线程同步成为问题(多线程总是很头疼),你可以回滚到DEL.

更新:

从 Redis 6.0 开始,有一个新的配置:lazyfree-lazy-user-del。您可以将其设置为 yes,Redis 将 运行 执行 DEL 命令,就好像 运行 执行 UNLINK 命令一样。