偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

還不知道 Redis 分布式鎖的背后原理?還不趕快學(xué)習(xí)一下

存儲(chǔ) 分布式 Redis
以前在學(xué)校做小項(xiàng)目的時(shí)候,用到Redis,基本也只是用來(lái)當(dāng)作緩存。可阿粉在工作中發(fā)現(xiàn),Redis在生產(chǎn)中并不只是當(dāng)作緩存這么簡(jiǎn)單。

 [[321595]]

以前在學(xué)校做小項(xiàng)目的時(shí)候,用到Redis,基本也只是用來(lái)當(dāng)作緩存。可阿粉在工作中發(fā)現(xiàn),Redis在生產(chǎn)中并不只是當(dāng)作緩存這么簡(jiǎn)單。在阿粉接觸到的項(xiàng)目中,Redis起到了一個(gè)分布式鎖的作用,具體情況是這樣的:

該項(xiàng)目在某金融平臺(tái)中負(fù)責(zé)某塊業(yè)務(wù),是一個(gè)分布式系統(tǒng),線上大概跑著10個(gè)左右的實(shí)例。其中有一個(gè)步驟需要用戶(hù)支付一定的費(fèi)用,Redis分布式鎖在其中大概處于這么一個(gè)位置:

 

可以看到在上分布式鎖之后,系統(tǒng)做了兩個(gè)查詢(xún)校驗(yàn),然后向數(shù)據(jù)庫(kù)中插入了一條訂單記錄,接著才解鎖進(jìn)入支付流程。

從業(yè)務(wù)的角度考慮分布式鎖是好理解的,它保證了查詢(xún)及插入數(shù)據(jù)整個(gè)流程的原子性,防止查詢(xún)校驗(yàn)的時(shí)候查到臟數(shù)據(jù),使得支付前訂單信息落表的操作串行化執(zhí)行。

盡管從業(yè)務(wù)上來(lái)說(shuō)很好理解,但使用Redis作為分布式鎖對(duì)我來(lái)說(shuō)是個(gè)新知識(shí),阿粉打算結(jié)合項(xiàng)目中的代碼,深挖一下這個(gè)知識(shí)點(diǎn)。

正文

1. 為什么要使用分布式鎖

在實(shí)際項(xiàng)目中見(jiàn)過(guò)分布式鎖后,就不難理解為什么要使用分布式鎖了:總結(jié)來(lái)說(shuō)就是分布式系統(tǒng)要訪問(wèn)共享資源,為了避免并發(fā)訪問(wèn)資源帶來(lái)錯(cuò)誤,我們?yōu)楣蚕碣Y源添加一把鎖,讓各個(gè)訪問(wèn)互斥,保證并發(fā)訪問(wèn)的安全性,這就是使用分布式鎖的原因。

2. Redis中分布式鎖的實(shí)現(xiàn)

redis中使用分布式鎖很簡(jiǎn)單,只要使用setnx指令對(duì)某個(gè)key上鎖就行:

  1. setnx lock test //上鎖 
  2. del lock test   //解鎖 

當(dāng)某個(gè)key沒(méi)有被占用的時(shí)候,setnx指令會(huì)返回1,否則返回0,這就是Redis中分布式鎖的使用原理。

當(dāng)然我們還可以在上鎖之后使用expire指令給鎖設(shè)置過(guò)期時(shí)間。

看到這里你可能會(huì)有疑問(wèn),如果我們的程序流程不使用指令解鎖,靠redis設(shè)置時(shí)間過(guò)期來(lái)解鎖,貌似會(huì)出問(wèn)題。假如我們的服務(wù)進(jìn)程在執(zhí)行setnx之后和執(zhí)行expire指令之前掛掉了,那這個(gè)鎖豈不是永遠(yuǎn)都不能被釋放?

 

沒(méi)錯(cuò),這確實(shí)是個(gè)問(wèn)題,當(dāng)時(shí)人們?cè)赗edis的開(kāi)源社區(qū)提出了一堆解決方案專(zhuān)門(mén)來(lái)解決這個(gè)問(wèn)題,可實(shí)現(xiàn)方式都極為復(fù)雜。后來(lái)Redis的作者在Redis 2.8版本中加入了set指令的擴(kuò)展參數(shù),使得setnx指令和expire指令能夠同時(shí)執(zhí)行,具體使用像下面這個(gè)樣子:

 

  1. set lock test ex 5 nx 
  2. ex:設(shè)置鍵的過(guò)期時(shí)間 
  3. nx:只在鍵不存在時(shí),才對(duì)鍵進(jìn)行設(shè)置操作 

從此以后,Redis成為了分布式鎖的寵兒。

3. 分布式鎖在Redis集群中遇到的麻煩

在學(xué)習(xí)了Redis中分布式鎖的使用后,很快我們便發(fā)現(xiàn)了新的問(wèn)題。在企業(yè)中,Redis基本上都是集群部署的,集群部署避免不了要面對(duì)某個(gè)節(jié)點(diǎn)宕機(jī)的問(wèn)題。

