欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

redis分布式鎖與zk分布式鎖的對比分析

 更新時間:2022年11月18日 14:06:04   作者:進步的每一天  
這篇文章主要介紹了redis分布式鎖與zk分布式鎖的對比分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

在分布式環(huán)境下,傳統(tǒng)的jvm級別的鎖會失效,那么分布式鎖就是非常有必要的一個技術,一般我們可以通過redis,zk等技術來實現(xiàn)我們的分布式鎖

redis實現(xiàn)分布式鎖

原理

我們都知道redis的處理讀寫請求是單線程的,這種情況就不會發(fā)生并發(fā)的問題,其實實現(xiàn)起來很簡單,就是使用redis的 setnx 命令實現(xiàn),該命令如果redis中存在當前key,就會返回0,否者插入成功。

那么就可以獲取鎖的時候添加一個k-v值(任意的一個值)到redis,釋放鎖的時候就刪除,這樣就使用redis實現(xiàn)了一個分布式鎖,相當于分布式中所謂的鎖概念其實就相當一個redis或者zk中的一個值,有這個值就加鎖成功 

能實現(xiàn)的鎖類型

1、普通的鎖

2、讀寫鎖:大致就是給當前的key設置一個特定的值標識當前鎖是讀鎖還是寫鎖,讀與讀之間不互斥,相當與就是沒有鎖,讀與寫,寫于寫之間進行互斥,這個鎖的目的是為了解決緩存一致性的問題,這個問題下面來分析

3、紅鎖:底層原理涉及到redis半數(shù)寫入機制,針對主從架構中主節(jié)點掛了但是數(shù)據(jù)還未同步到從節(jié)點的問題,實現(xiàn)的方式就是當一半以上的節(jié)點都寫入成功了才返回給客戶端成功的提示,而不是主節(jié)點寫入成功就返回,但是這種情況下的效率比較慢

注意事項 

1、死鎖的情況:出現(xiàn)死鎖的情況有以下幾種情

(1)應用程序沒有正常的釋放鎖:比如程序拋出異常之類導致釋放鎖代碼沒有執(zhí)行; 

解決方案:需要把釋放鎖的代碼寫在finally模塊里面。

(2)鎖還沒有釋放redis宕機:這個時候本來應該刪除的key因為redis服務停掉了導致刪除不成功,出現(xiàn)死鎖的問題 

解決方案:給每一個key設置一個超時時間,超時了自動清除。

2、鎖永久失效的情況:出現(xiàn)原因是因為當前線程A還沒有運行完然后鎖因為過期時間的原因自動刪除了,這個時候其他線程B又能拿到這個鎖在redis中創(chuàng)建一個對應的k-v值,然后線程A執(zhí)行到釋放鎖的時候會刪除掉對應key的值,這個時候刪除的值是線程B對應的鎖,而不是線程A的,這樣在高并發(fā)的情況下就有可能導致鎖壓根不生效 

解決方案:在進行設值的時候,value值設置成能標識當前線程的一個值,比如在當前線程中創(chuàng)建一個uuid,然后在釋放鎖的時候也要比較value值,相同的情況就表示是當前線程對應的鎖,允許釋放,否則不允許釋放。

3、會存在鎖提前釋放的問題:當然這個問題也是引起上面第2個問題的根本原因,但是解決方案是不一樣的 

解決方案:在獲得鎖之后,處理業(yè)務邏輯的過程中,新建一個timer來定時的去重置鎖的生命周期,當然前提是當前業(yè)務邏輯還在執(zhí)行,這個定時的頻率一般設置為鎖生命周期的1/3,redisson中的 **看門狗 **其實內部就是這樣實現(xiàn)。 

4、主從結構中鎖丟失:上面 紅鎖 已經(jīng)說明了情況

zk實現(xiàn)分布式鎖

原理

zk實現(xiàn)分布式鎖的原理其實和redis很像,都是往里面插入對應的值,通過zk的create命令來實現(xiàn),zk中的值是通過樹形結構,類似與文件夾的層級目錄一樣,如果當前節(jié)點存在那么create命令就會執(zhí)行失敗,這種情況就代表其他的線程已經(jīng)獲取到了鎖,當前線程通過get -w /xxx的命令對當前鎖進行監(jiān)聽,如果當前鎖被其他線程釋放,那么當前線程會重新參與競爭鎖 

