Redis-分布式鎖!

分布式鎖,顧名思義,分布式鎖就是分布式場景下的鎖,比如多臺不同機器上的進程,去競爭同一項資源,就是分布式鎖。

分布式鎖特性

互斥性:鎖的目的是獲取資源的使用權,所以只讓一個競爭者持有鎖,這一點要盡可能保證;

安全性:避免鎖因為異常永遠不被釋放。當一個競爭者在持有鎖期間內,由于意外崩潰而導致未能主動解鎖,其持有的鎖也能夠被兜底釋放,并保證后續其它競爭者也能加鎖;

對稱性:同一個鎖,加鎖和解鎖必須是同一個競爭者。不能把其他競爭者持有的鎖給釋放了。

可靠性:需要有一定程度的異常處理能力、容災能力。
?

分布式鎖的實現

?

1.直接用Redis的setnx命令

首先,當然是搭建一個最簡單的實現方式, 直接用Redis的setnx命令, 這個命令的語法是: setnx key value如果key不存在,則會將key設置為value,并返回1;如果key存在,不會有任務影響,返回0。
基于這個特性,我們就可以用setnx實現加鎖的目的:通過setnx加鎖,加鎖之后其他服務無法加鎖,用完之后,再通過delete解鎖

就是這個獲取鎖的過程就是setnx的過程?如果有鎖了?那就會返回0?如果沒鎖?就會把key設置為value然后釋放鎖就會delete

2.支持過期時間

最簡化版本有一個問題:如果獲取鎖的服務掛掉了,那么鎖就一直得不到釋放,就像石沉大海,查無音信。所以,我們需要一個超時來兜底。
Redis中有expire命令,用來設置一個key的超時時間。 但是setnx和expire不具備 原子性,如果setnx獲取鎖之后,服務掛掉(還沒來的及設置時間),依舊是泥牛入海。
很自然,我們會想到,set和expire, 有沒有原子操作?
當然有,Redis早就考慮到了這種場景,推出了如下執行語句: set key value nx ex seconds nx表示具備setnx特定,ex表示增加了過期時間,最后一個參數就是過期時間的值。

他把set和expire合成了一個原子操作

這個過期和釋放鎖是并列的?就是主動釋放鎖和過期都會delete

3.加上Owner

我們來試想一下如下場景:服務A獲取了鎖,由于業務流程比較長,或者網絡延遲、GC卡頓等原因,導致鎖過期,而業務還會繼續進行。這時候,業務B已經拿到了鎖,準備去執行,這個時候服務A恢復過來并做完了業務,就會釋放鎖,而B卻還在繼續執行。
在真實的分布式場景中,可能存在幾十個競爭者,那么上述情況發生概率就很高,導致同一份資源頻繁被不同競爭者同時訪問,分布式鎖也就失去了意義
基于這個場景,我們可以發現,問題關鍵在于,競爭者可以釋放其他人的鎖。(也就是說?只能這個鎖持有者自己釋放了鎖才行?就是這個delete過程?只能自己來刪除?而不能其他線程刪除)那么在異常情況下,就會出現問題,所以我們可以進一步給出解決方案: 分布式鎖需要滿足誰申請誰釋放原則,不能釋放別人的鎖,也就是說,分布式鎖,是要有歸屬的。

我們獲取鎖之前不是會有一個delete釋放鎖的過程嗎??我們讓其他線程沒法執行這個delete操作?只有我鎖持有者可以delete

具體步驟?釋放前先檢測是否是持有者要delete?然后返回檢查結果?然后再根據結果進行操作


4.引入LUA


釋放前先檢測是否是持有者要delete?然后返回檢查結果?然后再根據結果進行操作

這三步不是原子的

我們來看?檢測和返回結果之間的間隙

這個同時鎖過期了?

檢測?這鎖過期釋放了鎖?且有其他客戶端獲取到了鎖?然后返回結果? 刪除鎖?

