隨想(二) 基於負載均衡和本地鎖的分布式鎖

2021-07-12 00:19:21 字數 1754 閱讀 3453

實現背景

業務需求

實現多人對同一片文件的協同編輯,要求採用第乙個發起請求時,當前文件的最新版本作為協同內容的基礎,多人同時請求時,要保證,所有請求獲得相同的文件內容

現有架構

分布式鎖的引入

文件同步問題

不同使用者協同的請求,很有可能會被不同的webserver所處理,所以協同請求同求在併發時就會出現問題。以下是分布式鎖引入前的流程:

以上流程的問題在於如果對於同一篇文件step2和step3,在不同的web server併發執行,也就是說兩個請求都會導致讀取最新版本文件和寫入快取,如果這個時候,兩個請求之間,又有

非協同的使用者,寫入了乙個新的版本,就會導致兩個使用者獲得的協同內容不一致,從而導致協同失敗。

解決方案--分布式鎖

基於上述item 1的描述,需要在step 2/3處實現乙個分布式鎖,保證同一時間只有乙個請求讀取檔案,並寫入redish分布式快取。經過當前框架和業務需求的以下幾點分析,我們決定

採用基於當前webserver到儲存server的定向hash和儲存server上的本地鎖,來實現分布式鎖:

具體實現

首先,基於一樣的rpc定向機制,實現trytorequestlock和releasecollablock方法,提供給webserver進行呼叫,引數中包含文件id,以便進行store server的定向。

其次在store server上,實現乙個本地鎖,最終基於文件id的定向+本地鎖,就可以實現這個分布式鎖的需求了。本地鎖的實現可以用reentrantlock來實現,一下是乙個例子,供參考:

/**這個鎖通過乙個計數器,判斷請求的人數

同時加上鎖過期的概念,防止呼叫者沒有釋放鎖的情況

*/public class customlock

/*** request the lock

* the requester should be unique

* */

public void trytorequestlock(string requester, long expiremilli) else

} catch (interruptedexception e)

}else

}finally }/*

釋放鎖*/

public void trytoreleaselock(string requester) throws ydriveexception finally

}private long pushintorequestlist(string requester) throws ydriveexception

this.lockrequestlist.put(requester, long.valueof(system.currenttimemillis()));

requestcount = this.lockrequestlist.size();

}return requestcount;

}private void releaserequest(string requester) }/*

* remove the expired request

* */

private void removeexpiredrequest()}}

} }

Nginx IIS分布式部署和負載均衡

建立2個 埠分別為9001 9002 在http節點下面新增 upstream backend server upstream backend server 為伺服器列表名稱,localhost為 本地 伺服器位址,9001 9002為站點埠,weight為權重,即隨機訪問到的站點概率。以上配置引數...

漫談分布式集群的負載均衡

為了理解分布式集群這個概念,我們先說說這兩個概念 集群 和 分布式 藝術 於生活,電腦科學亦是如此。我們先通過例子,來了解一下現實生活中的 集群 和 分布式 從開餐館說起 你開了一家餐館,自己掌勺後廚 即做菜 隨著生意越來越好,發現自己忙不過來。於是你聘請了兩個廚師,你們三位廚師就是乙個 集群 主要...

分布式架構的負載均衡演算法

輪詢 round robin 法 將請求按順序輪流分配到後台伺服器上,均衡的對待每一台伺服器,而不關心伺服器實際的連線數和當前的系統負載 缺點 當集群中伺服器硬體配置不同 效能差別大時,無法區別對待 隨機法 通過系統隨機函式,根據後台伺服器列表的大小值來隨機選取其中一台進行訪問。隨著呼叫量的增大,其...