最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis分布式鎖存在的問(wèn)題(推薦)

 更新時(shí)間:2022年12月12日 08:44:43   作者:小黑說(shuō)Java  
有很多基于Redis實(shí)現(xiàn)的分布式鎖方案或者庫(kù),但是有些庫(kù)并沒(méi)有解決分布式環(huán)境下的一些問(wèn)題陷阱,這篇文章主要介紹了Redis分布式鎖存在的問(wèn)題,需要的朋友可以參考下

在很多場(chǎng)景中,我們?yōu)榱吮WC數(shù)據(jù)的最終一致性,需要很多的技術(shù)方案來(lái)支持,比如分布式事務(wù)、分布式鎖等。

有很多基于Redis實(shí)現(xiàn)的分布式鎖方案或者庫(kù),但是有些庫(kù)并沒(méi)有解決分布式環(huán)境下的一些問(wèn)題陷阱。

分布式鎖的特點(diǎn)

分布式鎖應(yīng)該具備以下屬性:

  • 互斥 在同一時(shí)刻只有一個(gè)客戶端可以持有鎖;這是分布式鎖的基本屬性。
  • 無(wú)死鎖 每個(gè)鎖請(qǐng)求都可以最終獲得鎖;即使是持有鎖的客戶端也會(huì)崩潰或遇到異常。 不同的實(shí)現(xiàn)

不同的實(shí)現(xiàn)

許多分布式鎖實(shí)現(xiàn)都是基于分布式共識(shí)算法(Paxos、Raft、ZAB、Pacifica)的,比如基于Paxos的Chubby、基于ZAB的Zookeeper等,以及基于Raft的Consul。Redis的作者還提出了一種分布式鎖,名為RedLock。

在接下來(lái)的章節(jié)中,我將展示如何基于Redis一步步實(shí)現(xiàn)分布式鎖,并且在每一步中,我都試圖解決分布式環(huán)境中可能發(fā)生的一個(gè)問(wèn)題。

場(chǎng)景一:?jiǎn)螌?shí)例Redis

為了簡(jiǎn)單起見(jiàn),假設(shè)我們有兩個(gè)客戶端和一個(gè)Redis實(shí)例。一個(gè)簡(jiǎn)單的實(shí)現(xiàn)應(yīng)該是:

boolean tryAcquire(String lockName, long leaseTime, OperationCallBack operationCallBack) {
   // 加鎖
  boolean getLockSuccessfully = getLock(lockName, leaseTime);
  if (getLockSuccessfully) {
      try {
          operationCallBack.doOperation();
      } finally {
          releaseLock(lockName);
      }
      return true;
  } else {
      return false;
  }
}

boolean getLock(String lockName, long expirationTimeMillis) {
	// 給當(dāng)前線程創(chuàng)建一個(gè)唯一的lockValue
  String lockValue = createUniqueLockValue();
  try {
	  // 如果lockName沒(méi)有加鎖,則將lockName作為key保存到redis中,并指定過(guò)期時(shí)間
      String response = storeLockInRedis(lockName, lockValue, expirationTimeMillis);
      return response.equalsIgnoreCase("OK");
  } catch (Exception exception) {
      releaseLock(lockName);
      throw exception;
  }
}

void releaseLock(String lockName) {
  String lockValue = createUniqueLockValue();
  // 移除鎖lockName,如果鎖的值是lockValue
  removeLockFromRedis(lockName, lockValue);
}

這種方式有什么問(wèn)題呢?

**假如客戶端1請(qǐng)求服務(wù)端獲取一個(gè)鎖,并指定了鎖超時(shí)時(shí)間,如果服務(wù)器響應(yīng)的時(shí)間大于鎖的超時(shí)時(shí)間,客戶端1拿到的則是一個(gè)過(guò)期的鎖,這時(shí)客戶端2同時(shí)可以獲取該鎖進(jìn)行業(yè)務(wù)操作。**這打破了分布式鎖應(yīng)該具備的相互排斥原則。

為了解決這個(gè)問(wèn)題,我們應(yīng)該給redis客戶端設(shè)置一個(gè)請(qǐng)求超時(shí)時(shí)間timeout,這個(gè)時(shí)間應(yīng)該小于鎖的超時(shí)時(shí)間。

當(dāng)時(shí)這還不能完全解決這個(gè)問(wèn)題,假設(shè)Redis服務(wù)器因?yàn)榈綦娭貑ⅲ瑒t會(huì)有其他的問(wèn)題,我們接下來(lái)看第二個(gè)場(chǎng)景。

場(chǎng)景二:?jiǎn)螌?shí)例Redis的單點(diǎn)故障

如果你對(duì)Redis的數(shù)據(jù)持久化方案有所了解,那一定知道Redis有兩種方式做數(shù)據(jù)持久化。

RDB(Redis Database):按指定的時(shí)間間隔將Redis的數(shù)據(jù)快照保存到磁盤。

