精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

手動擼一個 Redis 分布式鎖

數據庫 Redis
這個代碼,其實是我很久之前寫的,因為當時 Go 沒有開源的分布式鎖,但是我又需要通過單機去執行某個任務,所以就自己手動擼了一個,后來在線上跑了 2 年,一直都沒有問題。

大家好呀,我是樓仔。

今天第一天開工,收拾心情,又要開始好好學習,好好工作了。

對于使用 Java 的小伙伴,其實我們完全不用手動擼一個分布式鎖,直接使用 Redisson 就行。

但是因為這些封裝好的組建,讓我們越來越懶。

我們使用一些封裝好的開源組建時,可以了解其中的原理,或者自己動手寫一個,可以更好提升你的技術水平。

今天我就教大家用原生的 Redis,手動擼一個 Redis 分布式鎖,很有意思。

01 問題引入

其實通過 Redis 實現分布式鎖,經常會有面試官會問,很多同學都知道用 SetNx() 去獲取鎖,解決并發問題。

SetNx() 是什么?我簡單解答一下。

Redis Setnx(SET if Not eXists) 命令在指定的 key 不存在時,為 key 設置指定的值。

對于下面 2 種問題,你知道如何解決么?

  • 如果獲取鎖的機器掛掉,如何處理?
  • 當鎖超時時,A、B 兩個線程同時獲取鎖,可能導致鎖被同時獲取,如何解決?

這個就是我們實現 Redis 分布式鎖時,需要重點解決的 2 個問題。

02 理論知識

剛才說過,通過 SetNx() 去獲取鎖,可以解決并發問題。

當獲取到鎖,處理完業務邏輯后,會將鎖釋放。

圖片圖片

但當機器宕機,或者重啟時,沒有執行 Del() 刪除鎖操作,會導致鎖一直沒有釋放。

所以,我們還需要記錄鎖的超時時間,判斷鎖是否超時。

圖片圖片

這里我們通過 GetKey() 獲取鎖的超時時間 A,通過和當前時間比較,判斷鎖是否超時。

如果鎖未超時,直接返回,如果鎖超時,重新設置鎖的超時時間,成功獲取鎖。

還有其它問題么?當然!

因為在并發場景下,會存在 A、B 兩個線程同時執行 SetNx(),導致兩個線程同時獲取到鎖。

那如何解決呢?將 SetNx() 用 GetSet() 替換。

圖片圖片

GetSet() 是什么?我簡單解答一下。

Redis Getset 命令用于設置指定 key 的值,并返回 key 的舊值。

這里不太好理解,我舉個例子。

假如 A、B 兩個線程,A 先執行,B 后執行:

  • 對于線程 A 和 B,通過 GetKey 獲取的超時時間都是 T1 = 100;
  • 對于線程 A,將超時時間 Ta = 200 通過 GetSet() 設置,返回 T2 = 100,此時滿足條件 “T1 == T2”,獲取鎖成功;
  • 對于線程 B,將超時時間 Tb = 201 通過 GetSet() 設置,由于鎖超時時間已經被 A 重新設置,所以返回 T2 = 200,此時不滿足條件 “T1 == T2”,獲取鎖失敗。

可能有同學會繼續問,之前設置的超時是 Ta = 200,現在變成了 Tb = 201,延長或縮短了鎖的超時時間,不會有問題么?

其實在現實并發場景中,能走到這一步,基本是“同時”進來的,兩者的時間差非常小,可以忽略此影響。

03 代碼實戰

這里給出 Go 代碼,注釋都寫得非常詳細,即使你不會 Go,讀注釋也能讀懂。

