使用HIREDIS执行流水线命令后不调用redisGetReply()是否存在风险?
redisAppendCommand调用后跳过redisGetReply的风险说明
即使你不需要返回结果、不关注错误场景,也必须调用redisGetReply消费所有流水线命令对应的返回结果,否则会出现严重的稳定性问题,具体危害如下:
- 内存持续泄漏:官方C客户端hiredis的底层实现中,Redis返回的所有响应都会先缓存在客户端的输入缓冲区,你不调用
redisGetReply拉取并释放响应对象,这部分内存会一直处于占用状态。随着流水线调用次数增加,内存占用会持续堆高,最终触发进程OOM崩溃。 - 连接状态损坏:客户端与Redis的TCP连接读写缓冲区是绑定的,如果客户端长期不读取服务端返回的响应,服务端的TCP发送缓冲区会被占满,进而触发Redis主动断开连接,严重时还会影响同一实例上其他连接的请求处理;如果是集群部署模式,还可能引发槽路由错乱、连接池失效等连锁问题。
- 后续请求逻辑错乱:如果缓冲区堆积了未消费的旧响应,后续你再发起其他Redis请求,哪怕主动调用
redisGetReply拿结果,拿到的也是之前堆积的旧响应,和你最新发起的命令完全不匹配,导致业务逻辑完全出错。
你担心的性能损耗几乎可以忽略:
redisGetReply在流水线场景下的开销极低,仅为从客户端本地缓冲区读取数据、释放响应对象的操作,相比跳过该步骤带来的故障风险,成本微乎其微。如果确实不需要处理返回内容,只需要循环调用redisGetReply拿到结果后直接调用freeReplyObject()释放即可,不需要做任何额外的逻辑判断。
如果你的场景完全允许命令丢失、不在意执行结果,仅有一种极端情况可以跳过消费返回:批量发送完所有命令后直接关闭当前连接、重建新连接使用,但该方式会带来连接重建开销,且完全无法感知命令是否发送成功、执行成功,风险极高,不推荐使用。
内容的提问来源于stack exchange,提问作者Rita Sprinkle
相关产品推荐
相关产品推荐