這個時候?已經判斷完了它是自己的鎖?他就會刪除這個鎖

這就造成了鎖的誤刪

然后LUA給這仨操作合成原子操作了

(其實owner )

分布式鎖的可靠性靠什么保證

主從容災

emmm?就是主庫寄了?用從庫頂一頂先

但是主從切換,需要人工參與,會提高人力成本。不過Redis已經有成熟的解決方案,也就是哨兵模式,可以靈活自動切換,不再需要人工介入。

一堆箭頭亂七八糟的?描述一下?每個哨兵會監視其他兩個哨兵的?同時還會監視主庫和兩個從庫?

通過增加從節點的方式,雖然一定程度解決了單點的容災問題,但并不是盡善盡美的,由于同步有時延,Slave可能會損失掉部分數據,分布式鎖可能失效,這就會發生短暫的多機獲取到執行權限。

更妥善的方法

多機部署

如果對一致性的要求高一些, 可以嘗試多機部署,比如Redis的RedLock, 大概的思路就是多個機器,通常是奇數個,達到一半以上同意加鎖才算加鎖成功,這樣,可靠性會向ETCD靠近。
現在假設有5個Redis主節點,基本保證它們不會同時宕掉,獲取鎖和釋放鎖的過程中,客戶端會執行以下操作:
1.向5個Redis申請加鎖;
2.只要超過一半,也就是3個Redis返回成功,那么就是獲取到了鎖。如果超過一半失敗, 需要向每個Redis發送解鎖命令;
3.由于向5個Redis發送請求,會有一定時耗,所以鎖剩余持有時間,需要減去請求時間。這個可以作為判斷依據,如果剩余時間已經為0,那么也是獲取鎖失敗:
4.使用完成之后,向5個Redis發送解鎖請求。
這種模式的好處在于,如果掛了2臺Redis,整個集群還是可用的,給了運維更多時間來修復。

(這種方法太重了?業務很少會用的到)

?

分布式系統三大困境

簡稱NPC

這種模式的好處在于,如果掛了2臺Redis,整個集群還是可用的,給了運維更多時間來修復。
另外,多說一句,單點Redis的所有手段,這種多機模式都可以使用,比如為每個節點配置哨兵模式,由于加鎖是
-半以上同意就成功,那么如果單個節點進行了主從切換,單個節點數據的丟失,就不會讓鎖失效了。這樣增強了
可靠性。
N:Network Delay (網絡延遲)當分布式鎖獲得返回包的時間過長,此時可能雖然加鎖成功,但是已經時過境遷,鎖可能很快過期。RedLock算 了做了些考量,也就是前面所說的鎖剩余持有時間,需要減去請求時間,如此一來,就可以一定程度解決網絡延遲的問題。
P: Process Pause (進程暫停)比如發生GC,獲取鎖之后GC了,處于GC執行中,然后鎖超時。其他鎖獲取,這種情況幾乎無解。這時候GC回來了,那么兩個進程就獲取到了同一個分布式鎖。

也許你會說,在GC回來之后,可以再去查一次啊?
這里有兩個問題,首先你怎么知道GC回來了?這個可以在做業務之前,通過時間,進行一個粗略判斷,但也是很吃場景經驗的;第二,如果你判斷的時候是ok的,但是判斷完GC了呢?這點RedLock是無法解決的。
?

C: Clock Drift (時鐘漂移)
如果競爭者A,獲得了RedLock,在5臺分布式機器上都加上鎖。為了方便分析,我們直接假設5臺機器都發生了時鐘漂移,鎖瞬間過期了。這時候競爭者B拿到了鎖,此時A和B拿到了相同的執行權限。
根據上述的分析.可以看出,RedLock也不能扛住NPC的挑戰,因此,單單從分布式鎖本身出發,完全可靠是不可能的。要實現一個相對可靠的分布式鎖機制,還是需要和業務的配合,業務本身要冪等可重入,這樣的設計可以省卻很多麻煩。
?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40373.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40373.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40373.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PyTorch: clamp函數與梯度的關系