AOF(Append-Only File):將服務(wù)器接收到的寫操作指令記錄下來(lái),這些操作指令在服務(wù)重啟時(shí)可以重新執(zhí)行來(lái)恢復(fù)原始數(shù)據(jù)。

默認(rèn)情況下,只會(huì)開(kāi)啟RDB模式,會(huì)按照如下方式配置:

save 900 1 

save 300 10 

save 60 10000

例如,第一行表示在900秒(15min)內(nèi)如果有一次寫操作,就將數(shù)據(jù)同步到數(shù)據(jù)文件。

所以在最壞的情況下,將一個(gè)加鎖數(shù)據(jù)保存需要15分鐘,如果在加鎖成功時(shí)Redis服務(wù)掉電重啟,則無(wú)法恢復(fù)內(nèi)存中的加鎖數(shù)據(jù),其它客戶端同樣可以獲取到相同的鎖

為了解決這個(gè)問(wèn)題,我們必須使用fsync=always選項(xiàng)來(lái)啟用AOF,然后在Redis中設(shè)置鍵。

注意,啟用這個(gè)選項(xiàng)對(duì)Redis的性能有一定的影響,但我們需要這個(gè)選項(xiàng)以保持強(qiáng)一致性。

場(chǎng)景三:主從復(fù)制

在這個(gè)配置中,我們有一個(gè)或多個(gè)實(shí)例(通常稱為從實(shí)例或副本),它們是主實(shí)例的精確副本。

默認(rèn)情況下,Redis中的復(fù)制是異步的;這意味著主服務(wù)器不會(huì)等待命令被副本處理完畢再返回給客戶端。

問(wèn)題是在復(fù)制發(fā)生之前,主服務(wù)器可能出現(xiàn)故障,并發(fā)生故障轉(zhuǎn)移;在此之后,如果另一個(gè)客戶端請(qǐng)求獲得鎖,它將成功!或者假設(shè)存在一個(gè)臨時(shí)的網(wǎng)絡(luò)問(wèn)題,因此其中一個(gè)副本沒(méi)有接收到命令,網(wǎng)絡(luò)變得穩(wěn)定,故障轉(zhuǎn)移很快發(fā)生;沒(méi)有接收到命令的節(jié)點(diǎn)成為主節(jié)點(diǎn)。

最終,該鎖將從所有實(shí)例中刪除!下圖說(shuō)明了這種情況:

作為解決方案,有一個(gè)等待命令,等待指定數(shù)量的確認(rèn)副本并返回副本的數(shù)量,承認(rèn)之前的寫命令發(fā)送等待命令,兩個(gè)的情況下達(dá)到指定數(shù)量的副本或者超時(shí)。

例如,如果我們有兩個(gè)副本,下面的命令最多等待1秒(1000毫秒)來(lái)從兩個(gè)副本獲得確認(rèn)并返回:

WAIT  2  1000

到目前為止,一切順利,但還有另一個(gè)問(wèn)題;副本可能會(huì)丟失寫入(由于錯(cuò)誤的環(huán)境)。例如,一個(gè)副本在保存操作完成之前失敗,同時(shí)主節(jié)點(diǎn)也失敗,故障轉(zhuǎn)移操作選擇重新啟動(dòng)的副本作為新的主節(jié)點(diǎn)。在與新主服務(wù)器同步后,所有副本和新主服務(wù)器都沒(méi)有舊主服務(wù)器中的密鑰!

為了使所有的從服務(wù)器和主服務(wù)器完全一致,我們應(yīng)該在獲得鎖之前為所有Redis實(shí)例啟用fsync=always的AOF。

注意:在這種方法中,我們?yōu)榱藦?qiáng)一致性而破壞了可用性,AOF會(huì)有一定的性能損耗。

場(chǎng)景四:自動(dòng)刷新的鎖

在這個(gè)場(chǎng)景中,只要客戶端是活的并且連接是正常的,就可以持有獲取的鎖。

我們需要一種機(jī)制來(lái)在鎖到期之前刷新鎖。我們還應(yīng)該考慮不能刷新鎖的情況;在這種情況下,必須立即退出。

此外,當(dāng)鎖的持有者釋放鎖時(shí),其他客戶端應(yīng)該能夠等待獲得鎖并進(jìn)入臨界區(qū):

小結(jié)

我這里通過(guò)四個(gè)小場(chǎng)景,引出了四個(gè)問(wèn)題,并給出相應(yīng)的解決辦法,但有一些重要的問(wèn)題還沒(méi)有解決我想在這里指出來(lái),希望在以后使用分布式鎖時(shí)作為參考。

不同節(jié)點(diǎn)之間的時(shí)鐘漂移問(wèn)題;獲取鎖之后客戶端出現(xiàn)長(zhǎng)線程的暫停或者進(jìn)程暫停;一個(gè)客戶端可能要等待很長(zhǎng)時(shí)間才能獲得鎖,而與此同時(shí),另一個(gè)客戶端會(huì)立即獲得鎖;非公平鎖。

