分布式鎖原理及實現

2021-08-22 07:28:19 字數 3655 閱讀 9621

強烈推薦乙個大神的人工智慧的教程:

四、zookeeper實現分布式鎖

五、資料庫實現

多工環境

任務都需要對同一共享資源進行寫操作

對資源的訪問是互斥的

**塊加synchronized鎖或者reentrantlock鎖

if(setnx(key,1) == 1) finally 

}

存在的問題:命令不是原子操作,可能出現還沒有設定超時時間,服務宕機,導致鎖永遠存在

優化使用命令:

set(key,1,30,nx)
存在的問題:可能導致誤刪除,兩個執行緒都來拿鎖,a執行緒先獲得鎖之後,設定超時時間30s,在30s後執行緒還沒執行到del命令列,這時鎖就自己刪掉了,這時候b執行緒就可以拿到鎖,因此當a執行del的時候刪掉的就是b的鎖

優化:值為執行緒id,刪除時判斷是否是自己的key

加鎖:

string threadid = thread.currentthread().getid()

set(key,threadid ,30,nx)

解鎖:if(threadid .equals(redisclient.get(key)))

解決誤刪除問題:獲得鎖的執行緒開啟乙個守護執行緒,為這個鎖續時,每20s執行一次,給key延時20s

是乙個分布式協調服務

每乙個節點都是乙個znode

znode儲存的資料資訊。

acl:

記錄znode的訪問許可權,即哪些人或哪些ip可以訪問本節點。

stat:

包含znode的各種元資料,比如事務id、版本號、時間戳、大小等等。

child:

當前節點的子節點引用,類似於二叉樹的左孩子右孩子。

通過zab協議保證,採用二階段提交保證

* zk實現分布式鎖

*/@service

public class zookeeperimprovelock implements lock

}@override

//非阻塞時加鎖

public boolean trylock()

//獲取所有臨時節點並排序,臨時節點名稱為自增長的字串,如:00000000400

listchildren = this.client.getchildren(lock_path);

collections.sort(children);

system.out.println(children.tostring());

system.out.println(thread.currentthread().getname()+ "get0--->"+ children.get(0));

system.out.println(thread.currentthread().getname()+"currentpath"+ currentpath);

string realpath = lock_path+'/'+children.get(0);

system.out.println(thread.currentthread().getname()+ "real---"+ realpath);

if(currentpath.equals(realpath))else

int wz = collections.binarysearch(children,currentpath.substring(6));

beforepath = lock_path + '/' + children.get(wz-1);

system.out.println(thread.currentthread().getname()+"beforepath"+ beforepath);

}} catch (runtimeexception e)

return false;

}@override

public void lock() else

}private void waitforlock()

@override

public void handledatadeleted(string s) throws exception }};

//給排在前面的節點增加資料刪除的watcher

this.client.subscribedatachanges(beforepath,listener);

if(this.client.exists(beforepath)) catch (interruptedexception e)

}this.client.unsubscribedatachanges(beforepath,listener);

}@override

public void lockinterruptibly() throws interruptedexception

@override

public boolean trylock(long time, timeunit unit) throws interruptedexception

@override

public void unlock()

@override

public condition newcondition()

}唯一索引

行級鎖

/**

* mysql實現分布式鎖

*///@service

public class mysqllock implements lock catch (interruptedexception e)

lock();}}

// 非阻塞式的實現

public boolean trylock() catch (exception e)

return true;

}// 解鎖

public void unlock()

public condition newcondition()

public void lockinterruptibly() throws interruptedexception

public boolean trylock(long time, timeunit unit) throws interruptedexception

}

Redis分布式鎖原理及實現

ps 該篇博文目錄為 redis分布式鎖使用 中的 有瑕疵,為避免錯誤使用,請移步 感興趣的也可以看看到底瑕疵在哪 解決問題 多個程序多台機器,對乙個資料進行的操作的互斥。比如,下訂單和扣庫存的操作,這兩個操作必須連貫,乙個執行緒執行完這兩個操作後,下面乙個執行緒才可以介入執行,如果同時併發執行,極...

分布式鎖實現原理

拜託,面試請不要再問我redis分布式鎖的實現原理!石杉的架構筆記 可重入鎖 為什麼不建議使用redis分布鎖 主從切換可能丟失鎖資訊 考慮一下這樣的場景 在分布式環境中,很多併發需要鎖來同步,當使用redis分布式鎖,通用的做法是使用redis的setnx key value px 這樣的命令,設...

分布式鎖 哨兵模式 分布式鎖實現原理

背景 記錄對分布式鎖的相關理解,不斷提公升自己 可重入鎖 為什麼不建議使用redis分布鎖 主從切換可能丟失鎖資訊 考慮一下這樣的場景 在分布式環境中,很多併發需要鎖來同步,當使用redis分布式鎖,通用的做法是使用redis的setnx key value px 這樣的命令,設定乙個字段,當設定成...