本文主要以下探究這一點:梯度反向傳播過程中,測試強行修改后的預測結果是否還會傳遞loss? clamp應用場景:在深度學習計算損失函數的過程中,會有這樣一個問題,如果Label是1.0,而預測結果是0.0&a…

【算法】排序+雙指針——leetcode三數之和、四數之和

三數之和 (1)排序雙指針 算法思路: 和之前的兩數之和類似,我們對暴力枚舉進行了一些優化,利用了排序雙指針的思路: 我們先排序,然后固定?個數 a ,接著我們就可以在這個數后面的區間…

Mybatis Plus Interceptor

Mybatis Plus Interceptor 1 獲取表名2 獲取SQL 1 獲取表名 Component public class MybatisInterceptor implements Interceptor {private static final List<String> EXCLUDE_TABLE new ArrayList<>();static {EXCLUDE_TABLE.add("test");}private s…

OpenCV實例(九)基于深度學習的運動目標檢測(一)YOLO運動目標檢測算法

基于深度學習的運動目標檢測&#xff08;一&#xff09; 1.YOLO算法檢測流程2.YOLO算法網絡架構3.網絡訓練模型3.1 訓練策略3.2 代價函數的設定 2012年&#xff0c;隨著深度學習技術的不斷突破&#xff0c;開始興起基于深度學習的目標檢測算法的研究浪潮。 2014年&#xff0c;…

電腦突然黑屏的解決辦法

記錄一次電腦使用問題 問題描述 基本情況&#xff1a;雷神游戲筆記本 windows10操作系統 64位 使用時間 4年 日期&#xff1a;2023年8月11日 當時 電腦充著電 打開了兩個瀏覽器&#xff1a;edge[頁面加載5個左右]&#xff0c;火狐[頁面加載1個左右] 兩個文件夾 一個百度網盤…

Davinci 報表工具 0.3.0-rc release 文本框模糊查詢不生效問題

背景: 在使用過程中發現davinci 的控制器配置中, 取值配置的對應關系設置 包含 或 不包含時 不生效, 不能實現模糊匹配效果, 只能精確查詢; 問題分析: 通過跟蹤接口及相應代碼, 發現在sql 拼接時沒有對 like 和 not like 類型的值兩側添加百分號, 導致模糊查詢失敗 調用過程…

CentOS系統環境搭建(七)——Centos7安裝MySQL

centos系統環境搭建專欄&#x1f517;點擊跳轉 坦誠地說&#xff0c;本文中百分之九十的內容都來自于該文章&#x1f517;Linux&#xff1a;CentOS7安裝MySQL8&#xff08;詳&#xff09;&#xff0c;十分佩服大佬文章結構合理&#xff0c;文筆清晰&#xff0c;我曾經在這篇文章…

Kotlin 使用 View Binding

解決的問題&#xff1a; 《第一行代碼——Android》第三版 郭霖 P277 視圖綁定的問題 描述&#xff1a; kotlin-android-extensions 插件已經棄用 butter knife 已經棄用 解決辦法 推薦使用 View Binding 來代替 findViewById 使用方法 1、配置 build.gradle 2、在act…

踩坑---uni-app中@input 事件不生效

在開發的時候遇到這么一種情況&#xff0c;我們希望input輸入框的值是范圍是0-100或者保留兩位小數之類的&#xff0c;當你輸入時處理后的結果卻不生效&#xff0c;但是試過很多辦法發現都實現不了&#xff0c;最后是按照以下方法解決的,問題原因是uni-app會延時,導致輸入的結果…

Go語言的主要優勢

Go語言的主要優勢包括: 1. 簡潔和易學 Go語法簡單明了,沒有太多晦澀難懂的概念,上手容易,適合快速開發。 2. 強大的并發支持 利用goroutine和channel,可以非常方便地編寫高效的并發程序。 3. 執行性能好 Go編譯成機器碼,執行性能接近C/C,比解釋型語言更高效。 4. 內存管…

絕對值函數的可導性

絕對值函數的可導性 聲明&#xff1a;下面截圖來自《考研數學常考題型解題方法技巧歸納》

利用Figlet工具創建酷炫Linux Centos8服務器-登錄歡迎界面-SHELL自動化編譯安裝代碼

因為我們需要生成需要的特定字符,所以需要在當前服務器中安裝Figlet,默認沒有安裝包的,其實如果我們也只要在一臺環境中安裝,然后需要什么字符只要復制到需要的服務器中,并不需要所有都安裝。同樣的,我們也可以利用此生成的字符用到腳本運行的開始起頭部分,用ECHO分行標…

學習筆記十八:污點、容忍度

污點、容忍度 污點、容忍度管理節點污點把k8snode2當成是生產環境專用的&#xff0c;其他node是測試的給k8snode1也打上污點 污點、容忍度 給了節點選則的主動權&#xff0c;我們給節點打一個污點&#xff0c;不容忍的pod就運行不上來&#xff0c;污點就是定義在節點上的鍵值屬…

使用python讀Excel文件并寫入另一個xls模版

效果如下&#xff1a; 原文件內容 轉化后的內容 大致代碼如下&#xff1a; 1. load_it.py #!/usr/bin/env python import re from datetime import datetime from io import BytesIO from pathlib import Path from typing import List, Unionfrom fastapi import HTTPExcep…

睿趣科技:抖音開網店現在做還來得及嗎

隨著社交媒體的迅速發展&#xff0c;抖音作為一款短視頻平臺&#xff0c;已經在年輕人中間取得了巨大的成功。而近年來&#xff0c;越來越多的人開始考慮在抖音上開設網店&#xff0c;以迎合這一潮流。那么&#xff0c;抖音開網店現在還來得及嗎? 首先&#xff0c;要明確的是&…

一篇文章教會你搭建私人kindle圖書館,并內網穿透實現公網訪問

搭建私人kindle圖書館&#xff0c;并內網穿透實現公網訪問 在電子書風靡的時期&#xff0c;大部分人都購買了一本電子書&#xff0c;雖然這本電子書更多的時候是被擱置在儲物架上吃灰&#xff0c;或者成為蓋泡面的神器&#xff0c;但當亞馬遜發布消息將放棄電子書在中國的服務…

Kubernetes部署Wordpress時碰到的兩個問題解決

文章目錄 小結問題1解決問題2解決參考 小結 在使用Kubernetes部署Wordpress時返回了兩個問題: Function not implemented: AH00141: Could not initialize random number generator chown: changing ownership of .: Operation not permitted 對這個兩個返回錯誤&#xff0…

利用Python隧道爬蟲ip輕松構建全局爬蟲網絡

嘿&#xff0c;爬蟲程序員們&#xff01;你們有沒有碰到過需要大規模數據爬取的情況&#xff1f;也許你們之前遇到過網站的反爬措施&#xff0c;卡住你們的進度。別擔心&#xff0c;今天我來分享一個利用Python隧道爬蟲ip實現的方法&#xff0c;幫助你們輕松搭建全局爬蟲ip網絡…

jmeter界面設置為中文

jmeter版本&#xff1a;5.6.2 找到jmeter下的bin目錄&#xff0c;打開jmeter.properties 文件 第39行修改為 languagezh_CN去掉前面的#&#xff0c;以后打開就是中文界面了

IC設計仿真云架構

對于IC仿真來說&#xff0c;最重要的是要安全、可維護、高性能的的HPC環境環境。 那么云上如何搭建起一套完整的IC仿真云環境呢&#xff1f; 這種架構應該長什么樣子&#xff1f; 桌面虛擬化基礎架構 將所有桌面虛擬機在數據中心進行托管并統一管理&#xff1b;同時用戶能夠…