1. 程式人生 > >隨想(二)-- 基於負載均衡和本地鎖的分散式鎖

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

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

其中
  • 使用者請求到WebServer之間是給予WebServer負載的負載均衡演算法
  • WebServer到儲存Server之間,是根據文件Id Hash實現的定向演算法,目的既有實現負載均衡,同時也可以利用本地的鎖,對同一個檔案的讀寫進行控制(尤其是寫),實現文件的版本和內容統一,例如如果兩個人在協同狀態下同時發出寫請求,我們會生成兩個版本,而不是後面覆蓋前面的。
分散式鎖的引入
  1. 文件同步問題
不同使用者協同的請求,很有可能會被不同的webServer所處理,所以協同請求同求在併發時就會出現問題。以下是分散式鎖引入前的流程:

以上流程的問題在於如果對於同一篇文件Step2和Step3,在不同的web server併發執行,也就是說兩個請求都會導致讀取最新版本文件和寫入快取,如果這個時候,兩個請求之間,又有協同的使用者,寫入了一個新的版本,就會導致兩個使用者獲得的協同內容不一致,從而導致協同失敗。
  1. 解決方案--分散式鎖
基於上述Item 1的描述,需要在Step 2/3處實現一個分散式鎖,保證同一時間只有一個請求讀取檔案,並寫入Redish分散式快取。經過當前框架和業務需求的以下幾點分析,我們決定採用基於當前webserver到儲存server的定向Hash和儲存server上的本地鎖,來實現分散式鎖
  • 從這個業務需求來看,分散式鎖和文件讀取,都是這個業務的關鍵點,也就是隻要一個失效,這個業務流程就需要終止,否則會產生意料不到的錯誤,例如,如果鎖有問題,導致兩個用在在不同版本上進行協同,產生的結果肯定是錯誤的。所以可以考慮將分散式鎖和文件讀取都分佈到儲存server上。
  • 從webserver到儲存server的RPC call,已經實現了基於文件Id的Hash定向,也就是說,從webserver到儲存server的rpc call,可以根據文件id, 定位到固定的儲存server上,所以可以用本地鎖來實現基於文件Id的分散式鎖
  • 儲存server已經實現了容錯機制,不會出現單點實現的問題,當前的分散式鎖也就天然的繼承了這個能力
  1. 具體實現