我們考慮這么一種情況:假設(shè)我們?cè)趓edis的主節(jié)點(diǎn)上添加了一把分布式鎖,不幸的是主節(jié)點(diǎn)掛掉了,而且主節(jié)點(diǎn)上的鎖還沒(méi)有同步到從節(jié)點(diǎn)上,如果此時(shí)有客戶(hù)端來(lái)請(qǐng)求獲得同一把鎖,那么它將順利地獲得鎖,之前那把鎖會(huì)被無(wú)情地忽視掉,這就是分布式鎖在Redis集群中遇到的麻煩。

 

Redis的作者為了解決這個(gè)問(wèn)題提出了一個(gè)叫Redlock的算法,它的原理是這樣的:當(dāng)上鎖的時(shí)候,把set指令發(fā)送給過(guò)半的節(jié)點(diǎn),只要過(guò)半的鎖set成功,就認(rèn)為這次加鎖成功;當(dāng)解鎖的時(shí)候,會(huì)向所有的節(jié)點(diǎn)發(fā)送del指令。

從這個(gè)算法的原理可以看出,由于Redlock需要同時(shí)對(duì)多個(gè)節(jié)點(diǎn)進(jìn)行讀寫(xiě),因此使用Redlock加分布式鎖的性能要比單機(jī)Redis低很多。因?yàn)橹鲝膹?fù)制出紕漏的概率極低,所以如果對(duì)分布式加鎖過(guò)程有一定的容錯(cuò)率的話(huà),可以考慮直接使用set指令;如果追求高可用性,可以考慮使用Redlock算法。

當(dāng)然,高可用性的分布式鎖不只有Redis的Redlock,我們還可以用zookeeper或者支持事務(wù)的數(shù)據(jù)庫(kù)做分布式鎖。

❝簡(jiǎn)述zookeeper的分布式鎖原理:假設(shè)zk用某個(gè)節(jié)點(diǎn)作為分布式鎖,當(dāng)不同的客戶(hù)端到zk競(jìng)爭(zhēng)這把鎖的時(shí)候,zk會(huì)按順序給不同的客戶(hù)端創(chuàng)建一個(gè)子節(jié)點(diǎn),掛在作為分布式鎖的節(jié)點(diǎn)下面。假設(shè)第一個(gè)來(lái)到的客戶(hù)端為A,第二個(gè)來(lái)到的是B,分布式節(jié)點(diǎn)下掛的第一個(gè)節(jié)點(diǎn)就是A,B緊跟著A,且B會(huì)監(jiān)聽(tīng)著A的生命狀態(tài),當(dāng)A釋放鎖后A會(huì)被刪除,這時(shí)B監(jiān)聽(tīng)到A被刪除,B接能上位獲得分布式鎖了。❞

在公司的項(xiàng)目中,雖然Redis是以集群的方式部署的,但還是使用最基本的set指令獲取分布式鎖,因?yàn)檫@種方式的性能遠(yuǎn)遠(yuǎn)高于Redlock算法,也高于zk,數(shù)據(jù)庫(kù)等分布式鎖實(shí)現(xiàn)方式。

雖然在高性能與低概率的錯(cuò)誤中選擇了高性能,但項(xiàng)目中還是做了其他工作對(duì)錯(cuò)誤情況進(jìn)行兜底的,比如在公司的項(xiàng)目中對(duì)主從復(fù)制時(shí)的錯(cuò)誤情況會(huì)拋出異常,然后根據(jù)異常會(huì)進(jìn)行一些重試的操作。

總結(jié)

這次對(duì)Redis分布式鎖的探索算是加深了自己對(duì)Redis的理解,但我知道Redis的用處還遠(yuǎn)遠(yuǎn)不止分布式鎖和緩存,留著后面繼續(xù)探索吧。

 

責(zé)任編輯:華軒 來(lái)源: Java極客技術(shù)
相關(guān)推薦

2016-07-22 17:55:07

云計(jì)算

2022-09-19 18:32:22

函數(shù)編程語(yǔ)言

2022-07-17 06:53:24

微服務(wù)架構(gòu)

2024-03-07 07:58:26

Web開(kāi)發(fā)響應(yīng)媒體查詢(xún)工具

2022-05-05 12:02:45

SCSS函數(shù)開(kāi)發(fā)

2010-03-12 09:15:28

Firefox新功能

2025-08-18 02:55:00

Spring數(shù)據(jù)庫(kù)容器

2018-09-02 15:43:56

Python代碼編程語(yǔ)言

2020-12-14 07:51:16

JS 技巧虛值

2019-11-28 15:36:43

Redis數(shù)據(jù)庫(kù)高延遲

2019-12-24 09:49:02

微軟英語(yǔ)瀏覽器

2022-04-15 07:51:12

off-heap堆外內(nèi)存JVM

2018-09-03 16:05:03

編程語(yǔ)言Python代碼技巧

2025-02-27 07:47:09

2021-10-22 09:41:26

橋接模式設(shè)計(jì)

2021-03-18 14:02:56

iOS蘋(píng)果細(xì)節(jié)

2014-12-01 09:41:25

2022-06-18 23:03:05

Seata分布式事務(wù)

2023-01-02 10:08:42

StampedLocAQS框架

2018-07-10 11:33:58

計(jì)算器iPhone刪除
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)