能實現(xiàn)的鎖類型

1、非公平鎖:就是通過create創(chuàng)建節(jié)點,誰創(chuàng)建成功誰就獲得了鎖,其他鎖對這個節(jié)點進行監(jiān)聽,當釋放鎖的時候,所有線程又來競爭這個鎖,但是這種情況會引發(fā)羊群效應,就是當一個節(jié)點被釋放的時候所有的線程都會來競爭,浪費性能

2、公平鎖:通過zk的臨時有序節(jié)點來實現(xiàn),當前線程創(chuàng)建一個臨時順序節(jié)點,然后判斷當前節(jié)點是不是最小的節(jié)點,如果時就獲得鎖,如果不是那么就監(jiān)聽他的上一個節(jié)點,等到釋放鎖的時候會通知后一個節(jié)點,然后重復以上判斷,這個就是公平鎖的實現(xiàn)方案,這樣就可以避免羊群效應,減輕服務器的壓力,但是這種情況可能會發(fā)生幽靈節(jié)點的產(chǎn)生導致死鎖

幽靈節(jié)點:就是客戶端發(fā)送創(chuàng)建命令之后,zk已經(jīng)成功創(chuàng)建,但是在響應的時候發(fā)生了宕機,這個時候客戶端以為沒有成功,但是服務器端實際上已經(jīng)有了,但是這個客戶端不知道,就不會去釋放,就造成了幽靈節(jié)點,通過 Protection模式能夠避免這個問題,這個的本質就是在節(jié)點前面加上一個唯一的標識,如uuid,人客戶端再次請求的時候會比較這個uuid,如果有就認為創(chuàng)建成功了,使用curator的protection模式原理就是這樣的,一下附一張公平鎖實現(xiàn)原理圖:

3、讀寫鎖:實現(xiàn)原理和公平鎖差不多,只是在創(chuàng)建每一個節(jié)點的時候標識當前節(jié)點時讀鎖(加read標識)還是寫鎖(加write標識)

兩種鎖的對比

分布式系統(tǒng)中通常要考慮CAP的,一致性,可用性和分區(qū)容錯性,很多場景下是很難同時保證CAP的,這個時候就得做出取舍,分布式鎖也是這樣的。

redis分布式鎖:

  • 優(yōu)點:性能高,能保證AP,保證其高可用,
  • 缺點:但是不能保證其一致性,原因就是在redis集群+主從的結構中,數(shù)據(jù)是通過分片存儲的,但是這個時候當一個master節(jié)點掛了之后,slave節(jié)點還未同步到master節(jié)點的數(shù)據(jù),導致數(shù)據(jù)丟失,萬一丟失的數(shù)據(jù)剛好是你的鎖,那么就有可能造成并發(fā)問題,所以不能保證強一致性,這種情況下可以通過redisson的紅鎖來解決,解決的原理其實就是redis的半數(shù)寫入機制,但是這樣完全降低了redis的性能,所以一般情況下是不采用的,zk其實能保證其一致性的原因就是其半數(shù)寫入機制加上其 leader選舉的邏輯實現(xiàn)

zk分布式鎖:

  • 優(yōu)點:能夠保證其一致性,每個節(jié)點的創(chuàng)建都會同時寫入leader和follwer節(jié)點,半數(shù)以上寫入成功才返回,如果leader節(jié)點掛了之后選舉的流程會優(yōu)先選舉zxid(事務Id)最大的節(jié)點,就是選數(shù)據(jù)最全的,又因為半數(shù)寫入的機制這樣就不會導致丟數(shù)據(jù)(ZAB協(xié)議)
  • 缺點:性能沒有redis高 

以上已經(jīng)說明了兩種分布式鎖實現(xiàn)的方式及其原理,怎么選擇以實際業(yè)務為準

緩存一致性:數(shù)據(jù)庫于緩存的結果不一樣

雙寫一致性問題(圖網(wǎng)上找的,懶得畫了)

讀寫一致性問題

解決方案:

