寫在前面的話
2023年2月22日來杭,
杭州天氣不錯,
晴空萬里,氣溫回暖,
疫情彷佛散去,
而我開始了既定的跳槽,
投簡歷,刷面試片刻未敢停留。
一周下來也差不多面了10來家公司,
反饋還行,
但是並沒有想象中的那麼好,
總體來看杭州網際網路既沒有那麼好,
也沒有想象的那麼槽。
所以小夥伴們適度焦慮就ok,
重要的還是提公升自己的硬實力。
下面來講幾個面試碰到的有意思的問題吧。
如何確定分布式鎖的釋放時間?
描述:就是你在使用分布式鎖對**加乙個鎖,會不會業務沒有執行完,鎖釋放了?
我腦子一轉這種情況肯定不能讓他發生,不然不是併發了嗎。
此時你需要想一下分布式鎖的實現????
setnx??? set?
如果你說setnx我估計是要歇菜的,因為你剛好掉進面試官的乙個坑里,我們來看下setnx命令
沒有過期時間???沒有過期時間意味著鎖要我們自己手動釋放,看下偽**
if
(setnx(
'key',1
))catch(exception e)finally
}
假設在上述**的1或者4處出現異常,或者說是出現error,比如記憶體溢位,jvm直接不可用,那麼這個鎖是不是就釋放不掉了??別的執行緒就無法訪問這段**了,這就是死鎖的現象。基於這個問題,我們用什麼方式來解決呢?首先系統層面是無法解決的,但是我們可以用reids的過期策略來解決。比如說我們用別的redis的set命令
set key value [ex seconds] [px milliseconds] [nx|xx]分析上面的命令發現,其實並沒有合適的命令,具有過期時間的命令其實可以幫助我們解決系統異常出現的無法釋放鎖的問題,但是這些命令其實是可以重複set的,所以可以認為沒有排他性,有的同學可能會說在set前先get一下,但是如果get出現併發其實還是可以有多個執行緒可以獲得到鎖的。將字串值 value 關聯到 key 。
如果 key 已經持有其他值, set 就覆寫舊值,無視型別。
對於某個原本帶有生存時間(ttl)的鍵來說, 當 set 命令成功在這個鍵上執行時, 這個鍵原有的 ttl 將被清除。
可選引數
從 redis 2.6.12 版本開始, set 命令的行為可以通過一系列引數來修改:
ex second :設定鍵的過期時間為 second 秒。 set key value ex second 效果等同於 setex key second value 。
px millisecond :設定鍵的過期時間為 millisecond 毫秒。 set key value px millisecond 效果等同於 psetex key millisecond value 。
nx :只在鍵不存在時,才對鍵進行設定操作。 set key value nx 效果等同於 setnx key value 。
xx :只在鍵已經存在時,才對鍵進行設定操作。
當然我們使用的分布式鎖還有通過redisson實現的,這個是有過期時間的,那麼這個過期時間是否導致我們的業務沒走完,鎖釋放了?同樣不存在的,redisson在獲取鎖之後,會維護乙個看門狗,當鎖即將過期還沒有釋放時,看門狗會給過期時間進行續航。
結論:無論是使用setnx命令還是redisson都無法解決這種極端情況的死鎖現象。但是這種場景是極端情況發生的,而且一旦發生,我們的應用都不可用了,死鎖的問題就相對較輕了,我們應該抓緊恢復我們的服務,死鎖手動釋放下就好了。
分布式鎖一定安全嗎???
答:不一定。我們來看乙個簡單的主從獲取鎖的流程
我們考慮一種情況,在應用程式獲取鎖之後,還沒來得及複製到從節點時,主節點下線了,這時會進行故障轉移,主從節點的角色會調換,那麼此時新的主節點肯定是還沒有鎖的key的,那麼客戶端的請求過來時肯定會再次獲得鎖成功。
上面的問題客觀存在,不了解故障轉移的看下我這篇文章redis哨兵
這個問題同樣無法解決,但是這種情況發生的概率極低,他要滿足兩種情況
獲取鎖成功後redis主節點不可用
故障轉移後的主節點沒有完全複製完資料
其實這種情況的概率是極低的,首先故障轉移之前會做客觀下線與主管下線判斷,還會進行領頭哨兵的選舉,這個過程給了一定的主從複製的時間,其次故障轉移挑選出的新的主節點肯定是複製偏移量最大的,這也降低了新的主節點丟失資料的風險。
最後不懂主從複製的可以看下我的這篇文章redis主從複製
掃碼關注
使用redis構建可靠分布式鎖
關於分布式鎖的概念,具體實現方式,直接參閱下面兩個帖子,這裡就不多介紹了。分布式鎖的多種實現方式 分布式鎖總結 對於分布式鎖的幾種實現方式的優劣,這裡再列舉下 1.資料庫實現方式 優點 易理解 缺點 運算元據庫消耗較大,效能較低。為了處理一些異常,會使得整個方案越來越複雜 2.快取實現方式 優點 效...
redis分布式鎖
redis分布式鎖 直接上 我寫了四個redis分布式鎖的方法,大家可以提個意見 第一種方法 redis分布式鎖 param timeout public void lock long timeout thread.sleep 100 catch exception e override publi...
Redis分布式鎖
分布式鎖一般有三種實現方式 1.資料庫樂觀鎖 2.基於redis的分布式鎖 3.基於zookeeper的分布式鎖.首先,為了確保分布式鎖可用,我們至少要確保鎖的實現同時滿足以下四個條件 互斥性。在任意時刻,只有乙個客戶端能持有鎖。不會發生死鎖。即使有乙個客戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保...