精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

亚洲成人你懂的| 噜噜噜91成人网| 日韩亚洲欧美中文三级| 日本五级黄色片| 无码国产精品一区二区色情男同| 亚洲国内精品| 亚洲性视频网站| 99sesese| av中文字幕电影在线看| 国产日韩欧美麻豆| 91精品久久久久久蜜桃| 91porny在线| 欧美激情国产在线| 亚洲第一综合天堂另类专| 亚洲人成无码www久久久| 欧美成人xxx| 成人av一区| 国产日韩欧美三区| 色哟哟亚洲精品一区二区| 免费不卡av网站| 超碰成人av| 国产精品久久久久久久久免费樱桃| 亚洲影影院av| 波多野结衣在线电影| 欧美aⅴ99久久黑人专区| 国产丝袜一区视频在线观看 | 91高清在线视频| 成人综合在线视频| 91精品国产综合久久久久久蜜臀 | 青青九九免费视频在线| 激情图片小说一区| 2020国产精品视频| 久久在线视频精品| 97精品一区二区| 亚洲开心激情网| www.美色吧.com| 亚洲爽爆av| 色欧美88888久久久久久影院| 99在线观看视频免费| 9色在线视频网站| 91美女在线观看| 成人av免费在线看| 99热这里只有精品66| 老司机免费视频一区二区三区| 午夜免费在线观看精品视频| 久久国产在线视频| 91精品啪在线观看国产18| 一区二区三欧美| 亚洲AV无码国产成人久久| 成人av激情人伦小说| 欧美日韩一区二区三区免费看| 北条麻妃69av| 98色花堂精品视频在线观看| 一区二区三区不卡视频| 最新视频 - x88av| 欧美激情黑人| 亚洲天堂中文字幕| 在线不卡日本| 色网站免费在线观看| 国产三级欧美三级| 欧美一区二区三区电影在线观看 | 开心九九激情九九欧美日韩精美视频电影| 清纯唯美日韩制服另类| 国产成人在线播放视频| 99香蕉国产精品偷在线观看| 91成人在线观看国产| 男人的天堂一区| 在线亚洲欧美| 国产精品成人一区二区| 亚洲国产无线乱码在线观看| 麻豆一区二区99久久久久| 国产日韩换脸av一区在线观看| 中文在线观看av| 久久超级碰视频| 91香蕉电影院| 黄色av网址在线| 91麻豆福利精品推荐| 欧美aaaaa喷水| 国产福利在线视频| 亚洲视频 欧洲视频| 国产日韩欧美大片| 97天天综合网| 一本色道亚洲精品aⅴ| 国产三级日本三级在线播放| 免费成人高清在线视频| 日韩视频免费观看高清完整版在线观看 | 亚洲a∨精品一区二区三区导航| 狠狠躁天天躁日日躁欧美| 欧美极品欧美精品欧美| 九色porny自拍视频在线播放| 欧美视频中文在线看| 成人免费观看视频在线观看| 三上悠亚激情av一区二区三区| 日韩欧美亚洲综合| 国产视频九色蝌蚪| 日本免费一区二区三区四区| 在线免费观看日本欧美| 狠狠干狠狠操视频| 欧美激情三级| 欧美大片国产精品| 国产小视频自拍| 成人嘿咻视频免费看| 中文字幕日韩欧美在线| 久久久久久久久久网站| 亚洲久色影视| 国产精品96久久久久久又黄又硬| 中文天堂在线资源| 国产suv精品一区二区6| 久久久久久99| 无码精品视频一区二区三区 | 9久re热视频在线精品| 欧美亚洲第一页| 中文字幕在线观看你懂的| 国内精品久久久久影院一蜜桃| julia一区二区中文久久94| 精品国产乱码一区二区三| 国产亚洲视频系列| 日韩不卡一二区| a√中文在线观看| 欧美性欧美巨大黑白大战| 91 视频免费观看| 蜜臀av一区| 日韩在线观看免费高清| 中文字幕一区二区三区手机版| 丝袜美腿亚洲色图| 成人淫片在线看| 黄色在线小视频| 一区二区三区在线免费视频| 日韩亚洲在线视频| 亚洲一二av| 中文字幕日韩精品有码视频| 日操夜操天天操| 极品尤物av久久免费看| 久久综合九色综合久99| 视频在线观看入口黄最新永久免费国产| 精品福利在线视频| 黄色片子免费看| 欧美老女人另类| 18久久久久久| 国产av无码专区亚洲a∨毛片| 国产亚洲精品bt天堂精选| 人妻激情另类乱人伦人妻| jizzjizz少妇亚洲水多| 日韩av在线不卡| 国产女人18水真多毛片18精品| 日韩不卡一区二区| 精品国产91亚洲一区二区三区www| 久久亚洲天堂| 日本道精品一区二区三区| 国产chinese中国hdxxxx| 亚洲香蕉av| 国产精品欧美日韩一区二区| 飘雪影院手机免费高清版在线观看 | 精品久久久久av| 农村少妇一区二区三区四区五区| 久热精品视频在线观看一区| 中文字幕+乱码+中文字幕明步| 国产亚洲一区二区三区四区| 一本大道熟女人妻中文字幕在线 | 91.com视频| 国产成人一区二区在线观看| 免费看的黄色欧美网站| 国产一区二区在线网站| 欧美videos另类精品| 欧美一级欧美一级在线播放| www.com.av| 翔田千里一区二区| 欧美亚洲国产免费| 国产高清不卡| 亚洲欧美一区二区激情| 在线天堂中文字幕| 91在线porny国产在线看| 久久人人爽人人爽人人av| 亚洲国产中文在线| 欧美肥老妇视频| 99热这里只有精品在线| 亚洲一区av在线| 日本50路肥熟bbw| 一区二区三区导航| 欧美精品欧美精品系列c| 中文在线资源| 亚洲欧洲黄色网| 中文字幕永久在线| 国产精品久久久爽爽爽麻豆色哟哟 | 天海翼亚洲一区二区三区| …久久精品99久久香蕉国产| 欧美18xxxxx| 欧洲精品视频在线观看| 国产精品www爽爽爽| 久久国产尿小便嘘嘘| 爱爱爱视频网站| 欧美片网站免费| 欧美激情视频免费观看| 日批视频免费播放| 欧美日韩一区二区在线播放| a级片在线观看| 久久精品免费观看| www.成年人视频| 亚洲制服一区| 国产欧美一区二区白浆黑人| 呦呦在线视频| 日韩av一区二区在线观看| 中文精品久久久久人妻不卡| 亚洲人成网站影音先锋播放| 国产伦精品一区二区三区88av| 亚洲高清二区| 一区二区三区不卡在线| 秋霞影院一区| 欧美综合激情网| 91青青在线视频| 欧美tk—视频vk| 中文字幕精品无码一区二区| 国产精品美女www爽爽爽| 色偷偷中文字幕| 狂野欧美一区| 国产一区一区三区| 亚洲激情播播| 亚洲一区二区三区久久| 日韩脚交footjobhd| 中文字幕欧美日韩在线| 欧美一区二区三区激情| 欧美三级午夜理伦三级中视频| 三级黄色在线观看| 国产亚洲女人久久久久毛片| 国产吃瓜黑料一区二区| 日韩激情av在线| wwwwww欧美| 爽成人777777婷婷| 免费亚洲精品视频| 日韩高清一区| 国产精品678| 91av久久| 久久久av一区| 国产二区在线播放| 亚洲国产欧美日韩精品| 国产原创中文av| 日韩欧美精品网址| 久久国产精品系列| 亚洲精品久久7777| 少妇视频一区二区| 久久久久久久久蜜桃| 成人做爰www看视频软件| 韩国av一区二区三区| 日本爱爱免费视频| 日韩国产在线观看一区| 凹凸国产熟女精品视频| 国内激情久久| 玖玖精品在线视频| 久久亚洲成人| 日韩欧美亚洲日产国| 欧美性生活一级片| 欧美大陆一区二区| 极品束缚调教一区二区网站| 18成人免费观看网站下载| 日韩三级一区| 国产精品女人久久久久久| 欧美magnet| 日本午夜在线亚洲.国产| 午夜影院在线观看国产主播| 91禁外国网站| heyzo高清国产精品| 久久99国产精品自在自在app| 欧美成人三区| 少妇高潮久久77777| 在线国产91| 亚洲欧美精品在线| 国产69精品久久app免费版| 亚洲欧美精品中文字幕在线| 日本天堂影院在线视频| 日韩精品福利在线| 日本午夜在线| 亚洲香蕉伊综合在人在线视看| 日本人妻熟妇久久久久久| 日韩成人中文字幕| 日av在线播放| 亚洲一级黄色av| 在线播放毛片| 最好看的2019的中文字幕视频| 成全电影播放在线观看国语| 日韩在线中文字| 污污在线观看| 欧美激情在线观看视频| 国产三级伦理在线| 91爱爱小视频k| 天堂av在线网| 国产精品福利片| 78精品国产综合久久香蕉| 5g国产欧美日韩视频| 国产精东传媒成人av电影| 久久99精品久久久久久久青青日本 | 色一情一乱一伦| 欧美综合视频在线观看| 一级爱爱免费视频| 精品人在线二区三区| 网站黄在线观看| 精品香蕉一区二区三区| 超碰国产在线| 欧美精品一区二区免费| av在线最新| 8x拔播拔播x8国产精品| 国产精品高清乱码在线观看| 成人黄色在线免费| 国产精品tv| 日韩电影在线播放| 欧美在线精品一区| 欧美成人精品免费| 久久精品国产精品青草| 国产免费无码一区二区| 久久嫩草精品久久久精品| chinese全程对白| 亚洲国产精品自拍| 性高潮视频在线观看| 日韩一区二区麻豆国产| 你懂的视频在线免费| 久久天天躁狠狠躁夜夜躁2014| bbw在线视频| 国产精品香蕉在线观看| 国产极品模特精品一二| 欧美一区二区高清在线观看| 亚洲国产免费看| 思思久久精品视频| 91免费版在线看| 性色av无码久久一区二区三区| 一本到三区不卡视频| 午夜精品在线播放| 日韩有码在线观看| 免费电影日韩网站| 成人黄动漫网站免费| 日本一区二区高清不卡| 午夜免费福利小电影| 丝袜美腿亚洲一区| 国产手机在线观看| 一区二区三区在线影院| 亚洲天堂视频在线| 亚洲男女性事视频| 欧美bbbxxxxx| 成人欧美一区二区三区在线 | 色欧美乱欧美15图片| 性欧美18一19性猛交| 久久精品亚洲精品| 国产精品伦一区二区| 久久综合色一本| 亚洲美女网站| 91久久精品网| 懂色av蜜臀av粉嫩av分享吧最新章节| 亚洲精品国产精品久久清纯直播| 成人av福利| 成人福利视频网| 北条麻妃国产九九九精品小说| 国产美女无遮挡网站| 欧美有码在线| 一区二区三区在线播放欧美| 免费在线看黄网站| 国产精品自产拍在线观| 久久不见久久见免费视频7| 少妇高潮喷水在线观看| 成人国产一区二区三区精品| 国产无遮挡又黄又爽| 日韩欧美中文字幕一区| av网站在线看| 亚洲sss综合天堂久久| 欧美成人milf| 中文字幕第21页| 国产精品福利一区| 在线免费观看av片| 亚洲欧美日韩久久久久久| 欧美人与性动交xxⅹxx| 欧美日韩精品不卡| 久久精品道一区二区三区| 国产精品成人在线视频| 欧美日韩视频在线观看一区二区三区| 国产视频精品久久| 国产精品视频久久久| japanese国产精品| 亚洲精品mv在线观看| 亚洲男人的天堂网| www黄色在线观看| 欧美激情亚洲自拍| 欧美黑人巨大videos精品| 久久国产色av免费观看| 日本一区二区成人| 91免费视频播放| 欧美人在线视频| 精品五月天堂| 亚洲人辣妹窥探嘘嘘| 中文字幕一区二区三区在线播放 | 99ri日韩精品视频| 伊人久久99| 成人黄色在线看| 久久久蜜桃一区二区| 精品国产一区二区三区久久| 日韩精品中文字幕一区二区| 少妇熟女一区二区| 91日韩一区二区三区| 中文字幕观看视频| 欧美老女人性生活| 午夜先锋成人动漫在线| 男女视频在线看| 亚洲国产日日夜夜| 超碰人人干人人|