如何實現(xiàn)單機redis分布式鎖

這篇文章主要為大家展示了如何實現(xiàn)單機redis分布式鎖,內容簡而易懂,希望大家可以學習一下,學習完之后肯定會有收獲的,下面讓小編帶大家一起來看看吧。

目前成都創(chuàng)新互聯(lián)公司已為上千家的企業(yè)提供了網(wǎng)站建設、域名、網(wǎng)站空間網(wǎng)站托管、企業(yè)網(wǎng)站設計、興縣網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

最近我們有個服務經常出現(xiàn)存儲的數(shù)據(jù)出現(xiàn)重復,首先上一個系統(tǒng)流程圖:

如何實現(xiàn)單機redis分布式鎖

用戶通過http請求可以通知任務中心結束掉自己發(fā)送的任務,這時候任務中心會通過MQ通知結束服務去結束任務保存數(shù)據(jù),由于任務結束數(shù)據(jù)計算保存有一定延時,所以存在用戶短時間內多次結束同一個任務,這時候就會導致我們結束服務對同一個任務保存多次數(shù)據(jù)。恰好我們也是用了redis,所以對于這個問題我當時想到使用分布式鎖來解決,那么如何用redis實現(xiàn)分布式鎖呢?

首先要明確一個分布式鎖應具備的原則:

互斥性。在任意時刻,只有一個客戶端能持有鎖;不會發(fā)生死鎖。即使一個客戶端持有鎖的期間崩潰而沒有主動釋放鎖,也需要保證后續(xù)其他客戶端能夠加鎖成功;加鎖和解鎖必須是同一個客戶端;有高可用的獲取鎖和釋放鎖功能。

由于我們只使用了單機的redis,所以本文的實現(xiàn)不具備第四點原則。

我們這個鎖的實現(xiàn)就包括兩點:加鎖、解鎖。首先看加鎖。先上代碼:

public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) throws Exception{
    Jedis jedis = null;
    try {
      jedis = getJedisClient();
      String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
      if (LOCK_SUCCESS.equals(result)) {
        return true;
      }
      return false;
    } finally {
      returnResource(jedis);
    }
 }

我們的加鎖就是設置一個鍵值對,并且滿足以下條件:

確保只有當鍵不存在時才設置有效;設置的值必須是當前客戶端生成的uuid;鍵必須要有過期時間。

這三點條件就可以滿足上述的原則1、原則2。

接下來看下解鎖,代碼如下:

public boolean releaseDistributedLock(String lockKey, String requestId) throws Exception{
    Jedis jedis = null;
    try {
      jedis = getJedisClient();
      String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
      Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
      if (RELEASE_SUCCESS.equals(result)) {
        return true;
      }
      return false;
    }finally {
      returnResource(jedis);
    }
}

解鎖是通過一段lua腳本實現(xiàn),邏輯如下:

1、獲取鎖鍵值看是否與當初設置的值一致;

2、如果一致則刪除鍵。

由于解鎖過程分為兩步,為了確保原子性所以通過讓redis執(zhí)行l(wèi)ua腳本來實現(xiàn),校驗鍵值可以確保加鎖解鎖都是同一個客戶端。

這樣一個簡易的分布式鎖就實現(xiàn)完畢了,當然在本文開頭就說了,這個實現(xiàn)只能滿足單機redis的情況,對于redis集群其實是不嚴謹?shù)?,對于redis集群有一個redlock方案,我也在研究中,后面也會總結一下。

以上就是關于如何實現(xiàn)單機redis分布式鎖的內容,如果你們有學習到知識或者技能,可以把它分享出去讓更多的人看到。

分享文章:如何實現(xiàn)單機redis分布式鎖
當前鏈接:http://muchs.cn/article12/jejpgc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供微信公眾號、面包屑導航、軟件開發(fā)、電子商務、網(wǎng)站內鏈App開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設公司