【小题大做】【redis】redis expire 时间设置为 1秒

【思考点滴】

作者 : 杨考  微信号 : devin_cn_hd_09_16

一、背景

不做详细说明,有朋友自己设计了一个redis锁,使用 setnx 之后,通过 expire(1)设置的超时。发现会有偶发的 expire 失败,以及redis锁节点一致无法删除。

二、问题分析

1、首先在生产环境中,不建议使用 setnx + expire的方式来实现锁,毕竟两步操作中间发生异常,则锁一直无法释放。可以使用 setnx(key, timeout)来做更合理

2、expire可以设置超时时间,但是不建议1秒,毕竟来讲在调用expire到expire执行完毕,有可能会跨越一个秒级的时间戳,即1534304914秒执行,执行完毕已经是1534304915秒了,此时1534304915是实际的设置的超时时间,即在设置之后已经过期了。至于设置一个已过期的时间,是否会导致 expire失败?还是redis节点删除? 还是 ttl为其它值,这里不做过多介绍,毕竟expire不能设置负数值

3、通过expireat 来设置一个已经过期的时间,做一个简单的测试,验证一下expire(负数)的效果。

expireat操作成功,但是TTL为-1,即redis节点一直存在。其实已经验证了redis节点无法删除的问题了。

三、总结:

使用任何API的时候,要多想一下,为什么要使用1秒,1秒有什么好处,有什么坏处

1. 不能触发系统缺陷

2.满足业务需求,且不能提前删除,否则redis锁就是去意义了

3. 至于设置为多少合适,看业务处理的耗时,建议设置为<2*业务的耗时>

毕竟来讲,设置超时时间之后,在操作完成的时候,会主动删除redis锁,因此redis锁超时设置为1秒和100秒是没有差别的,都是在操作执行完之后,就将redis锁删除了。而1秒恰恰还有设计缺陷的弊端,自己统计一下,业务执行时间,然后根据2倍执行时间作为超时时间,这个就是比较好的。

之前有过怀疑expire(1),但是在网上搜不到资料,此文也没有严格的论证,但是从预判的角度,可以给个初步分析。希望对那些喜欢采坑的童鞋有所帮助

猜你喜欢

转载自blog.csdn.net/yk200808/article/details/81675268