// 獲取分布式鎖,需要考慮以下情況:
// 1. 機器A獲取到鎖,但是在未釋放鎖之前,機器掛掉或者重啟,會導致其它機器全部hang住,這時需要根據鎖的超時時間,判斷該鎖是否需要重置;
// 2. 當鎖超時時,需要考慮兩臺機器同時去獲取該鎖,需要通過GETSET方法,讓先執行該方法的機器獲取鎖,另外一臺繼續等待。
func GetDistributeLock(key string, expireTime int64) bool {

 currentTime := time.Now().Unix()
 expires := currentTime + expireTime
 redisAlias := "jointly"

 // 1.獲取鎖,并將value值設置為鎖的超時時間
 redisRet, err := redis.SetNx(redisAlias, key, expires)
 if nil == err && utils.MustInt64(1) == redisRet {
  // 成功獲取到鎖
  return true
 }

 // 2.當獲取到鎖的機器突然重啟&掛掉時,就需要判斷鎖的超時時間,如果鎖超時,新的機器可以重新獲取鎖
 // 2.1 獲取鎖的超時時間
 currentLockTime, err := redis.GetKey(redisAlias, key)
 if err != nil {
  return false
 }

 // 2.2 當"鎖的超時時間"大于等于"當前時間",證明鎖未超時,直接返回
 if utils.MustInt64(currentLockTime) >= currentTime {
  return false
 }

 // 2.3 將最新的超時時間,更新到鎖的value值,并返回舊的鎖的超時時間
 oldLockTime, err := redis.GetSet(redisAlias, key, expires)
 if err != nil {
  return false
 }

 // 2.4 當鎖的兩個"舊的超時時間"相等時,證明之前沒有其它機器進行GetSet操作,成功獲取鎖
 // 說明:這里存在并發情況,如果有A和B同時競爭,A會先GetSet,當B再去GetSet時,oldLockTime就等于A設置的超時時間
 if utils.MustString(oldLockTime) == currentLockTime {
  return true
 }
 return false
}

刪除鎖邏輯:

// 刪除分布式鎖
// @return bool true-刪除成功;false-刪除失敗
func DelDistributeLock(key string) bool {
 redisAlias := "jointly"
 redisRet := redis.Del(redisAlias, key)
 if redisRet != nil {
  return false
 }
 return true
}

業務邏輯:

func DoProcess(processId int) {

 fmt.Printf("啟動第%d個線程\n", processId)

 redisKey := "redis_lock_key"
 for {
  // 獲取分布式鎖
  isGetLock := GetDistributeLock(redisKey, 10)
  if isGetLock {
   fmt.Printf("Get Redis Key Success, id:%d\n", processId)
   time.Sleep(time.Second * 3)
   // 刪除分布式鎖
   DelDistributeLock(redisKey)
  } else {
   // 如果未獲取到該鎖,為了避免redis負載過高,先睡一會
   time.Sleep(time.Second * 1)
  }
 }
}

最后起個 10 個多線程,去執行這個 DoProcess():

func main() {
 // 初始化資源
 var group string = "group"
 var name string = "name"
 var host string

 // 初始化資源
 host = "http://ip:port"
 _, err := xrpc.NewXRpcDefault(group, name, host)
 if err != nil {
  panic(fmt.Sprintf("initRpc when init rpc  failed, err:%v", err))
 }
 redis.SetRedis("louzai", "redis_louzai")

 // 開啟10個線程,去搶Redis分布式鎖
 for i := 0; i <= 9; i ++ {
  go DoProcess(i)
 }

 // 避免子線程退出,主線程睡一會
 time.Sleep(time.Second * 100)
 return
}

程序跑了100 s,我們可以看到,每次都只有 1 個線程獲取到鎖,分別是 2、1、5、9、3,執行結果如下:

啟動第0個線程
啟動第6個線程
啟動第9個線程
啟動第4個線程
啟動第5個線程
啟動第2個線程
啟動第1個線程
啟動第8個線程
啟動第7個線程
啟動第3個線程
Get Redis Key Success, id:2
Get Redis Key Success, id:2
Get Redis Key Success, id:1
Get Redis Key Success, id:5
Get Redis Key Success, id:5
Get Redis Key Success, id:5
Get Redis Key Success, id:5
Get Redis Key Success, id:5
Get Redis Key Success, id:5
Get Redis Key Success, id:5
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:9
Get Redis Key Success, id:3
Get Redis Key Success, id:3
Get Redis Key Success, id:3
Get Redis Key Success, id:3
Get Redis Key Success, id:3

04 后記

這個代碼,其實是我很久之前寫的,因為當時 Go 沒有開源的分布式鎖,但是我又需要通過單機去執行某個任務,所以就自己手動擼了一個,后來在線上跑了 2 年,一直都沒有問題。

不過期間也遇到過一個坑,就是我們服務遷移時,忘了將舊機器的分布式鎖停掉,導致鎖經常被舊機器搶占,當時覺得很奇怪,我的鎖呢?

寫這篇文章時,又讓我想到當時工作的場景。

最后再切回正題,本文由淺入深,詳細講解了 Redis 實現的詳細過程,以及鎖超時、并發場景下,如何保證鎖能正常釋放,且只有一個線程去獲取鎖。

責任編輯:武曉燕 來源: 樓仔
相關推薦

2020-07-30 09:35:09

Redis分布式鎖數據庫

2021-11-01 12:25:56

