redis del与unlink命令用法及实现

1. DEL 命令

 

DEL key [key ...]

删除指定的一批keys,如果删除中的某些key不存在,则直接忽略。

返回值

integer-reply: 被删除的keys的数量

例子

redis> SET key1 "Hello"
OK
redis> SET key2 "World"
OK
redis> DEL key1 key2 key3
(integer) 2
redis> 

2. unlink 命令

unlink key [key ...]

该命令和DEL十分相似:删除指定的key(s),若key不存在则该key被跳过。但是,相比DEL会产生阻塞,该命令会在另一个线程中回收内存,因此它是非阻塞的。 这也是该命令名字的由来:仅将keys从keyspace元数据中删除,真正的删除会在后续异步操作。

返回值

integer-reply:unlink的keys的数量.

例子

redis> SET key1 "Hello"
"OK"
redis> SET key2 "World"
"OK"
redis> UNLINK key1 key2 key3
(integer) 2
redis> 

3. unlink实现

del和unlink命令底层调用的都为delGenericCommand函数, 只是第二个参数不同

===cut===
void delCommand(client *c) {
delGenericCommand(c,0);
}

void unlinkCommand(client *c) {
delGenericCommand(c,1);
}

===cut===

delGenericCommand流程如下:

其中,释放key代价计算函数lazyfreeGetFreeEffort(),集合类型键,且满足对应编码,cost就是集合键的元数个数,否则cost就是1.

List:4.0只有一种编码,quicklist,所以编码无限制,直接返回element个数。

Set:非hash table编码,即intset编码时返回1.当一个集合只包含整数值元素, 并且这个集合的元素数量不多时, Redis 就会使用intset作为集合键的底层实现。

Hash:同上。

    当hash键值满足下面任意条件编码为hash table:

->element count > "hash-max-ziplist-entries",default 512.
->value length > "hash-max-ziplist-value",default 64

Zset:非skiplist编码,返回1.

   当zset键值满足下面任意条件编码为hash table:

->element count >"zset-max-ziplist-entries",default 128
->value length > "zset-max-ziplist-value", default 64


举例:
1 一个包含100元素的list key, 它的free cost就是100
2 一个512MB的string key, 它的free cost是

 

总结:

  1. 不管是del还是unlink,key都是同步删除的。
  2. 使用unlink命令时,如果value分配的空间不大,使用异步删除反而会降低效率,所以redis会先评估一下free value的effort,根据effort的值来决定是否做异步删除。
  3. 使用unlink命令时,由于string类型的effort一直返回的是1,所以string类型不会做异步删除。
### 使用 Redis 命令进行模糊匹配删除 Keys 在 Redis 中直接通过 `DEL` 或者 `UNLINK` 命令配合通配符来实现批量删除特定模式的键并不是一种推荐的做法,因为这可能会导致性能问题。然而,在某些情况下确实可以通过组合其他命令间接达成目的。 对于想要基于 Glob 风格模式(例如 `*`, `?`, `[...]`)删除多个 key 的场景,通常建议先利用 `SCAN` 命令遍历数据库中的所有 keys 并筛选符合条件的目标集合,再针对这些目标调用 `DEL` 或 `UNLINK` 来移除它们[^1]。 下面是一个 Python 脚本的例子,展示了如何安全有效地完成这一操作: ```python import redis def delete_keys_by_pattern(pattern='*', host='localhost', port=6379, password=None): client = redis.StrictRedis(host=host, port=port, decode_responses=True, password=password) cursor = '0' while cursor != 0: cursor, keys = client.scan(cursor=cursor, match=pattern, count=100) if keys: client.delete(*keys) delete_keys_by_pattern('my-prefix-*') ``` 此脚本会连接到指定地址和端口上的 Redis 实例,并根据给定的模式参数扫描并删除相应的 keys。注意这里使用了 `scan` 方法而不是简单的 `KEYS`,前者可以在不影响服务的情况下逐步检索数据,从而避免阻塞整个服务器进程。 另外需要注意的是当涉及到生产环境下的大规模清理工作时应当格外小心谨慎,最好提前做好充分测试以及备份措施以防意外发生。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金士顿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值