關於分布式鎖的一種實現思路

2021-08-25 05:43:52 字數 1169 閱讀 7214

需求語言描述:多個節點競爭同一資源,且只能有乙個節點競爭成功;

場景描述:

最近在做乙個資料同步程式,因為es出色的查詢效能以及為了減輕與底層資料庫的互動,將底層資料庫如sqlserver中的資料同步到es。

在做了定時任務的統一排程和配置之後,由於是多人協同開發,所以各自本地都可能啟動乙個例項,那麼就相當於多個例項。但是同乙個同步程式(定時任務)在指定時間內我們只想排程(觸發)一次,而多個例項同時觸發,由於也沒有做es的鎖的控制,所以發現es會寫入重複的資料。舉個栗子,比如乙個名為 「jobbondguarantor」的定時任務,cron表示式設定的4個小時排程一次,那麼12點的時候,在沒有人修改排程表示式的時候,所有本地例項都會觸發定時任務,這樣就會造成es寫入資料重複(a例項先寫,b例項後寫),同理,16點,20點,8點等等,都有這樣的問題。

解決:2.利用資料庫的排他鎖,加上冪等解決。

解釋:資料庫設計

更新sql(冪等):

資料庫更新時的排他鎖,就是當有乙個執行緒(程序)更新這條資料時,那麼其他執行緒就不能更新這條資料了,這個鎖一般都是行級鎖,其他執行緒一般會等待獲取鎖,等拿到鎖之後執行相應的更新,如果超時則會取消,這個不絕對,和你用的持久層框架有關,你也可以自己寫持久層互動。

那麼為什麼要用冪等呢,比如a執行緒先搶到鎖,更新了,將 is_sync更新為1了,返回影響行數1行,這個沒問題,b執行緒在等待a執行緒更新完資料釋放鎖之後,獲取到鎖,執行更新,如果不用冪等,只是update edr_cloud_sync_job set is_sync =1 where job_name = ..., 那麼b執行緒更新返回影響行數也是1,我們無法區分ab執行緒到底是誰更新了is_sync=1,而用冪等,那麼b執行緒則會查不出資料,因為is_sync已經被a執行緒更新為1了,所以加上is_sync=0時,b執行緒更新返回影響行數為0。那麼就可以區分到底誰更改了is_sync=1,即有唯一乙個執行緒更改資料成功,那麼由他執行此次的任務即可。

一般而言,市面上資料庫預設更新時排他鎖,而且為行級鎖,如果是表級鎖也不是很適合用這個方法(一般也沒人會把更新做成表級鎖,即使需要,也另外設表),具體的還需要各位親測。

分布式概念 分布式鎖(分布式互斥的一種實現方式)

分布式系統中,多個節點都需要訪問乙個臨界資源,但是同一時刻只能有乙個節點可以訪問,為了解決這個問題就是要通過分布式互斥來實現 分布式鎖就是實現分布式互斥的一種實現方式。鎖是實現多執行緒同時訪問同一共享資源,保證同一時刻只有乙個執行緒可訪問共享資源所做的一種標記。分布式鎖是指分布式環境下,系統部署在多...

redis實現分布式鎖思路

redis 處理socket ready 事件是單執行緒執行的,也就是說redis一次只會處理乙個socket,避免了併發所帶來的資源競爭問題,可以用來實現分布式鎖.具體實現思路 通過setnx嘗試設值 currenttimestamp timeout 如果設定成功,說明類似獲取鎖操作成功,失敗則獲...

redis實現分布式鎖思路

1.利用redis的setnx命令 setnx name value 如果對應的name沒有被設定過,則會設定成功,如果設定過,則返回失敗。2.expire命令 可以對name設定過期時間,防止持有鎖的執行緒因為意外情況掛掉,導致業務阻塞。3.redis是單執行緒的機制。ps 第二條中expire命...