Redis分布式

2019-06-19 15:40:06

分布式鎖RedisJava

2022-11-11 08:19:03

redis分布式

2024-05-08 10:20:00

Redis分布式

2022-09-22 13:28:34

Redis分布式鎖

2022-09-29 08:28:57

SpringRedis分布式

2024-07-15 08:25:07

2022-04-14 07:56:30

公平鎖Java線程

2023-03-06 08:14:48

MySQLRedis場景

2023-08-21 19:10:34

Redis分布式

2022-01-06 10:58:07

Redis數據分布式鎖

2019-02-26 09:51:52

分布式鎖RedisZookeeper

2023-09-21 22:22:51

開發分布式鎖

2022-12-18 20:07:55

Redis分布式

2019-03-21 09:45:20

IM即時通訊CIM

2024-10-07 10:07:31

2020-11-16 12:55:41

Redis分布式鎖Zookeeper

2022-09-19 08:17:09

Redis分布式

2021-06-16 07:56:21

Redis分布式
點贊
收藏

51CTO技術棧公眾號

实拍女处破www免费看| 日韩精品999| 三年中文高清在线观看第6集| 午夜精品久久久久久久爽| 99在线|亚洲一区二区| 亚洲色图国产精品| 久久国产精品偷| 99在线精品免费视频| 欧美大片aaa| 久久成人免费网站| 国内精品久久久久久久| 一本在线免费视频| 盗摄系列偷拍视频精品tp| 欧美综合在线视频| 国产自产在线视频| 日韩免费啪啪| 成人免费av在线| 国产在线播放不卡| 国产美女激情视频| 欧美国产精品| 久久精品国产欧美激情| 强伦人妻一区二区三区| 一区二区三区在线资源| 欧美日韩精品欧美日韩精品一综合| 久久人人爽人人爽人人av| 婷婷在线视频观看| 久久久青草青青国产亚洲免观| 亚洲xxx大片| 最近中文字幕av| 欧美亚洲专区| 91精品国产99| 久久国产在线视频| 亚洲综合中文| 中文字幕亚洲色图| 国产 欧美 在线| 久久久久观看| 精品91自产拍在线观看一区| 三大队在线观看| 国产专区精品| 777久久久精品| 国产精品一区二区羞羞答答| 欧美性xxx| 欧美日韩国产综合视频在线观看中文| 青青青在线观看视频| av在线导航| 亚洲欧美一区二区三区极速播放 | 99国产精品久| 国产91视觉| 肥臀熟女一区二区三区| 国产传媒日韩欧美成人| 亚洲自拍偷拍一区| www.黄色片| 国产成人在线看| 91视频在线免费观看| www.黄色av| 成人精品视频一区二区三区尤物| 岛国视频一区免费观看| 成人黄色免费视频| caoporn国产精品| 精品一区二区久久久久久久网站| 日本激情一区二区| 99综合电影在线视频| 国产精品视频免费观看| 人妻无码一区二区三区久久99| 国产91精品入口| 国产欧美韩日| 男人久久精品| 国产精品久久久久三级| 韩国黄色一级大片| 天天色天天射天天综合网| 亚洲一二三区不卡| 国产免费观看高清视频| 黑人巨大精品欧美一区二区桃花岛| 日韩欧美亚洲综合| 中文字幕av不卡在线| 国产不卡精品在线| 精品国产91洋老外米糕| 菠萝菠萝蜜网站| 国产精品亚洲片在线播放| 中文字幕精品视频| 国产波霸爆乳一区二区| 一区视频在线看| 日韩美女福利视频| 国产孕妇孕交大片孕| 成人性色生活片免费看爆迷你毛片| 精品蜜桃一区二区三区| 1024视频在线| 亚洲一区二区三区美女| 国产激情在线观看视频| 超碰国产精品一区二页| 精品国产3级a| 久久久久久成人网| 亚洲视频久久| 国产精品女人久久久久久| 国产日韩免费视频| 91网站视频在线观看| 亚洲制服中文| sm性调教片在线观看| 欧美少妇bbb| 中文字幕人妻一区二区三区| 成人精品电影| 久久全球大尺度高清视频| 一区二区乱子伦在线播放| 国产成人精品免费在线| 日韩久久精品一区二区三区| 色图在线观看| 欧美三级午夜理伦三级中视频| 乱码一区二区三区| 日韩av在线播放网址| 久久免费视频这里只有精品| 91精品国自产| 久久综合九色综合欧美98| 神马午夜伦理影院| 电影一区二区| 日韩成人av网址| 欧美久久久久久久久久久久| 日本在线不卡视频一二三区| 国产精品一区二区三区在线| 在线免费看a| 精品久久久久久久大神国产| 欧美日韩久久婷婷| 水蜜桃精品av一区二区| 欧美综合激情网| 乱精品一区字幕二区| 国产精品国产三级国产普通话三级| 欧洲黄色一级视频| 亚洲国产aⅴ精品一区二区| 中文字幕国产精品| 中文字幕免费高清网站| 91麻豆免费看| 日本在线xxx| 51社区在线成人免费视频| 日韩一区二区三区国产| 欧美一区免费看| 26uuu亚洲婷婷狠狠天堂| 激情五月婷婷六月| 91精品久久久久久综合五月天| 少妇高潮久久77777| 亚洲无码精品一区二区三区| 久久先锋影音av| 欧美v在线观看| 日韩极品在线| 欧美专区在线视频| 黄视频在线观看免费| 色一情一伦一子一伦一区| 一级特黄a大片免费| 亚洲黄色在线| 国产伦精品一区二区三区视频黑人 | 免费拍拍拍网站| xxxx日韩| 97激碰免费视频| 日本免费一区视频| 婷婷中文字幕综合| 欧美亚一区二区三区| 亚洲专区欧美专区| 欧美日韩天天操| 午夜欧美巨大性欧美巨大| 国产视频精品在线| 天天爱天天做天天爽| 国产精品久久久久久亚洲毛片| 一区二区三区韩国| 天天射综合网视频| 成人18视频| 午夜欧美激情| 亚洲欧美激情视频| 中文字幕乱码在线观看| 自拍偷拍欧美激情| 性活交片大全免费看| 国产综合激情| 久久精品99| 国产一区二区主播在线| www.日韩不卡电影av| 性生活免费网站| 天天色天天操综合| 永久免费av无码网站性色av| 美国av一区二区| 欧美日韩dvd| 网友自拍区视频精品| 国产精品丝袜久久久久久高清| 日本www在线观看视频| 欧美一区二区三区小说| 亚洲精品国产精品乱码| 国产欧美一区二区三区鸳鸯浴| 日本一二三四区视频| 亚洲激情偷拍| 亚洲在线色站| 精品av导航| 国产精品亚洲自拍| heyzo高清在线| 一本色道久久88综合亚洲精品ⅰ| 国产手机av在线| 欧美午夜精品久久久久久浪潮| 国产精品18在线| 成人国产视频在线观看| 尤蜜粉嫩av国产一区二区三区| 欧美阿v一级看视频| 蜜桃网站成人| av在线亚洲色图| 国产精品久久不能| 波多野结衣久久| 日韩一区二区欧美| 麻豆导航在线观看| 日韩三级免费观看| 91麻豆精品在线| 亚洲va国产天堂va久久en| 99久久99久久精品免费看小说.| 成人午夜av电影| 国产福利精品一区二区三区| 国产深夜精品| 黄色成人在线免费观看| 欧洲乱码伦视频免费| 精品视频在线观看| 6080亚洲理论片在线观看| 国产精品美腿一区在线看| 黄色在线免费观看网站| 欧美精品在线观看91| 91av资源在线| 亚洲天堂av高清| 欧美中文在线| 亚洲国产精品va在线| 99久久精品日本一区二区免费 | 欧美大肥婆大肥bbbbb| 黄色影院在线播放| 日韩电影大片中文字幕| xxxx18国产| 制服丝袜亚洲网站| 亚洲熟妇av乱码在线观看| 色天天综合久久久久综合片| 香蕉免费毛片视频| 亚洲一级二级三级| 欧美三级免费看| 亚洲欧洲制服丝袜| 日韩欧美国产成人精品免费| 中文字幕乱码久久午夜不卡 | 久久不见久久见国语| 国产尤物99| 久久久久影视| 精品蜜桃一区二区三区| 欧美激情99| 精品亚洲第一| 亚洲激情播播| 欧美国产综合视频| 国产欧美一区二区精品久久久| 久久99影院| 台湾色综合娱乐中文网| 久久伊人一区二区| 国产videos久久| 五码日韩精品一区二区三区视频| 国产亚洲一区| 色综合视频二区偷拍在线| 成人一区二区| 亚洲综合首页| 中文无码久久精品| 日本免费成人网| 亚洲美女色禁图| 久久精品国产精品亚洲色婷婷| 性欧美videos另类喷潮| 亚洲成人福利在线观看| 奇米精品一区二区三区四区| av在线网址导航| 国产麻豆精品在线观看| 第一页在线视频| 99re热这里只有精品免费视频| a视频免费观看| 久久综合九色综合97婷婷| 男女男精品视频网站| 亚洲乱码日产精品bd| 日本一二三区视频| 色88888久久久久久影院野外| a片在线免费观看| 正在播放亚洲一区| 狠狠人妻久久久久久综合麻豆| 日韩精品亚洲视频| 日本三级视频在线播放| 久久久久久香蕉网| 国产不卡网站| 成人信息集中地欧美| 国产精品zjzjzj在线观看| 欧美日韩免费精品| 一区二区三区午夜视频| 成人在线免费在线观看| 久久精品国产99国产精品| 26uuu国产| 久久精品欧美日韩| 亚洲波多野结衣| 亚洲国产综合在线| 免费在线不卡av| 精品国产免费一区二区三区香蕉| 黄色av免费在线观看| 美女视频久久黄| 中文字幕成在线观看| 国产精品免费一区| 北条麻妃在线一区二区免费播放| 日本中文不卡| 亚洲一级淫片| 色诱视频在线观看| 高清在线观看日韩| 日韩精品电影一区二区三区| 亚洲国产wwwccc36天堂| 在线观看毛片网站| 日韩精品中文字| 久久大胆人体| 国产精品久久久久av| 国产一级成人av| 正在播放久久| 久久aⅴ国产紧身牛仔裤| 在线观看视频在线观看| 久久久久久久久久久黄色| 国产精品111| 7777女厕盗摄久久久| 国产视频第一区| 国外成人性视频| 日韩在线视频一区二区三区| 日韩欧美99| 亚洲永久免费精品| av av在线| 亚洲伦理在线精品| 中文字幕一区二区三区四区免费看| 日韩成人免费视频| 女同视频在线观看| 亚洲精品女av网站| 色婷婷亚洲mv天堂mv在影片| 久久精品香蕉视频| 91麻豆精东视频| 日韩欧美性视频| 精品久久久久久久人人人人传媒| 久操视频在线| 国产欧美日韩精品专区| 欧美精品一区二区三区中文字幕| 久久国产成人精品国产成人亚洲| 福利视频网站一区二区三区| www.超碰在线观看| 欧美军同video69gay| 国产午夜在线视频| 国产999精品久久久| 美女毛片一区二区三区四区最新中文字幕亚洲| 国产3p露脸普通话对白| 成人免费观看男女羞羞视频| 国产福利久久久| 精品sm在线观看| 大菠萝精品导航| 精品日本一区二区| 一区二区国产精品| 给我看免费高清在线观看| 精品久久久久久久久久ntr影视| 黄色av网站免费在线观看| 欧美精品videos| 老牛国内精品亚洲成av人片| 毛片在线视频播放| www亚洲一区| 波多野结衣在线电影| 亚洲香蕉成人av网站在线观看| 性感美女一区二区在线观看| 日韩中文一区| 美国毛片一区二区三区| 婷婷伊人五月天| 日韩欧美精品在线视频| 变态调教一区二区三区| 女同一区二区| 免费在线观看精品| frxxee中国xxx麻豆hd| 日韩欧美中文字幕精品| xxxx视频在线| 欧美日韩在线观看一区| 青草国产精品久久久久久| 成人免费视频网站入口::| 精品第一国产综合精品aⅴ| 1234区中文字幕在线观看| 另类欧美小说| 久久99久久精品| 久久影院一区二区| 亚洲精品中文字幕有码专区| 国产成人午夜性a一级毛片| 懂色av一区二区三区四区五区| 国产成人av电影免费在线观看| 久久午夜免费视频| 正在播放亚洲1区| 精品视频一区二区三区| 男人操女人免费软件| 国产精品美女一区二区三区| 亚洲va欧美va| 日本精品一区二区三区在线播放视频 | 国产综合色产在线精品| 国产成年人免费视频| 国产一区二区三区在线视频| 国产日韩一区二区三免费高清| 少妇高潮喷水在线观看| 国产精品天干天干在观线| 国产成人手机在线| 国产精品www| 亚洲婷婷在线| 成人无码精品1区2区3区免费看| 精品国产成人在线影院 | eeuss一区二区三区| 日韩av电影免费观看高清完整版| 日韩黄色免费观看| 一本色道久久综合狠狠躁篇的优点| www.成人网| 国产美女视频免费看| 在线日韩一区二区|