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