使用 etcd 的分佈式鎖進行選主的嘗試

最近做項目在使用 etcd, 由於項目裏很多定時任務,在實現高可用的時候需要進行選主,即只執行一次定時任務。之前的項目用的是 zookeeper 進行選主。大概思路是搶一個key,沒搶到的就不執行了,搶到的就執行,類似於 redis 的 setnx 。因爲項目本身用了 etcd,所以再引入 zookeeper 是不太合適的,同時 zookeeper 選主一旦定時任務如果執行失敗,無法重試。

etcd 的分佈式鎖

  • 本文使用的分佈式鎖是 etcd 的 v3lock,附上官網文檔
  • etcd 在創建分佈式鎖的時候必須綁定租約(Lease)。
  • 在獲取分佈式鎖的時候,如果鎖已經被創建,線程會阻塞,直到鎖被釋放。假設 A、B、C 三個線程租約都是 50 秒,同時去搶鎖,然後假設 A 線程搶到了,B、C 就都在阻塞了,必須等租約 50 秒到期,或者 A 釋放鎖。
  • 如果 A 在執行很順利,那麼執行成功之後,A 需要把自己的租約 ID 寫到 SuccessLease 這個 key 裏面。這樣 B、C 在獲取鎖之後,可以去查看 SuccessLease ,如果裏面對應的租約沒有到期,則說明 A 是執行成功了的,即無需再執行一次;如果租約到期了(上一次定時任務寫入的),或者這個 key 不存在,則說明之前的執行是失敗的,或者無效,那麼當前線程可以進行臨界區操作。
  • 如果 A 執行失敗,比如報錯了,或者線程掛了。那麼 B、C 只能等租約到期,再獲取鎖,請注意:這時候 B 和 C 會同時獲取鎖,所以必須 B、C 必須看一下自己的租約到期了沒有,如果到期了,說明獲取鎖是無效的,要新建一個租約,重新獲取鎖。

分佈式鎖選主流程設計

獲取成功
到期
沒到期
獲取成功
過期
獲取失敗
沒過期
Start
創建租約 LeaseA
獲取分佈式鎖 LockB
判斷 LeaseA 是否到期
進入臨界區
獲取 SuccessLease
判斷 SuccessLease 是否過期
進行操作
釋放 LockB 並退出臨界區
將 LeaseA 寫入 SuccessLease
結束

結束語

  • 第一次畫流程圖,有點長,路漫漫其修遠兮,加油加油!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章