91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis鎖的用法

發布時間:2021-07-20 17:58:09 來源:億速云 閱讀:289 作者:chen 欄目:大數據

這篇文章主要介紹“Redis鎖的用法”,在日常操作中,相信很多人在Redis鎖的用法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Redis鎖的用法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

對于分布式鎖的實現,除了redis鎖之外,還有很多,像zookeeper,memcache,數據庫,chubby等。redis鎖因為使用簡單,所以被大家廣泛使用。

本篇文章主要從以下幾個方面來講解redis鎖:

1.redis鎖使用的時候,有哪些問題2.這些問題會導致什么樣子的后果3.應該如何解決這些問題

一、redis鎖的實現

加鎖命令:

SETNX key value:當鍵不存在時,對鍵進行設置操作并返回成功1,否則返回失敗0。Key是鎖的唯一標識,一般按業務來決定命名;Value 往往用來比較加鎖的是哪一個線程或者哪一個消息,一般使用UUID.randomUUID().toString()方法生成。例如:setnx(key,1)

解鎖命令:

DEL key通過刪除鍵值對釋放鎖,以便其他線程可以通過 SETNX 命令來獲取鎖。例如:del(key)

鎖超時:

EXPIRE key timeout設置 key 的超時時間,以保證即使鎖沒有被顯式釋放,鎖也可以在一定時間后自動釋放,避免資源被永遠鎖住。例如:expire(key,30),表示30s超時釋放鎖。

備注:


Redis 2.6.12以上版本為set指令增加了可選參數,偽代碼如下:set(key,1,30,NX),它將加鎖和超時兩個動作合并到了一起,利用原子性封裝了起來。

二、redis鎖解決的具體場景

場景1: 為什么redis鎖需要設置超時?

原因分析:1.redis與業務進程之間通常是使用網絡通訊的方式進行數據加鎖的,而網絡通訊就存在丟包的情況。再加上加鎖和解鎖是兩個操作,這樣就會存在鎖永遠不能釋放的問題。2.除此之外業務進程在加鎖之后,也可能panic掉,沒有辦法去釋放掉這個鎖,導致分布式鎖被永遠掛住。
基于上面的兩個原因:分布式鎖就需要一個超時時間來主動釋放這個鎖,防止分布式鎖一直被掛住。
redis分布式鎖的解決辦法,1.通過加鎖和超時兩步操作來解決,不過我們最好使用set(key,1,30,NX)這種原子操作。2.使用setnx和expire兩個操作的話,因為它們不是原子性操作,也會存在上面1和2的問題,進而導致鎖被永遠鎖住,不過也不是沒有辦法,我們可以采用lua腳本在redis上面實現的方式來保證它們的原子性。

場景2: 鎖超時釋放了之后,加鎖的業務又過來釋放鎖怎么辦?

具體場景,進程1在超時釋放了鎖之后,進程2獲取到了鎖,后來進程1又釋放鎖,如此以來就有可能導致進程2沒有完成就被進程1釋放了鎖。如下所示:

Redis鎖的用法

解決上面問題的關鍵點,在于我們在釋放鎖的時候,能夠判斷出來是不是當前加鎖的進程發起的解鎖操作。
一般是將進程id作為vlaue放到setnx中,在解鎖之前先去判斷一把這個鎖是不是同一個進程的,是就允許釋放,不是就不允許解鎖。
備注:這種操作其實是兩步操作,判斷鎖,釋放鎖,它們并不是一個原子操作,如此以來就存在一步操作完成,另一步沒有被操作的情況。解決辦法是,利用lua腳本實現鎖的原子性。

場景3:鎖超時釋放之后,會不會存在兩個業務同時處理加鎖的代碼的情況?

這個場景與場景2是一個問題的延伸,一旦我們在設置鎖的超時時間過短,就會發生這個情況。

鎖在被進程2拿走之后,進程1還沒有執行代碼結束,如此以來就會存在進程1和進程2同時操作那段公共代碼的情況,這樣就會出問題,也顯然不是我們期望的場景。

對于這個場景的解決辦法,往往有兩個:

1.調整超時時間,讓業務進程在這段時間之內一定可以執行完畢。2.啟動守護進程,在業務進程沒有執行完成的時候,主動的去調節這個超時時間,讓鎖的超時時間變長。

場景4:鎖被使用之后,其他的業務如何才能獲取這個分布式鎖?

這個場景,是非常基本的場景,一旦鎖被進程1獲取之后,在釋放鎖之前,進程2是怎么知道何時才能夠獲取到鎖呢?

這個解決辦法有點像操作系統的輪詢和信號量兩種。

1.輪詢的話,就需要進程2不停的去超時加鎖,直到能夠加鎖成功位置,不過這種實現比較耗費服務器資源。2.類似信號量的方法,業務進程2將加鎖消息進行訂閱操作,而訂閱模塊會維護一個消息隊列,等到鎖釋放之后,便從隊列中取出進程2,告知鎖已經釋放的通知。進程2收到通知以后,就可以進行加鎖操作了。

場景5:redis是集群的話,使用redis分布式鎖會不會有問題?

為了保證redis的可用性,往往redis服務器會設置主從,主從服務器中的從服務器在檢測到主服務器掛掉之后,就會重新選舉一個作為主服務器,而redis鎖是操作在主服務器上的。

一旦,發生下面的現象:

1.主服務器剛剛被進程1加鎖完成,還沒有來得及同步數據到從服務器就掛掉了。2.從服務器經過選舉,選出了新的主服務器。3.進程2在新的主服務器上加鎖成功。4.如此以來進程1和進程2都會同時操作那段公共代碼,這樣就會存在問題,算是加鎖失敗。

針對這種問題,我們其實沒有太好的辦法,不過還好這種數據的概率比較低。

Redis 分布式鎖只能作為一種緩解并發的手段,要完全解決并發問題,仍需要數據庫的防并發手段配合使用。

到此,關于“Redis鎖的用法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

怀安县| 简阳市| 昌黎县| 宿松县| 建德市| 太仆寺旗| 彭阳县| 凤冈县| 泰安市| 开封县| 嘉善县| 达孜县| 凤翔县| 清新县| 嘉义市| 镇江市| 方城县| 察雅县| 台东市| 杭锦后旗| 柘荣县| 旌德县| 滨州市| 安义县| 政和县| 康平县| 曲靖市| 上林县| 泗水县| 徐水县| 丹巴县| 张家港市| 宁强县| 璧山县| 石楼县| 越西县| 衢州市| 壤塘县| 佛学| 洞头县| 防城港市|