Redis获取值前需先检查键是否存在?该实现是否冗余影响性能?
结论:该操作完全不必要,且会影响性能
你判断的没错,这种先调用EXISTS再执行GET/DEL的实现属于冗余操作,既没有必要,还会带来性能损耗和潜在的竞态问题。
1. 冗余性分析
- GET场景:Redis的
GET命令本身就会在键不存在时返回nil,和你当前代码中EXISTS判断后返回null的逻辑完全一致。直接调用GET就能达到相同效果,完全不需要提前做存在性检查。 - DEL场景:同理,Redis的
DEL命令会自动忽略不存在的键,返回实际删除的键数量(不存在则返回0),提前用EXISTS检查没有任何额外价值。
2. 性能与风险问题
- 性能损耗:每次缓存操作都多了一次Redis网络往返请求(RTT)。Redis本身性能极高,但网络开销是不可忽视的,在高并发场景下,额外的请求会累积成明显的性能下降。
- 竞态风险:两次命令之间存在时间窗口,比如
EXISTS返回true后,GET执行前,该键可能被其他客户端删除,这时GET依然会返回null,等于白做了一次EXISTS检查,逻辑上没有任何增益。
优化后的示例代码
以你提供的get方法为例,简化后完全可以达到原逻辑的效果:
public function get($id): mixed { try { // 直接调用GET,键不存在时Predis会返回null return $this->connection->get($id); } catch (PredisException $predisException) { // 保留原异常处理逻辑 ... } return null; }
内容的提问来源于stack exchange,提问作者Maarten de Jager
相关产品推荐
相关产品推荐

