【问题标题】:Is the UNLINK command always better than DEL command?UNLINK 命令总是比 DEL 命令好吗?
【发布时间】:2018-01-30 18:48:20
【问题描述】:

在 Redis 4.0 中,有一个新的命令UNLINK 用于删除 Redis 内存中的键。

此命令与 DEL 非常相似:它删除指定的键。 就像 DEL 一样,如果一个键不存在,它就会被忽略。然而 命令在不同的线程中执行实际的内存回收所以它没有阻塞,而 DEL 是。这是命令名称的地方 来自:该命令只是从键空间中取消键的链接。这 实际删除将在稍后异步发生。

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

【问题讨论】:

    标签: redis blocking nonblocking


    【解决方案1】:

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

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

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

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

    更新:

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

    【讨论】:

    • >> 如果你发现线程同步有问题
    • 一般不会有问题。但是,对于每次异步删除,后台线程需要获得两次锁,而前台(主)线程需要获得一次锁。这可能是一个问题,例如上下文切换,锁定。恕我直言,如果您发现 UNLINK 很慢(同样,通常不会),您可以将其替换为 DEL,并进行一些基准测试。
    • 对于单个密钥,我将过期设置为 0 怎么样。会更快吗?
    • @Ultrablendz 如果将 expire 设置为 0,Redis 会立即删除密钥。默认情况下,它会同步删除 key,并且会阻塞 Redis。但是,你可以将lazyfree_lazy_expire config 设置为yes,这样Redis 会异步删除key,不会阻塞。
    【解决方案2】:

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

    UNLINK 是一个智能命令:它计算一个对象的释放成本,如果它非常小,它只会执行 DEL 应该做的事情并尽快释放该对象。否则对象被发送到后台队列进行处理。

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

    【讨论】:

      猜你喜欢
      • 2020-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-28
      • 1970-01-01
      • 2013-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多