网站建设运营的灵魂是,如何建立公众号的步骤,中企动力app,重庆seo霸屏目录Redis的租约问题Redis租约问题的想法Redis租约问题的解决方案Redis的租约问题
首先我们先来说一说什么是Redis的租约问题。 在我们实现Redis分布式锁的时候#xff0c;我们会出现Redis锁的时间业务执行执行时间#xff0c;这其实就是一个典型的租约问题#xf…
目录Redis的租约问题Redis租约问题的想法Redis租约问题的解决方案Redis的租约问题
首先我们先来说一说什么是Redis的租约问题。 在我们实现Redis分布式锁的时候我们会出现Redis锁的时间业务执行执行时间这其实就是一个典型的租约问题那么什么是租约问题呢我们让用户线程获取锁之后同时为了防止用户进程产生错误而无法释放锁导致其他用户再也无法获取不到锁产生的死锁现象所以我们为每一个锁设定一个Expire Time这样即使在用户进程不能正常释放锁的情况下过期时间到了之后Redis会自动释放掉锁来让别的用户来获取到锁。 这就是典型的租约机制用户申请了一个租约时长为lock_timeout的锁用户可以在租约期间使用完之后正常释放锁如果说了租约时间即使用户没有释放锁Redis也会自动释放锁。
Redis租约问题的想法 我们来设想一下如果用户可以很清晰的知道自己将要使用锁的时间那么我们设置lock_timeout就很容易了但是如果当用户并不知道自己用锁的时间设置租约就会是一个困难当然一般都不知道。我们设置租约时间
如果我们设置的时间过短那么可以用户还没用完锁锁就被Redis释放掉了之后多个用户访问一个共享资源产生错误。如果我们设置的时间过长那么当用户如果产生错误不能正常释放锁的时候其他用户线程就需要等待较长的时间才能获取到锁。
所以我们就萌生出一个想法当用户并不知道自己会用多久的时间那么我们为该锁设置一个较小的lock_timeout同时在该锁的过期之前就自动的向服务器延长该锁的lifetime.
Redis租约问题的解决方案
Redis租约问题一般有两个解决方案。
业务调研 我们需要大量测试我们业务的执行时间然后可以将我们所的过期时间设置为业务时间的1.5倍给他充分的冗余时间。但是如果我们考虑更多的异常情况发生的话那么我们这种方法可能不太靠谱。所以就有了第二种方法。锁的续约 锁的续约我们在去加锁的时候一般都会去启动一个线程而在开启这个启动线程的时候我们同样去启动一个守护线程这个守护线程我们就可以用来作为锁的续命。过程 假设我们用户拿到了我们的锁但是我们的业务时间远远大于我们加锁的时间如果我们的锁快到我们的过期时间的时候比如过期时间的前5s这个时候我们就可以用我们的守护线程去扫它看看我们的业务有没有执行完如果没有执行完那么续约同样的lock_timeout以此类推确保我们当前的加锁时间大于我们的业务执行时间这个是锁续约的核心思想。
那么我们这么做可能会出现什么问题 在我们进行业务调研后我们得出了我们业务时间的平均值如果我们的用户线程在执行过程中出现了问题那么业务执行时间就会无限长那么我们的岂不是会进行无限的续约所以简单的设计有点不太合理。
那么怎么解决呢 我们的解决方案是使用重试次数这个重试次数是重点 假设我们的业务的执行时间平均是10s那么我们最多容忍它执行50s如果他还没有执行完成那么我们就认为的服务器或者代码有问题我们需要进行人为干预。这里的话我们需要重试四次即可。 注意我们的守护线程是依赖于我们的用户线程而生的用户线程死我们的守护线程就死所以我们守护线程来进行续命用户线程在守护线程就在就可以续命。 这里使用了Lua脚本Lua脚本的作用在于保证原子性它能确保Lua脚本里面的内容要么同时执行要么同时不执行。