(1)對于我們的用戶自己的訂單數(shù)據(jù),或者用戶信息數(shù)據(jù),或者說高并發(fā)場景下能容忍短時間的數(shù)據(jù)不一致,這些都可以采用添加過期時間(本來進入到緩存的數(shù)據(jù)就不要求強一致性,這種方式能解決大多數(shù)的情況,這種方式比較推薦也最常用)

(2)延遲雙刪:就是在更新了數(shù)據(jù)庫之后等一小段時間再刪除緩存(這種的缺點就是對于非高并發(fā)的請求,出現(xiàn)緩存一致性的問題概率本來就不大,但是卻人為的降低了代碼的性能)

(3)采用我們redis提供的分布式讀寫鎖,讀讀之間不阻塞,一旦有數(shù)據(jù)更新那么讀的操作就阻塞,等待更新+刪除緩存的操作結束之后再進行讀,這個情況雖然能真正的保證數(shù)據(jù)的一致性,但是加鎖了之后會進行阻塞,高并發(fā)情況下的性能就降低了

(4)使用阿里巴巴的cannal組件,類似于一個mysql的slave節(jié)點,監(jiān)聽著mysql的binlog日志文件,有變化就會主動的通知我們(推薦)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • 關于Redis的內存淘汰策略詳解

    關于Redis的內存淘汰策略詳解

    當內存空間使用達到限制時,Redis 會根據(jù)配置策略來選擇不同處理方式,要么返回 errors,要么按照不同的策略算法來清除一些舊數(shù)據(jù),達到回收內存的目的,這就是 Redis 的內存淘汰,有些文章中,內存淘汰也叫緩存回收,需要的朋友可以參考下
    2023-05-05
  • Redisson分布式限流的實現(xiàn)原理分析

    Redisson分布式限流的實現(xiàn)原理分析

    這篇文章主要介紹了Redisson分布式限流的實現(xiàn)原理分析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 詳解基于redis實現(xiàn)的四種常見的限流策略

    詳解基于redis實現(xiàn)的四種常見的限流策略

    限流算法在分布式領域是一個經(jīng)常被提起的話題,當系統(tǒng)的處理能力有限時, 如何阻止計劃外的請求繼續(xù)對系統(tǒng)施壓,這是一個需要重視的問題。除了控制流量,限流還有一個應用目的是控制用戶行為,避免垃圾請求
    2021-06-06
  • Redis概述及l(fā)inux安裝redis的詳細教程

    Redis概述及l(fā)inux安裝redis的詳細教程

    這篇文章主要介紹了Redis概述及l(fā)inux安裝redis的詳細教程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Redis的持久化方式

    Redis的持久化方式

    Redis提供了兩種主要的持久化方式:RDB和AOF,RDB通過定時快照的方式保存數(shù)據(jù)狀態(tài),而AOF記錄每個寫操作以便于重啟時重放,兩者可以結合使用,且在重啟時AOF文件會被優(yōu)先用于數(shù)據(jù)恢復,RDB快照具有速度快、節(jié)省磁盤空間的優(yōu)點,但可能會丟失最近的數(shù)據(jù)
    2024-10-10
  • Redis 有序集合的使用場景

    Redis 有序集合的使用場景

    在Redis的學習中,有序集合是一種非常實用的數(shù)據(jù)結構,本文就來介紹一下Redis 有序集合的使用場景,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Redis配置文件redis.conf詳細配置說明

    Redis配置文件redis.conf詳細配置說明

    本文列出了Redis的配置文件redis.conf的各配置項的詳細說明,簡單易懂
    2018-03-03
  • redis熱key問題怎樣解決

    redis熱key問題怎樣解決

    這篇文章主要介紹了redis熱key問題怎樣解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • redis的bigkey掃描腳本深入介紹

    redis的bigkey掃描腳本深入介紹

    這篇文章主要給大家介紹了關于redis的bigkey掃描腳本的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-07-07
  • redis key命名規(guī)范的設計

    redis key命名規(guī)范的設計

    如果結構規(guī)劃不合理、命令使用不規(guī)范,會造成系統(tǒng)性能達到瓶頸、活動高峰系統(tǒng)可用性下降,也會增大運維難度,本文主要介紹了redis key命名規(guī)范的設計,感興趣的可以了解一下
    2024-03-03

最新評論