Redis——分佈式鎖

什麼是分佈式鎖

  1. 分佈式鎖: 進行邏輯處理時經常會遇到併發問題。可以藉助redis來實現分佈式鎖,簡單來說就是限制兩個操作不同時進行,每次執行某個操作的時候用setnx()加鎖,當沒被鎖再執行下一個操作.限制程序的併發執行!
  2. 一般步驟: 使用 setnx(set if not exists) 指令,只允許被一個客戶端佔坑。先來先佔,用完了,再調用 del 指令釋放茅坑。
  3. setnx lock:XXX true

分佈式鎖問題

  1. 鎖的釋放問題: 如果執行到一半出現問題,沒有執行del釋放鎖,那麼鎖就得不到釋放

    可以給鎖加個expire過期時間

  2. 鎖的超時問題: 當設置過期時間比較短的時候,可能程序還未執行完畢,鎖已經超時過期了.第二個線程重新持有了這把鎖, 但是緊接着第一個線程執行完了業務邏輯,就把鎖給釋放了,第三個線程就會在第二個線程邏 輯執行完之間拿到了鎖。(超時後使用del 導致誤刪其他線程的鎖)

    • 分佈式鎖不要用於長時間的任務
    • 給value設置一個隨機數,釋放的時候匹配隨機數是否一致再刪除
    • 編寫守護進程,當一個鎖快要過期的時候,任務還未結束,可以給鎖續一波命(過期時間),任務結束關閉該守護進程

lua腳本實現匹配和刪除的一個原子操作

	# delifequals
	if redis.call("get",KEYS[1]) == ARGV[1] 
	then
		return redis.call("del",KEYS[1])
	else
		return 0
	end
<?php
// php中使用redis執行lua腳本
$lua = <<<SCRIPT
     lua代碼
SCRIPT;
$s = $redis->eval($lua,'參數');
  1. 請求加鎖失敗的處理:
    • 拋出異常,稍後重試
    • 將請求添加到延時隊列
    • sleep幾秒鐘

分佈式鎖應用場景

  1. 訂單等併發請求
  2. 任務隊列
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章