域名備案代理石家莊seo管理
在分布式系統(tǒng)下,涉及到多個(gè)節(jié)點(diǎn)訪問同一個(gè)公共資源的情況,此時(shí)需要通過 鎖 進(jìn)行互斥控制:避免出現(xiàn) 線程安全問題。
1.分布式鎖的基本實(shí)現(xiàn)
超賣問題:
解決:
采用redis實(shí)現(xiàn)分布式鎖
可用采取:在購票的時(shí)候,操作過程中需要先加鎖。在redis上設(shè)置一個(gè)key - value,完成上述買票操作,再把key - value 刪掉。如果發(fā)現(xiàn)key - value 存在,就加鎖失敗,無法進(jìn)行購票
上述可用保證,第一個(gè)服務(wù)器執(zhí)行(查詢 - 更新)過程中,第二個(gè)服務(wù)器不會(huì)執(zhí)行 (查詢)操作
具體實(shí)現(xiàn):
redis中的setnx命令(不存在就設(shè)置進(jìn)去,當(dāng)前key值存在就失敗)解鎖使用del
考慮一下特殊情況:
某個(gè)服務(wù)器加鎖成功后,在執(zhí)行后續(xù)邏輯的過程中,程序崩潰了,沒有執(zhí)行到解鎖操作?
不可以采取finally:這種做法只是針對(duì)進(jìn)程內(nèi)的鎖有用,針對(duì)分布式鎖無效,比如說服務(wù)器直接掉電,進(jìn)程異常終止,后面的del邏輯都走不到~
還可以使用過期時(shí)間來實(shí)現(xiàn)~
給set的key設(shè)置一個(gè)過期時(shí)間,時(shí)間到了key自動(dòng)被刪去了。
可以使用 set ex nx
異常情況:
這個(gè)時(shí)候還有一個(gè)問題,服務(wù)器1給redis上鎖,服務(wù)器2給解鎖了,會(huì)引起超賣問題
為了解決上述問題,就需要加入校驗(yàn)機(jī)制
1、給服務(wù)器編號(hào),每個(gè)服務(wù)器有自己的身份標(biāo)識(shí)
2、進(jìn)行加鎖的時(shí)候,設(shè)置key-value。key對(duì)應(yīng)著要針對(duì)哪一個(gè)資源進(jìn)行加鎖~,value就可以存儲(chǔ)剛才服務(wù)器的編號(hào)~~這樣可以表示出,這個(gè)鎖是哪一個(gè)服務(wù)器加上的。
因此后續(xù)解鎖的時(shí)候,就可以進(jìn)行校驗(yàn)了。
1、解鎖的時(shí)候,先查詢一下這個(gè)鎖對(duì)應(yīng)的服務(wù)器編號(hào),然后判定一下這個(gè)編號(hào) 是否就是 當(dāng)前執(zhí)行的解鎖的服務(wù)器編號(hào)。
2、如果是 ,才去執(zhí)行del,如果不是,則失敗
?問題:解鎖時(shí),查詢判定和del是非原子操作
一個(gè)服務(wù)器內(nèi)部,這是倆個(gè)行為,會(huì)出現(xiàn)線程安全問題,可以使用lua腳本實(shí)現(xiàn)原子性
但上述還有問題:設(shè)置過期時(shí)間后,仍然存在一定的可能性,任務(wù)沒執(zhí)行完,key先過期了,導(dǎo)致鎖提前失效。也就是過期時(shí)間的續(xù)約問題
這樣負(fù)責(zé)動(dòng)態(tài)續(xù)約 專門獨(dú)立出來的 線程 叫 看門狗
高可用
如果使用redis作為分布式鎖,還需要考慮redis掛了的情況,因此要想保證高可用需要一套預(yù)案去保證高可用。
搞幾個(gè)哨兵節(jié)點(diǎn)
redlock算法
簡(jiǎn)而言之:冗余
?具體展現(xiàn)為:
?