首先,基於一樣的RPC定向機制,實現tryToRequestLock和releaseCollabLock方法,提供給webserver進行呼叫,引數中包含文件id,以便進行store server的定向。 其次在store server上,實現一個本地鎖,最終基於文件ID的定向+本地鎖,就可以實現這個分散式鎖的需求了。本地鎖的實現可以用ReentrantLock來實現,一下是一個例子,供參考: /** 這個鎖通過一個計數器,判斷請求的人數 同時加上鎖過期的概念,防止呼叫者沒有釋放鎖的情況 */ public class CustomLock { // the lock for counter private final String lockName; private final Lock lockInst = new ReentrantLock(); private final Condition waitForLock = lockInst.newCondition(); private final HashMap<String, Long> lockRequestList = new HashMap<String, Long>(); private final long requestExpireSecs = 5 * 60; // five minutes public CustomLock(String lockName) { // here the lockName can map to the document ID this.lockName = lockName; } /** * Request the lock * the requester should be unique * */ public void tryToRequestLock(String requester, long expireMilli) { lockInst.lock(); try { long requestCount = this.pushIntoRequestList(requester); // for the first access, we don't need to wait if (requestCount > 1) { // if there are others to wait the lock, // current one should also wait try { if(!waitForLock.await(expireMilli, TimeUnit.MILLISECONDS)){ // if timeout, we should decline the request count and // throw timeout exception this.releaseRequest(requester); this.removeExpiredRequest(); throw new Exception(); }else{ // print some log } } catch (InterruptedException e) { throw new Exception(); } }else{ // print some log } }finally { lockInst.unlock(); } } /* 釋放鎖 */ public void tryToReleaseLock(String requester) throws YDriveException { lockInst.lock(); try { waitForLock.signal(); }finally { this.releaseRequest(requester); lockInst.unlock(); } } private long pushIntoRequestList(String requester) throws YDriveException{ long requestCount; synchronized (this.lockRequestList) { if(this.lockRequestList.containsKey(requester)){ throw new Exception(); } this.lockRequestList.put(requester, Long.valueOf(System.currentTimeMillis())); requestCount = this.lockRequestList.size(); } return requestCount; } private void releaseRequest(String requester) { synchronized (this.lockRequestList) { this.lockRequestList.remove(requester); } } /* * remove the expired request * */ private void removeExpiredRequest(){ Iterator<Map.Entry<String, Long>> itr = this.lockRequestList.entrySet().iterator(); if(itr != null){ while (itr.hasNext()){ Map.Entry<String, Long> request = itr.next(); long latency = (System.currentTimeMillis() - request.getValue().longValue()) / 1000; if(latency >= this.requestExpireSecs){ itr.remove(); } } } } }

相關推薦

隨想-- 基於負載均衡本地分散式

實現背景 業務需求實現多人對同一片文件的協同編輯,要求採用第一個發起請求時,當前文件的最新版本作為協同內容的基礎,多人同時請求時,要保證,所有請求獲得相同的文件內容 現有架構 其中 使用者請求到WebServer之間是給予WebServer負載的負載均衡演算法 W

Azure Traffic Manager 基於權重與基於優先順序的路由策略為我們的Web專案提供負載均衡

一,引言   上一片文章我們使用 Azure Traffic Manager 分發使用者請求,同時演示了兩種路由策略,“Performance”,“Geographic”的兩種方式,今天我們繼續講解 Traffic Manager profile 的其

Azure Load Balancer 基於內部的負載均衡來轉發為訪問請求

一,引言   上一節,我們使用 Azure Load Balancer 型別為外部的,來轉發我們的 Web 服務。今天我們看看另一種型別為 “Internal” 的 Azure Load Balancer。接下來,我們依舊先看看基礎架構圖。 --------------------

Spring Boot + Spring Cloud 構建微服務系統:服務消費負載Ribbon

使用RestTemplate呼叫服務 在上一篇教程中,我們是這樣呼叫服務的,先通過 LoadBalancerClient 選取出對應的服務,然後使用 RestTemplate 進行遠端呼叫。 LoadBalancerClient 就是負載均衡器,預設使用的是 Ribbon 的實現 RibbonLoadBa

Socket系列基於Socket網路通訊的服務端客戶端程式設計

        Socket系列一主要介紹了Socket的基礎知識、工作原理以及與傳統的http協議的區別。這部分內容的目的是為本文做鋪墊。本文將介紹基於Socket網路通訊的伺服器端和客戶端的程式設計。 一、伺服器端的程式設計         關於Socket伺服器端的

DNS服務器介紹——主從復制區域轉發

dns;區域轉發;主從復值背景介紹實際環境中為了避免單點故障,DNS服務器是由一組服務器組成每一個服務器上都有若幹個區域,不同服務器上的相同區域分為主和從兩種角色。由於正向和反向是不同的區域,所以多臺服務器間的相同區域可以互為主從或者一主多從,本處以右圖為例進行演示。DNS服務器的主從復制1.之前已經在172

apache atlas配置運行

altas href 訪問 min mage sta 功能 技術分享 -1 上一篇文章,我們已經構建出了altas的安裝包,所以我們繼續使用安裝包配置和運行atlas 首先解壓atlas壓縮包,授予bin目錄下的執行權限 1.默認啟動atlas cd atlas/bi

iptables實用教程:管理鏈策略

否則 命令顯示 accept 目的 number cep 存在 當前 末尾 概念和原理請參考上一篇文章“iptables實用教程(一)”。 本文講解如果管理iptables中的鏈和策略。 下面的代碼格式中,下劃線表示是一個占位符,需要根據實際情況輸入參數,不帶下劃線的表示是

來學學數據分析吧第一章 預測關聯數量特征

想要 夠快 均方誤差 容易 預測 適用於 color 就是 工程 Chapter 1 Regression: Predicting and Relating Quantitative Features 1.1 統計學,數據分析,回歸 統計學是利用數學來研究和提高從不完

springMVC學習總結路徑映射請求方法限定

根路徑 後臺 mapping oca log alt public mes cti springMVC學習總結(二)路徑映射和請求方法限定 一、路徑映射 無參數的訪問路徑 對springmvc項目的訪問路徑,是由根路徑和子路徑組成;在註解式開發中,根路徑標註在類名之上,子

Linux故障處理更改root密碼修復文件系統

無法識別 丟失 ges 包括 故障處理 磁盤 free roo ext4 Linux故障處理(二)更改root密碼和修復文件系統一、遺忘root用戶的密碼大多數時候Linux主機中具有root權限的用戶只有一個,因此需要通過其他途徑來重設root賬號密碼。最簡單的途徑是在開

設計模式學習筆記--簡單工廠模式工廠模式

bsp bubuko rac oid nds gen body () pri 老生長談的兩個設計模式了,這裏把這兩個設計模式對比著來總結一下。 什麽是簡單工廠模式? 簡單工廠模式:根據傳入工廠類的參數動態決定要創建哪一個產品類的實例。 UML圖如下(以實現一個計算器為例):

兩種開源聊天機器人的性能測試——基於tensorflow的chatbot

drive 找到 環境配置 gpu版本 hat dict 終端 開源 fontsize http://blog.csdn.net/hfutdog/article/details/78155676 開源項目鏈接:https://github.com/dennybritz/c

linux web服務器 基於域名,ip,端口的web虛擬主機

田峰 IT linux linux web服務器(二) 1 :搭建基於域名的虛擬主機 首先為兩個網站搭建dns服務器,並新建區域,分別為:www.goole.co

QtCreator插件開發——QtCreator菜單菜單項

QtCreator插件開發 菜單QtCreator插件開發(二)——QtCreator菜單和菜單項 一、QtCreator菜單欄簡介 1、QtCreator菜單簡介 QtCreator菜單欄如下:QtCreator默認菜單包括“文件”、“編輯”、“工具”、“窗體”、“幫助”。“構建”、“調試”、“分析”由插

MyBatis入門—— 輸入映射輸出映射、動態sql、關聯查詢

輸出類型 sql name屬性 一對一 test HA h標簽 自動 CI p.p4 { margin: 0.0px 0.0px 0.0px 10.0px; font: 10.5px "PingFang SC" } p.p6 { margin: 0.0px 0.0px 0.

MySQLMySQL的安裝簡單使用

cti loaded 都差不多 插入記錄 tro 提高 CI bsp 一個數 1、MySQL產品的介紹 MySQL數據庫屬於MySQL AB公司,總部位於瑞典,後被Oracle收購。 優點: (1)成本低:開放源代碼,可以免費使用 (2)性能高:執行很快 (2)簡單:很容易

C# 詞法分析器輸入緩沖代碼定位

自己 ML 轉換 .html 優點 有時 表示 error hub 系列導航 (一)詞法分析介紹 (二)輸入緩沖和代碼定位 (三)正則表達式 (四)構造 NFA (五)轉換 DFA (六)構造詞法分析器 (七)總結 一、輸入緩沖 在介紹如何進行

Mybatis基於註解的入門實例

調用 getc val void pass 搭建 for erb date 前言 上一篇簡單的介紹了Mybatis的概念和基於XML來實現數據庫的CRUD,這篇給大家實現基於註解的CRUD。 一、初始搭建 在基於註解當中前四步和上一篇基於XML是一樣的,分別是: 1)創建數

python作業實現註冊功能登陸功能

[] nbsp del inf pen pan style NPU pytho #1、實現註冊功能 輸入:username、passowrd,cpassowrd #最多可以輸錯3次 #3個都不能為空 #用戶名長度最少6位, 最長20位