分佈式紅鎖的leaseTime的設計原理

3.分佈式紅鎖的leaseTime的設計原理

提前做2個動作:
1.先把3臺 redis key全部清空(爲了不受debug干擾,必須先刪除鎖)
127.0.0.1:6379> flushdb
OK

都設置爲30分鐘超時 過期
2.isLock = redLock.tryLock(10006030, 10006030, TimeUnit.MILLISECONDS);

leaseTime就是租約時間,就是redis key的過期時間。

long newLeaseTime = -1;
if (leaseTime != -1) {
    if (waitTime == -1) {
        newLeaseTime = unit.toMillis(leaseTime);
    } else {
        newLeaseTime = unit.toMillis(waitTime)*2;
    }
}

爲什麼要新建一個newLeaseTime?而且還是unit.toMillis(waitTime)*2 ?? 關於這個newLeaseTime我思考了很久,花了我一個下午的時間才研究透!
1.先新建一個臨時的leasetime ,用(waitTime)*2
2.把臨時的leasetime設置到tryLockInnerAsync

redis.call('pexpire', KEYS[1], ARGV[1]);

臨時的LeaseTime

for循環執行完後tryLockInnerAsync 後,看下3臺redis實例,看下剩餘時間是多少,都是60分鐘

127.0.0.1:6379> ttl MY_REDLOCK
(integer) 3494

真實的LeaseTime

最後再重新設置真實的LeaseTime

if (leaseTime != -1) {
            List<RFuture<Boolean>> futures = new ArrayList<>(acquiredLocks.size());
            for (RLock rLock : acquiredLocks) {
                RFuture<Boolean> future = ((RedissonLock) rLock).expireAsync(unit.toMillis(leaseTime), TimeUnit.MILLISECONDS);
                futures.add(future);
            }
            
            for (RFuture<Boolean> rFuture : futures) {
                rFuture.syncUninterruptibly();
            }
        }
127.0.0.1:6379> ttl MY_REDLOCK
(integer) 1665

總結:
這種設計的好處就是避免了前面代碼在執行過程中,損失了leasetime,導在leasetime精度丟失。
所以用了一個newLeaseTime先設置一個臨時的過期時間;
最後在結束的時候再重新設置了leasetime,保證代碼邏輯的嚴謹性,這種代碼的嚴謹性,真是值得我們去學習。

今後大家在寫過期時間的時候,如果複雜度高的話,建議在代碼的最後再重新設置過期時間,保證精度不丟失。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章