Node.js使用redis包如何删除指定前缀的所有Redis key及对应字段?
问题根因
Redis的DEL、HDEL命令本身不支持通配符模式匹配,你传入带*的键名时,Redis只会尝试删除键名完全等于该字符串的记录,自然匹配不到你要删的前缀键,所以没有数据被删除。只有KEYS、SCAN这类查询类命令才支持*通配符的模式匹配逻辑。
正确实现方案
生产环境优先使用SCAN迭代匹配键,避免KEYS命令遍历全量键导致Redis主线程阻塞,影响其他业务请求。以下是对应redis npm包的实现代码:
- 首先在你的缓存服务中新增按模式批量删除键的通用方法:
public deleteByPattern(pattern: string): Promise<number> { return new Promise((resolve, reject) => { // 启用scan流迭代匹配键,避免全量扫描阻塞Redis const stream = this.store.scanStream({ match: pattern, count: 100 // 单次迭代拉取的键数量,可根据业务场景调整 }); const matchedKeys: string[] = []; stream.on('data', (keys: string[]) => { if (keys.length) matchedKeys.push(...keys); }); stream.on('end', () => { if (matchedKeys.length === 0) return resolve(0); // 批量删除键,Redis 4.0+推荐用unlink替代del,异步回收内存性能更好 this.store.unlink(matchedKeys, (err, deletedCount) => { if (err) return reject(err); resolve(deletedCount); }); }); stream.on('error', (err) => reject(err)); }); }
- 调整你的业务调用逻辑:
async deleteSessionFiles(sessionId: string) { const pathPattern = SessionPathResolver.resolveSessionAllFiles(sessionId); await this.cacheService.deleteByPattern(pathPattern); }
额外优化建议
如果你的业务场景中,同一个session下的文件都是以hash结构的字段存储,可以直接将hash的主键名设为sessions/${sessionId}/files,不需要给每个文件单独设顶级键,删除时直接调用你原本的hdel('sessions/${sessionId}/files')即可直接删除整个hash,不需要做模式匹配,性能会高很多。
内容的提问来源于stack exchange,提问作者ben berizovsky
相关产品推荐
相关产品推荐