許多三方庫(kù)使用Redis提供分布式鎖的服務(wù),我們應(yīng)該去了解它們是如何工作的以及可能發(fā)生的問(wèn)題,在它們的正確性和性能之間做出權(quán)衡。

到此這篇關(guān)于Redis分布式鎖存在的問(wèn)題的文章就介紹到這了,更多相關(guān)Redis分布式鎖存在的問(wèn)題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis請(qǐng)求處理的流程分析

    Redis請(qǐng)求處理的流程分析

    這篇文章主要介紹了Redis?是如何進(jìn)行請(qǐng)求處理,這篇文章介紹了整個(gè)?Redis?的請(qǐng)求處理模型到底是怎樣的。從注冊(cè)監(jiān)聽(tīng)?fd?事件到執(zhí)行命令,到最后將數(shù)據(jù)回寫給客戶端都做了個(gè)大概的分析,需要的朋友可以參考下
    2022-07-07
  • 淺談Redis緩存有哪些淘汰策略

    淺談Redis緩存有哪些淘汰策略

    redis用做緩存是一種非常常見(jiàn)的手段,然而由于內(nèi)存大小的限制,會(huì)導(dǎo)致redis在內(nèi)存空間滿了以后需要處理繼續(xù)存入的數(shù)據(jù),所以就需要淘汰策略,本文就詳細(xì)的介紹一下
    2021-08-08
  • Mac中Redis服務(wù)啟動(dòng)時(shí)錯(cuò)誤信息:NOAUTH Authentication required

    Mac中Redis服務(wù)啟動(dòng)時(shí)錯(cuò)誤信息:NOAUTH Authentication required

    這篇文章主要介紹了Mac中使用Redis服務(wù)啟動(dòng)時(shí)錯(cuò)誤信息:"NOAUTH Authentication required"問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Redis接口訪問(wèn)優(yōu)化的方法步驟

    Redis接口訪問(wèn)優(yōu)化的方法步驟

    本文基于之前的Redis接口訪問(wèn)進(jìn)行優(yōu)化,引入了接口防抖功能,通過(guò)時(shí)間段參數(shù)限制接口調(diào)用頻率,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • 詳解Redis中的BigKey如何發(fā)現(xiàn)和處理

    詳解Redis中的BigKey如何發(fā)現(xiàn)和處理

    這篇文章主要為大家詳細(xì)介紹了Redis中的BigKey如何發(fā)現(xiàn)和處理,文中給大家詳細(xì)講解了BigKey危害和如何解決這些問(wèn)題,文章通過(guò)代碼示例和圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • 深入理解redis_memcached失效原理(小結(jié))

    深入理解redis_memcached失效原理(小結(jié))

    這篇文章主要介紹了深入理解redis_memcached失效原理(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Redis中的BigKey問(wèn)題排查與解決思路詳解

    Redis中的BigKey問(wèn)題排查與解決思路詳解

    Redis是一款性能強(qiáng)勁的內(nèi)存數(shù)據(jù)庫(kù),但是在使用過(guò)程中,我們可能會(huì)遇到Big Key問(wèn)題,這個(gè)問(wèn)題就是Redis中某個(gè)key的value過(guò)大,所以Big Key問(wèn)題本質(zhì)是Big Value問(wèn)題,這篇文章主要介紹了Redis中的BigKey問(wèn)題:排查與解決思路,需要的朋友可以參考下
    2023-03-03
  • 淺談RedisTemplate和StringRedisTemplate的區(qū)別

    淺談RedisTemplate和StringRedisTemplate的區(qū)別

    本文主要介紹了RedisTemplate和StringRedisTemplate的區(qū)別及個(gè)人見(jiàn)解,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 關(guān)于在Redis中使用Pipelining加速查詢的問(wèn)題

    關(guān)于在Redis中使用Pipelining加速查詢的問(wèn)題

    這篇文章主要介紹了在Redis中使用Pipelining加速查詢,Redis是一個(gè)client-server模式的TCP服務(wù),也被稱為Request/Response協(xié)議的實(shí)現(xiàn),本文通過(guò)一個(gè)例子給大家詳細(xì)介紹,感興趣的朋友一起看看吧
    2022-05-05
  • redis刪除key下所有value步驟詳解

    redis刪除key下所有value步驟詳解

    在使用Redis時(shí),經(jīng)常需要?jiǎng)h除某個(gè)key下的所有value,本文就來(lái)詳細(xì)的介紹一下redis刪除key下所有value步驟,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01

最新評(píng)論

阿坝县| 本溪市| 靖江市| 龙川县| 康马县| 萍乡市| 石家庄市| 临夏县| 崇礼县| 象山县| 汉源县| 梅河口市| 垦利县| 长沙市| 鸡泽县| 乌拉特后旗| 南投市| 汝州市| 新疆| 岑溪市| 吉林市| 奉节县| 沁源县| 丹阳市| 徐水县| 宁津县| 永平县| 定州市| 长海县| 庆元县| 石首市| 郁南县| 隆子县| 水富县| 运城市| 嘉兴市| 南投县| 南宫市| 定安县| 扶绥县| 松溪县|