Redis 分佈式鎖

要介紹分佈式鎖,首先要提到與分佈式鎖相對應的是線程鎖、進程鎖。

線程鎖:主要用來給方法、代碼塊加鎖。當某個方法或代碼使用鎖,在同一時刻僅有一個線程執行該方法或該代碼段。

進程鎖:爲了控制同一操作系統中多個進程訪問某個共享資源,因爲進程具有獨立性,各個進程無法訪問其他進程的資源。

分佈式鎖:當多個進程不在同一個系統中,用分佈式鎖控制多個進程對資源的訪問。

設計思路

由於 Redis 是單線程模型,命令操作原子性,所以利用這個特性可以很容易的實現分佈式鎖。

A 用戶端在 Resdis 寫入 1 個 KEY, 其他的用戶無法寫入這個 KEY, 實現鎖的效果。

A 用戶使用完成後釋放 KEY, 或者是 KEY 過了超時時間,釋放 KEY。

主要代碼

 Boolean isLoading = dataPermissionRedis.TryLoading(a, b);
            if (isLoading)
            {
                try
                {
                  //todo
                }
                finally
                {
                    dataPermissionRedis.removeLoading(a, b);
                }
            }
   public bool TryLoading(string a, string b, int expireTime = 20)
        {
            var key = GetLoadingKey(a, b);
            using (IRedisClient client = this.GetClient())
            {
                var r = client.Add(key, "1", new TimeSpan(0, 0, 0, expireTime));
                //存在
                if (!r)
                {
                    //獲取過期時間
                    var totalSeconds = client.GetTimeToLive(key)?.TotalSeconds;
                    //存在且過期時間大於 expireTime(當做永久key) 解決歷史遺留key
                    if (totalSeconds.HasValue && totalSeconds.Value > expireTime)
                    {
                        //強制設置過期時間
                        client.ExpireEntryIn(key, new TimeSpan(0, 0, 0, expireTime));
                    }
                }
                return r;
            }
        }
 public void removeLoading(string a, string b)
        {
            using (IRedisClient client = this.GetClient())
            {
                client.Remove(GetLoadingKey(a, b));
            }
        }
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/lGezIJZROtLAKH2omW5DvA