分布式鎖的基本功能:
1.同一時刻只能存在乙個鎖
2.需要解決意外死鎖問題,也就是鎖能超時自動釋放
3.支援主動釋放鎖
分布式鎖解決什麼問題:
多程序併發執行任務時,需要保證任務的有序性或者唯一性
準備:
redis版本》=2.6
redis是主從+sentinel模式(為了高可用)
原理:
redis2.6之後,set命令支援超時和key存在檢查,這是乙個原子操作
set key value [ex seconds] [px milliseconds] [nx|xx]
刪除鎖:
del key
ex:單位是秒
px:單位是毫秒
nx:如果key存在,返回nil(失敗),不存在返回ok
xx:如果key存在,返回ok,不存在返回nil(失敗)
基本操作如圖示:
案例:
有乙個系統,需要對使用者資訊進行增刪改查操作,系統是多程序的,要求對使用者的操作是有序的序列的
上測試**,可以多開程序**效果:
# -*- coding: utf-8 -*-
import time
import redis
# 獲取鎖
def get_lock(uid):
# 連線redis
r = redis.strictredis(host='localhost', port=6379, db=0, socket_timeout=1, socket_connect_timeout=3)
# 當前時間戳,用於刪除鎖時check
sec = str(time.time())
# 處理超時時間
timeout = 300
# 試圖鎖住uid
while true:
res = r.set(uid, sec, ex=timeout, nx=true)
if res == true:
print "get lock succeed, return"
return true, sec
else:
print "get lock failed, lock exist, wait"
time.sleep(0.001)
return false, none
# 釋放鎖
def del_lock(uid, sec):
# 連線redis
r = redis.strictredis(host='localhost', port=6379, db=0, socket_timeout=1, socket_connect_timeout=3)
# 校驗
redis_sec = r.get(uid)
if sec != redis_sec:
print "check permission failed :%s" % uid
return false
print "check permission succeed :%s" % uid
#刪除res = r.delete(uid)
if res:
print "del key succeed :%s" % uid
return false
else:
print "del key failed :%s" % uid
return true
if __name__ == '__main__':
uid = "001"
while true:
status, sec = get_lock(uid)
if status:
del_lock(uid, sec)
time.sleep(0.001)
缺陷:a) 一旦redis發生主從切換,可能會丟失一些鎖,
b) 如果對鎖的要求很高,可以參考redis官方提供的方案:
c) 範例**只能當作原理來理解,實際上有很多需要優化的地方,優化可參考:
end;
基於Redis實現分布式鎖
之前專案中使用redis鎖實現秒殺等一些併發業務,在這裡整理一下基於redis實現分布式鎖的簡單入門例項,記錄一下,便於以後檢視 學習。springboot整合redisson分布式鎖 1 簡介 在分布式系統中存在併發場景,為了解決這一問題,基於redis鎖一定程度可以解決這一問題,但是也有缺點,如...
基於redis實現分布式鎖
實現方式 具備條件 確保鎖可用,必須要滿足一下幾個條件 1 互斥性,任意時刻只有乙個使用者能持有鎖 2 不會產生死鎖,假設某個使用者在持有鎖的期間由於服務崩潰或者其他原因沒有主動釋放鎖,也能保證後續其他使用者可以加鎖 3 加鎖和解鎖必須是同一使用者,b使用者無法解除a使用者加的鎖 實現 1 引入je...
基於redis實現分布式鎖
四個同時都去切換表 1 的操作是不可以的,他們要先從 redis 獲取一把鎖,沒有獲取到鎖的就直接退出,等待下一次定時任務的排程。拿到了鎖的就去執行切換當前分表的操作 獲取鎖 和 釋放鎖 的關鍵 如下所示 set the string value as value of the key.the st...