当前位置: 首页>后端>正文

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 & 七种方案!探讨Redis分布式锁的正确使用姿势!

Redis鍒嗗竷寮忛攣鍩烘湰鍘熺悊

閲囩敤 redis 瀹炵幇鍒嗗竷寮忛攣锛屼富瑕佹槸鍒╃敤鍏跺崟绾跨▼鍛戒护鎵ц鐨勭壒鎬э紝涓€鑸槸 setnx锛?鍙細鏈変竴涓嚎绋嬩細鎵ц鎴愬姛锛屼篃灏辨槸鍙湁涓€涓嚎绋嬭兘鎴愬姛鑾峰彇閿侊紱 鐪嬬潃寰堝畬缇庛€傜劧鑰岋紝銆傘€傘€?/p>

鐪嬬湅鍙兘鏈変粈涔堥棶棰橈紵

涓€鑸敓浜х幆澧冧负浜嗗彲鐢ㄦ€э紝redis 浼氶儴缃?master-slave + sentinel 鐨勭粨鏋勶紝 濡傦細

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 & 七种方案!探讨Redis分布式锁的正确使用姿势!,第1张

master 鎻愪緵鏈嶅姟銆乻lave standby 浣滀负澶囦唤鑺傜偣涓嶆彁渚涙湇鍔★紝 master寮傛灏嗘暟鎹鍒剁粰 slave 浠ヤ繚璇佹暟鎹竴鑷达紝 sentinel鍝ㄥ叺妫€鏌?master鑺傜偣锛屽綋master鑺傜偣鏁呴殰鏃?灏唖lave鑺傜偣鎻愬崌涓?鏂扮殑master 瀵瑰鎻愪緵鏈嶅姟锛?/p>

姝e父鎯呭喌涓嬶紝閮芥槸褰撳墠 master 瀵瑰鎻愪緵鏈嶅姟锛屽涓嚎绋?setnx 鍙細鏈変竴涓垚鍔?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 & 七种方案!探讨Redis分布式锁的正确使用姿势!,第2张

褰?master 鏁呴殰鏃?/h2>

绾夸笂鐜鍢涳紝鎬讳細鏈夊悇绉嶅悇鏍风殑鏁呴殰鍑虹幇锛岃繖涔熸槸涓轰粈涔堣閮ㄧ讲 ha 鐨勫師鍥狅紱

鎴戜滑璁炬兂锛宼hread-1 setnx a 1 鎴愬姛鍚庯紝master鑺傜偣鍙戠敓鏁呴殰锛?strong>浣嗘槸锛屾鏃?a=1 杩欐潯鏁版嵁杩樻病鏉ュ緱鍙婂悓姝ュ埌 slave 鑺傜偣锛岀劧鍚?sentinel 鍝ㄥ叺浼氳繘琛屾晠闅滃垏鎹㈠皢 slave 鎻愬崌涓婃潵瀵瑰鎻愪緵鏈嶅姟锛?鐒跺悗 thread-2 鏉?setnx a 1 鍔犻攣锛屽洜涓轰箣鍓嶉攣鐘舵€佸湪 slave 涓嶅瓨鍦紝閭h繖鏃跺€?thread-2 涔熶細鍔犻攣鎴愬姛锛?杩欎釜鏃跺€欓攣鐨勮涔夊氨琚牬鍧忎簡锛?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 & 七种方案!探讨Redis分布式锁的正确使用姿势!,第3张

鍙傝€冮摼鎺ワ細https://www.cnblogs.com/mushishi/p/14959933.html

涓冪鏂规锛佹帰璁≧edis鍒嗗竷寮忛攣鐨勬纭娇鐢ㄥЭ鍔?/h2>

鍓嶈█

鏃ュ父寮€鍙戜腑锛岀鏉€涓嬪崟銆佹姠绾㈠寘绛夌瓑涓氬姟鍦烘櫙锛岄兘闇€瑕佺敤鍒板垎甯冨紡閿併€傝€孯edis闈炲父閫傚悎浣滀负鍒嗗竷寮忛攣浣跨敤銆傛湰鏂囧皢鍒嗕竷涓柟妗堝睍寮€锛岃窡澶у鎺㈣Redis鍒嗗竷寮忛攣鐨勬纭娇鐢ㄦ柟寮忋€傚鏋滄湁涓嶆纭殑鍦版柟锛屾杩庡ぇ瀹舵寚鍑哄搱锛屼竴璧峰涔犱竴璧疯繘姝ャ€?/p>

鍏紬鍙凤細鎹$敯铻虹殑灏忕敺瀛?/strong>

  • 浠€涔堟槸鍒嗗竷寮忛攣

  • 鏂规涓€锛歋ETNX + EXPIRE

  • 鏂规浜岋細SETNX + value鍊兼槸锛堢郴缁熸椂闂?杩囨湡鏃堕棿锛?/p>

  • 鏂规涓夛細浣跨敤Lua鑴氭湰(鍖呭惈SETNX + EXPIRE涓ゆ潯鎸囦护)

  • 鏂规鍥涳細SET鐨勬墿灞曞懡浠わ紙SET EX PX NX锛?/p>

  • 鏂规浜旓細SET EX PX NX + 鏍¢獙鍞竴闅忔満鍊?鍐嶉噴鏀鹃攣

  • 鏂规鍏? 寮€婧愭鏋?Redisson

  • 鏂规涓冿細澶氭満瀹炵幇鐨勫垎甯冨紡閿丷edlock

  • github鍦板潃锛屾劅璋㈡瘡棰梥tar

https://github.com/whx123/JavaHome

浠€涔堟槸鍒嗗竷寮忛攣

鍒嗗竷寮忛攣鍏跺疄灏辨槸锛屾帶鍒跺垎甯冨紡绯荤粺涓嶅悓杩涚▼鍏卞悓璁块棶鍏变韩璧勬簮鐨勪竴绉嶉攣鐨勫疄鐜般€傚鏋滀笉鍚岀殑绯荤粺鎴栧悓涓€涓郴缁熺殑涓嶅悓涓绘満涔嬮棿鍏变韩浜嗘煇涓复鐣岃祫婧愶紝寰€寰€闇€瑕佷簰鏂ユ潵闃叉褰兼骞叉壈锛屼互淇濊瘉涓€鑷存€с€?/p>

鎴戜滑鍏堟潵鐪嬩笅锛屼竴鎶婇潬璋辩殑鍒嗗竷寮忛攣搴旇鏈夊摢浜涚壒寰侊細

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 & 七种方案!探讨Redis分布式锁的正确使用姿势!,第4张
  • 浜掓枼鎬?/strong>: 浠绘剰鏃跺埢锛屽彧鏈変竴涓鎴风鑳芥寔鏈夐攣銆?/li>
  • 閿佽秴鏃堕噴鏀?/strong>锛氭寔鏈夐攣瓒呮椂锛屽彲浠ラ噴鏀撅紝闃叉涓嶅繀瑕佺殑璧勬簮娴垂锛屼篃鍙互闃叉姝婚攣銆?/li>
  • 鍙噸鍏ユ€?/strong>:涓€涓嚎绋嬪鏋滆幏鍙栦簡閿佷箣鍚?鍙互鍐嶆瀵瑰叾璇锋眰鍔犻攣銆?/li>
  • 楂樻€ц兘鍜岄珮鍙敤锛氬姞閿佸拰瑙i攣闇€瑕佸紑閿€灏藉彲鑳戒綆锛屽悓鏃朵篃瑕佷繚璇侀珮鍙敤锛岄伩鍏嶅垎甯冨紡閿佸け鏁堛€?/li>
  • 瀹夊叏鎬?/strong>锛氶攣鍙兘琚寔鏈夌殑瀹㈡埛绔垹闄わ紝涓嶈兘琚叾浠栧鎴风鍒犻櫎

Redis鍒嗗竷寮忛攣鏂规涓€锛歋ETNX + EXPIRE

鎻愬埌Redis鐨勫垎甯冨紡閿侊紝寰堝灏忎紮浼撮┈涓婂氨浼氭兂鍒?code>setnx+ expire鍛戒护銆傚嵆鍏堢敤setnx鏉ユ姠閿侊紝濡傛灉鎶㈠埌涔嬪悗锛屽啀鐢?code>expire缁欓攣璁剧疆涓€涓繃鏈熸椂闂达紝闃叉閿佸繕璁颁簡閲婃斁銆?/p>

SETNX 鏄疭ET IF NOT EXISTS鐨勭畝鍐?鏃ュ父鍛戒护鏍煎紡鏄疭ETNX key value锛屽鏋?key涓嶅瓨鍦紝鍒橲ETNX鎴愬姛杩斿洖1锛屽鏋滆繖涓猭ey宸茬粡瀛樺湪浜嗭紝鍒欒繑鍥?銆?/p>

鍋囪鏌愮數鍟嗙綉绔欑殑鏌愬晢鍝佸仛绉掓潃娲诲姩锛宬ey鍙互璁剧疆涓簁ey_resource_id,value璁剧疆浠绘剰鍊硷紝浼唬鐮佸涓嬶細

if锛坖edis.setnx(key_resource_id,lock_value) == 1锛墈 //鍔犻攣
    expire锛坘ey_resource_id锛?00锛? //璁剧疆杩囨湡鏃堕棿
    try {
        do something  //涓氬姟璇锋眰
    }catch(){
銆€銆€}
銆€銆€finally {
       jedis.del(key_resource_id); //閲婃斁閿?
    }
}
澶嶅埗浠g爜

浣嗘槸杩欎釜鏂规涓紝setnx鍜?code>expire涓や釜鍛戒护鍒嗗紑浜嗭紝涓嶆槸鍘熷瓙鎿嶄綔銆傚鏋滄墽琛屽畬setnx鍔犻攣锛屾瑕佹墽琛?code>expire璁剧疆杩囨湡鏃堕棿鏃讹紝杩涚▼crash鎴栬€呰閲嶅惎缁存姢浜嗭紝閭d箞杩欎釜閿佸氨鈥滈暱鐢熶笉鑰佲€濅簡锛?strong>鍒殑绾跨▼姘歌繙鑾峰彇涓嶅埌閿佸暒銆?/p>

Redis鍒嗗竷寮忛攣鏂规浜岋細SETNX + value鍊兼槸(绯荤粺鏃堕棿+杩囨湡鏃堕棿)

涓轰簡瑙e喅鏂规涓€锛?strong>鍙戠敓寮傚父閿佸緱涓嶅埌閲婃斁鐨勫満鏅?/strong>锛屾湁灏忎紮浼磋涓猴紝鍙互鎶婅繃鏈熸椂闂存斁鍒?code>setnx鐨剉alue鍊奸噷闈€傚鏋滃姞閿佸け璐ワ紝鍐嶆嬁鍑簐alue鍊兼牎楠屼竴涓嬪嵆鍙€傚姞閿佷唬鐮佸涓嬶細

long expires = System.currentTimeMillis() + expireTime; //绯荤粺鏃堕棿+璁剧疆鐨勮繃鏈熸椂闂?
String expiresStr = String.valueOf(expires);

// 濡傛灉褰撳墠閿佷笉瀛樺湪锛岃繑鍥炲姞閿佹垚鍔?
if (jedis.setnx(key_resource_id, expiresStr) == 1) {
        return true;
} 
// 濡傛灉閿佸凡缁忓瓨鍦紝鑾峰彇閿佺殑杩囨湡鏃堕棿
String currentValueStr = jedis.get(key_resource_id);

// 濡傛灉鑾峰彇鍒扮殑杩囨湡鏃堕棿锛屽皬浜庣郴缁熷綋鍓嶆椂闂达紝琛ㄧず宸茬粡杩囨湡
if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {

     // 閿佸凡杩囨湡锛岃幏鍙栦笂涓€涓攣鐨勮繃鏈熸椂闂达紝骞惰缃幇鍦ㄩ攣鐨勮繃鏈熸椂闂达紙涓嶄簡瑙edis鐨刧etSet鍛戒护鐨勫皬浼欎即锛屽彲浠ュ幓瀹樼綉鐪嬩笅鍝堬級
    String oldValueStr = jedis.getSet(key_resource_id, expiresStr);

    if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
         // 鑰冭檻澶氱嚎绋嬪苟鍙戠殑鎯呭喌锛屽彧鏈変竴涓嚎绋嬬殑璁剧疆鍊煎拰褰撳墠鍊肩浉鍚岋紝瀹冩墠鍙互鍔犻攣
         return true;
    }
}

//鍏朵粬鎯呭喌锛屽潎杩斿洖鍔犻攣澶辫触
return false;
}
澶嶅埗浠g爜

杩欎釜鏂规鐨勪紭鐐规槸锛屽阀濡欑Щ闄?code>expire鍗曠嫭璁剧疆杩囨湡鏃堕棿鐨勬搷浣滐紝鎶?strong>杩囨湡鏃堕棿鏀惧埌setnx鐨剉alue鍊?/strong>閲岄潰鏉ャ€傝В鍐充簡鏂规涓€鍙戠敓寮傚父锛岄攣寰椾笉鍒伴噴鏀剧殑闂銆備絾鏄繖涓柟妗堣繕鏈夊埆鐨勭己鐐癸細

  • 杩囨湡鏃堕棿鏄鎴风鑷繁鐢熸垚鐨勶紙System.currentTimeMillis()鏄綋鍓嶇郴缁熺殑鏃堕棿锛夛紝蹇呴』瑕佹眰鍒嗗竷寮忕幆澧冧笅锛屾瘡涓鎴风鐨勬椂闂村繀椤诲悓姝ャ€?/li>
  • 濡傛灉閿佽繃鏈熺殑鏃跺€欙紝骞跺彂澶氫釜瀹㈡埛绔悓鏃惰姹傝繃鏉ワ紝閮芥墽琛宩edis.getSet()锛屾渶缁堝彧鑳芥湁涓€涓鎴风鍔犻攣鎴愬姛锛屼絾鏄瀹㈡埛绔攣鐨勮繃鏈熸椂闂达紝鍙兘琚埆鐨勫鎴风瑕嗙洊
  • 璇ラ攣娌℃湁淇濆瓨鎸佹湁鑰呯殑鍞竴鏍囪瘑锛屽彲鑳借鍒殑瀹㈡埛绔噴鏀?瑙i攣銆?/li>

Redis鍒嗗竷寮忛攣鏂规涓夛細浣跨敤Lua鑴氭湰(鍖呭惈SETNX + EXPIRE涓ゆ潯鎸囦护)

瀹為檯涓婏紝鎴戜滑杩樺彲浠ヤ娇鐢↙ua鑴氭湰鏉ヤ繚璇佸師瀛愭€э紙鍖呭惈setnx鍜宔xpire涓ゆ潯鎸囦护锛夛紝lua鑴氭湰濡備笅锛?/p>

if redis.call('setnx',KEYS[1],ARGV[1]) == 1 then
   redis.call('expire',KEYS[1],ARGV[2])
else
   return 0
end;
澶嶅埗浠g爜

鍔犻攣浠g爜濡備笅锛?/p>

 String lua_scripts = "if redis.call('setnx',KEYS[1],ARGV[1]) == 1 then" +
            " redis.call('expire',KEYS[1],ARGV[2]) return 1 else return 0 end";   
Object result = jedis.eval(lua_scripts, Collections.singletonList(key_resource_id), Collections.singletonList(values));
//鍒ゆ柇鏄惁鎴愬姛
return result.equals(1L);
澶嶅埗浠g爜

杩欎釜鏂规杩樻槸鏈夌己鐐圭殑鍝︼紝鑷充簬鍝簺缂虹偣锛屼綘鍏堟€濊€冧竴涓嬨€備篃鍙互鎯充笅銆傝窡鏂规浜屽姣旓紝鍝釜鏇村ソ锛?/p>

Redis鍒嗗竷寮忛攣鏂规鏂规鍥涳細SET鐨勬墿灞曞懡浠わ紙SET EX PX NX锛?/h3>

闄や簡浣跨敤锛屼娇鐢↙ua鑴氭湰锛屼繚璇?code>SETNX + EXPIRE涓ゆ潯鎸囦护鐨勫師瀛愭€э紝鎴戜滑杩樺彲浠ュ阀鐢≧edis鐨凷ET鎸囦护鎵╁睍鍙傛暟锛侊紙SET key value[EX seconds][PX milliseconds][NX|XX]锛夛紝瀹冧篃鏄師瀛愭€х殑锛?/p>

SET key value[EX seconds][PX milliseconds][NX|XX]

  • NX :琛ㄧずkey涓嶅瓨鍦ㄧ殑鏃跺€欙紝鎵嶈兘set鎴愬姛锛屼篃鍗充繚璇佸彧鏈夌涓€涓鎴风璇锋眰鎵嶈兘鑾峰緱閿侊紝鑰屽叾浠栧鎴风璇锋眰鍙兘绛夊叾閲婃斁閿侊紝鎵嶈兘鑾峰彇銆?/li>
  • EX seconds :璁惧畾key鐨勮繃鏈熸椂闂达紝鏃堕棿鍗曚綅鏄銆?/li>
  • PX milliseconds: 璁惧畾key鐨勮繃鏈熸椂闂达紝鍗曚綅涓烘绉?/li>
  • XX: 浠呭綋key瀛樺湪鏃惰缃€?/li>

浼唬鐮乨emo濡備笅锛?/p>

if锛坖edis.set(key_resource_id, lock_value, "NX", "EX", 100s) == 1锛墈 //鍔犻攣
    try {
        do something  //涓氬姟澶勭悊
    }catch(){
銆€銆€}
銆€銆€finally {
       jedis.del(key_resource_id); //閲婃斁閿?
    }
}
澶嶅埗浠g爜

浣嗘槸鍛紝杩欎釜鏂规杩樻槸鍙兘瀛樺湪闂锛?/p>

  • 闂涓€锛?strong>閿佽繃鏈熼噴鏀句簡锛屼笟鍔¤繕娌℃墽琛屽畬銆傚亣璁剧嚎绋媋鑾峰彇閿佹垚鍔燂紝涓€鐩村湪鎵ц涓寸晫鍖虹殑浠g爜銆備絾鏄?00s杩囧幓鍚庯紝瀹冭繕娌℃墽琛屽畬銆備絾鏄紝杩欐椂鍊欓攣宸茬粡杩囨湡浜嗭紝姝ゆ椂绾跨▼b鍙堣姹傝繃鏉ャ€傛樉鐒剁嚎绋媌灏卞彲浠ヨ幏寰楅攣鎴愬姛锛屼篃寮€濮嬫墽琛屼复鐣屽尯鐨勪唬鐮併€傞偅涔堥棶棰樺氨鏉ヤ簡锛屼复鐣屽尯鐨勪笟鍔′唬鐮侀兘涓嶆槸涓ユ牸涓茶鎵ц鐨勫暒銆?/li>
  • 闂浜岋細閿佽鍒殑绾跨▼璇垹銆傚亣璁剧嚎绋媋鎵ц瀹屽悗锛屽幓閲婃斁閿併€備絾鏄畠涓嶇煡閬撳綋鍓嶇殑閿佸彲鑳芥槸绾跨▼b鎸佹湁鐨勶紙绾跨▼a鍘婚噴鏀鹃攣鏃讹紝鏈夊彲鑳借繃鏈熸椂闂村凡缁忓埌浜嗭紝姝ゆ椂绾跨▼b杩涙潵鍗犳湁浜嗛攣锛夈€傞偅绾跨▼a灏辨妸绾跨▼b鐨勯攣閲婃斁鎺変簡锛屼絾鏄嚎绋媌涓寸晫鍖轰笟鍔′唬鐮佸彲鑳介兘杩樻病鎵ц瀹屽憿銆?/li>

鏂规浜旓細SET EX PX NX + 鏍¢獙鍞竴闅忔満鍊?鍐嶅垹闄?/h3>

鏃㈢劧閿佸彲鑳借鍒殑绾跨▼璇垹锛岄偅鎴戜滑缁檝alue鍊艰缃竴涓爣璁板綋鍓嶇嚎绋嬪敮涓€鐨勯殢鏈烘暟锛屽湪鍒犻櫎鐨勬椂鍊欙紝鏍¢獙涓€涓嬶紝涓嶅氨OK浜嗗槢銆備吉浠g爜濡備笅锛?/p>

if锛坖edis.set(key_resource_id, uni_request_id, "NX", "EX", 100s) == 1锛墈 //鍔犻攣
    try {
        do something  //涓氬姟澶勭悊
    }catch(){
銆€銆€}
銆€銆€finally {
       //鍒ゆ柇鏄笉鏄綋鍓嶇嚎绋嬪姞鐨勯攣,鏄墠閲婃斁
       if (uni_request_id.equals(jedis.get(key_resource_id))) {
        jedis.del(lockKey); //閲婃斁閿?
        }
    }
}
澶嶅埗浠g爜

鍦ㄨ繖閲岋紝鍒ゆ柇鏄笉鏄綋鍓嶇嚎绋嬪姞鐨勯攣鍜?strong>閲婃斁閿?/strong>涓嶆槸涓€涓師瀛愭搷浣溿€傚鏋滆皟鐢╦edis.del()閲婃斁閿佺殑鏃跺€欙紝鍙兘杩欐妸閿佸凡缁忎笉灞炰簬褰撳墠瀹㈡埛绔紝浼氳В闄や粬浜哄姞鐨勯攣銆?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第5张

涓轰簡鏇翠弗璋紝涓€鑸篃鏄敤lua鑴氭湰浠f浛銆俵ua鑴氭湰濡備笅锛?/p>

if redis.call('get',KEYS[1]) == ARGV[1] then 
   return redis.call('del',KEYS[1]) 
else
   return 0
end;
澶嶅埗浠g爜

Redis鍒嗗竷寮忛攣鏂规鍏細Redisson妗嗘灦

鏂规浜旇繕鏄彲鑳藉瓨鍦?strong>閿佽繃鏈熼噴鏀撅紝涓氬姟娌℃墽琛屽畬鐨勯棶棰樸€傛湁浜涘皬浼欎即璁や负锛岀◢寰妸閿佽繃鏈熸椂闂磋缃暱涓€浜涘氨鍙互鍟︺€傚叾瀹炴垜浠鎯充竴涓嬶紝鏄惁鍙互缁欒幏寰楅攣鐨勭嚎绋嬶紝寮€鍚竴涓畾鏃跺畧鎶ょ嚎绋嬶紝姣忛殧涓€娈垫椂闂存鏌ラ攣鏄惁杩樺瓨鍦紝瀛樺湪鍒欏閿佺殑杩囨湡鏃堕棿寤堕暱锛岄槻姝㈤攣杩囨湡鎻愬墠閲婃斁銆?/p>

褰撳墠寮€婧愭鏋禦edisson瑙e喅浜嗚繖涓棶棰樸€傛垜浠竴璧锋潵鐪嬩笅Redisson搴曞眰鍘熺悊鍥惧惂锛?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第6张

鍙绾跨▼涓€鍔犻攣鎴愬姛锛屽氨浼氬惎鍔ㄤ竴涓?code>watch dog鐪嬮棬鐙楋紝瀹冩槸涓€涓悗鍙扮嚎绋嬶紝浼氭瘡闅?0绉掓鏌ヤ竴涓嬶紝濡傛灉绾跨▼1杩樻寔鏈夐攣锛岄偅涔堝氨浼氫笉鏂殑寤堕暱閿乲ey鐨勭敓瀛樻椂闂淬€傚洜姝わ紝Redisson灏辨槸浣跨敤Redisson瑙e喅浜?strong>閿佽繃鏈熼噴鏀撅紝涓氬姟娌℃墽琛屽畬闂銆?/p>

Redis鍒嗗竷寮忛攣鏂规涓冿細澶氭満瀹炵幇鐨勫垎甯冨紡閿?Redlock+Redisson

鍓嶉潰鍏鏂规閮藉彧鏄熀浜庡崟鏈虹増鐨勮璁猴紝杩樹笉鏄緢瀹岀編銆傚叾瀹濺edis涓€鑸兘鏄泦缇ら儴缃茬殑锛?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第7张

濡傛灉绾跨▼涓€鍦≧edis鐨刴aster鑺傜偣涓婃嬁鍒颁簡閿侊紝浣嗘槸鍔犻攣鐨刱ey杩樻病鍚屾鍒皊lave鑺傜偣銆傛伆濂借繖鏃讹紝master鑺傜偣鍙戠敓鏁呴殰锛屼竴涓猻lave鑺傜偣灏变細鍗囩骇涓簃aster鑺傜偣銆傜嚎绋嬩簩灏卞彲浠ヨ幏鍙栧悓涓猭ey鐨勯攣鍟︼紝浣嗙嚎绋嬩竴涔熷凡缁忔嬁鍒伴攣浜嗭紝閿佺殑瀹夊叏鎬у氨娌′簡銆?/p>

涓轰簡瑙e喅杩欎釜闂锛孯edis 浣滆€?antirez 鎻愬嚭涓€绉嶉珮绾х殑鍒嗗竷寮忛攣绠楁硶锛歊edlock銆俁edlock鏍稿績鎬濇兂鏄繖鏍风殑锛?/p>

鎼炲涓猂edis master閮ㄧ讲锛屼互淇濊瘉瀹冧滑涓嶄細鍚屾椂瀹曟帀銆傚苟涓旇繖浜沵aster鑺傜偣鏄畬鍏ㄧ浉浜掔嫭绔嬬殑锛岀浉浜掍箣闂翠笉瀛樺湪鏁版嵁鍚屾銆傚悓鏃讹紝闇€瑕佺‘淇濆湪杩欏涓猰aster瀹炰緥涓婏紝鏄笌鍦≧edis鍗曞疄渚嬶紝浣跨敤鐩稿悓鏂规硶鏉ヨ幏鍙栧拰閲婃斁閿併€?/p>

鎴戜滑鍋囪褰撳墠鏈?涓猂edis master鑺傜偣锛屽湪5鍙版湇鍔″櫒涓婇潰杩愯杩欎簺Redis瀹炰緥銆?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第8张

RedLock鐨勫疄鐜版楠わ紝濡備笅

  • 1.鑾峰彇褰撳墠鏃堕棿 t1锛屼互姣涓哄崟浣嶃€?/li>
  • 2.鎸夐『搴忓悜5涓猰aster鑺傜偣璇锋眰鍔犻攣銆傚鎴风璁剧疆缃戠粶杩炴帴鍜屽搷搴旇秴鏃舵椂闂达紝骞朵笖瓒呮椂鏃堕棿瑕佸皬浜庨攣鐨勫け鏁堟椂闂淬€傦紙鍋囪閿佽嚜鍔ㄥけ鏁堟椂闂翠负10绉掞紝鍒欒秴鏃舵椂闂翠竴鑸湪5-50姣涔嬮棿,鎴戜滑灏卞亣璁捐秴鏃舵椂闂存槸50ms鍚э級銆傚鏋滆秴鏃讹紝璺宠繃璇aster鑺傜偣锛屽敖蹇幓灏濊瘯涓嬩竴涓猰aster鑺傜偣銆?/li>
  • 3.瀹㈡埛绔娇鐢ㄥ綋鍓嶆椂闂?t2 鍑忓幓寮€濮嬭幏鍙栭攣鏃堕棿 t1锛堝嵆姝ラ1璁板綍鐨勬椂闂达級锛屽緱鍒拌幏鍙栭攣浣跨敤鐨勬椂闂淬€傚綋涓斾粎褰撹秴杩囦竴鍗婏紙N/2+1锛岃繖閲屾槸5/2+1=3涓妭鐐癸級鐨凴edis master鑺傜偣閮借幏寰楅攣锛屽苟涓斾娇鐢ㄧ殑鏃堕棿灏忎簬閿佸け鏁堟椂闂存椂锛岄攣鎵嶇畻鑾峰彇鎴愬姛銆傦紙濡備笂鍥撅紝10s> 30ms+40ms+50ms+4m0s+50ms锛?/li>
  • 4.濡傛灉鍙栧埌浜嗛攣锛宬ey鐨勭湡姝f湁鏁堟椂闂村氨鍙樺暒锛岄渶瑕佸噺鍘昏幏鍙栭攣鎵€浣跨敤鐨勬椂闂淬€?/li>
  • 5.濡傛灉鑾峰彇閿佸け璐ワ紙娌℃湁鍦ㄨ嚦灏慛/2+1涓猰aster瀹炰緥鍙栧埌閿侊紝鏈夋垨鑰呰幏鍙栭攣鏃堕棿宸茬粡瓒呰繃浜嗘湁鏁堟椂闂达級锛屽鎴风瑕佸湪鎵€鏈夌殑master鑺傜偣涓婅В閿侊紙鍗充究鏈変簺master鑺傜偣鏍规湰灏辨病鏈夊姞閿佹垚鍔燂紝涔熼渶瑕佽В閿侊紝浠ラ槻姝㈡湁浜涙紡缃戜箣楸硷級銆?/li>

绠€鍖栦笅姝ラ璇存槑灏辨槸锛?/p>

  • 鎸夐『搴忓悜5涓猰aster鑺傜偣璇锋眰鍔犻攣
  • 鏍规嵁璁剧疆鐨勮秴鏃舵椂闂存潵鍒ゆ柇锛屾槸涓嶆槸瑕佽烦杩囪master鑺傜偣銆?/li>
  • 濡傛灉澶т簬绛変簬涓変釜鑺傜偣鍔犻攣鎴愬姛锛屽苟涓斾娇鐢ㄧ殑鏃堕棿灏忎簬閿佺殑鏈夋晥鏈燂紝鍗冲彲璁ゅ畾鍔犻攣鎴愬姛鍟︺€?/li>
  • 濡傛灉鑾峰彇閿佸け璐ワ紝瑙i攣锛?/li>

Redisson瀹炵幇浜唕edLock鐗堟湰鐨勯攣锛屾湁鍏磋叮鐨勫皬浼欎即锛屽彲浠ュ幓浜嗚В涓€涓嬪搱~

鍏紬鍙?/h3>

娆㈣繋鍏虫敞鍏紬鍙凤細绂呬笌璁$畻鏈虹▼搴忚璁¤壓鏈?/p>

鍙傝€冧笌鎰熻阿

  • redis绯诲垪锛氬垎甯冨紡閿?/li>
  • 娴呮瀽 Redis 鍒嗗竷寮忛攣瑙e喅鏂规
  • 缁嗚Redis鍒嗗竷寮忛攣馃敀
  • Redlock锛歊edis鍒嗗竷寮忛攣鏈€鐗涢€肩殑瀹炵幇

娣卞害鍓栨瀽锛歊edis鍒嗗竷寮忛攣鍒板簳瀹夊叏鍚楋紵鐪嬪畬杩欑瘒鏂囩珷褰诲簳鎳備簡锛?/h2>

杩欑瘒鏂囩珷鎴戞兂鍜屼綘鑱婁竴鑱婏紝鍏充簬 Redis 鍒嗗竷寮忛攣鐨勩€屽畨鍏ㄦ€с€嶉棶棰樸€?/p>

Redis 鍒嗗竷寮忛攣鐨勮瘽棰橈紝寰堝鏂囩珷宸茬粡鍐欑儌浜嗭紝鎴戜负浠€涔堣繕瑕佸啓杩欑瘒鏂囩珷鍛紵

鍥犱负鎴戝彂鐜扮綉涓?99% 鐨勬枃绔狅紝骞舵病鏈夋妸杩欎釜闂鐪熸璁叉竻妤氥€傚鑷村緢澶氳鑰呯湅浜嗗緢澶氭枃绔狅紝渚濇棫浜戦噷闆鹃噷銆備緥濡備笅闈㈣繖浜涢棶棰橈紝浣犺兘娓呮櫚鍦板洖绛斾笂鏉ュ悧锛?/p>

  • 鍩轰簬 Redis 濡備綍瀹炵幇涓€涓垎甯冨紡閿侊紵
  • Redis 鍒嗗竷寮忛攣鐪熺殑瀹夊叏鍚楋紵
  • Redis 鐨?Redlock 鏈変粈涔堥棶棰橈紵涓€瀹氬畨鍏ㄥ悧锛?/li>
  • 涓氱晫浜夎 Redlock锛屽埌搴曞湪浜夎浠€涔堬紵鍝瑙傜偣鏄鐨勶紵
  • 鍒嗗竷寮忛攣鍒板簳鐢?Redis 杩樻槸 Zookeeper锛?/li>
  • 瀹炵幇涓€涓湁銆屽閿欐€с€嶇殑鍒嗗竷寮忛攣锛岄兘闇€瑕佽€冭檻鍝簺闂锛?/li>

杩欑瘒鏂囩珷锛屾垜灏辨潵鎶婅繖浜涢棶棰樺交搴曡娓呮銆?/p>

璇诲畬杩欑瘒鏂囩珷锛屼綘涓嶄粎鍙互褰诲簳浜嗚В鍒嗗竷寮忛攣锛岃繕浼氬銆屽垎甯冨紡绯荤粺銆嶆湁鏇村姞娣卞埢鐨勭悊瑙c€?/p>

鏂囩珷鏈夌偣闀匡紝浣嗗共璐у緢澶氾紝甯屾湜浣犲彲浠ヨ€愬績璇诲畬銆?/strong>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第9张

涓轰粈涔堥渶瑕佸垎甯冨紡閿侊紵

鍦ㄥ紑濮嬭鍒嗗竷寮忛攣涔嬪墠锛屾湁蹇呰绠€鍗曚粙缁嶄竴涓嬶紝涓轰粈涔堥渶瑕佸垎甯冨紡閿侊紵

涓庡垎甯冨紡閿佺浉瀵瑰簲鐨勬槸銆屽崟鏈洪攣銆嶏紝鎴戜滑鍦ㄥ啓澶氱嚎绋嬬▼搴忔椂锛岄伩鍏嶅悓鏃舵搷浣滀竴涓叡浜彉閲忎骇鐢熸暟鎹棶棰橈紝閫氬父浼氫娇鐢ㄤ竴鎶婇攣鏉ャ€屼簰鏂ャ€嶏紝浠ヤ繚璇佸叡浜彉閲忕殑姝g‘鎬э紝鍏朵娇鐢ㄨ寖鍥存槸鍦ㄣ€屽悓涓€涓繘绋嬨€嶄腑銆?/p>

濡傛灉鎹㈠仛鏄涓繘绋嬶紝闇€瑕佸悓鏃舵搷浣滀竴涓叡浜祫婧愶紝濡備綍浜掓枼鍛紵

渚嬪锛岀幇鍦ㄧ殑涓氬姟搴旂敤閫氬父閮芥槸寰湇鍔℃灦鏋勶紝杩欎篃鎰忓懗鐫€涓€涓簲鐢ㄤ細閮ㄧ讲澶氫釜杩涚▼锛岄偅杩欏涓繘绋嬪鏋滈渶瑕佷慨鏀?MySQL 涓殑鍚屼竴琛岃褰曟椂锛屼负浜嗛伩鍏嶆搷浣滀贡搴忓鑷存暟鎹敊璇紝姝ゆ椂锛屾垜浠氨闇€瑕佸紩鍏ャ€屽垎甯冨紡閿併€嶆潵瑙e喅杩欎釜闂浜嗐€?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第10张

鎯宠瀹炵幇鍒嗗竷寮忛攣锛屽繀椤诲€熷姪涓€涓閮ㄧ郴缁燂紝鎵€鏈夎繘绋嬮兘鍘昏繖涓郴缁熶笂鐢宠銆屽姞閿併€嶃€?/p>

鑰岃繖涓閮ㄧ郴缁燂紝蹇呴』瑕佸疄鐜般€屼簰鏂ャ€嶇殑鑳藉姏锛屽嵆涓や釜璇锋眰鍚屾椂杩涙潵锛屽彧浼氱粰涓€涓繘绋嬭繑鍥炴垚鍔燂紝鍙︿竴涓繑鍥炲け璐ワ紙鎴栫瓑寰咃級銆?/p>

杩欎釜澶栭儴绯荤粺锛屽彲浠ユ槸 MySQL锛屼篃鍙互鏄?Redis 鎴?Zookeeper銆備絾涓轰簡杩芥眰鏇村ソ鐨勬€ц兘锛屾垜浠€氬父浼氶€夋嫨浣跨敤 Redis 鎴?Zookeeper 鏉ュ仛銆?/p>

涓嬮潰鎴戝氨浠?Redis 涓轰富绾匡紝鐢辨祬鍏ユ繁锛屽甫浣犳繁搴﹀墫鏋愪竴涓嬶紝鍒嗗竷寮忛攣鐨勫悇绉嶃€屽畨鍏ㄦ€с€嶉棶棰橈紝甯綘褰诲簳鐞嗚В鍒嗗竷寮忛攣銆?/p>

鍒嗗竷寮忛攣鎬庝箞瀹炵幇锛?/h2>

鎴戜滑浠庢渶绠€鍗曠殑寮€濮嬭璧枫€?/p>

鎯宠瀹炵幇鍒嗗竷寮忛攣锛屽繀椤昏姹?Redis 鏈夈€屼簰鏂ャ€嶇殑鑳藉姏锛屾垜浠彲浠ヤ娇鐢?SETNX 鍛戒护锛岃繖涓懡浠よ〃绀?strong>SET if Not eXists锛屽嵆濡傛灉 key 涓嶅瓨鍦紝鎵嶄細璁剧疆瀹冪殑鍊硷紝鍚﹀垯浠€涔堜篃涓嶅仛銆?/p>

涓や釜瀹㈡埛绔繘绋嬪彲浠ユ墽琛岃繖涓懡浠わ紝杈惧埌浜掓枼锛屽氨鍙互瀹炵幇涓€涓垎甯冨紡閿併€?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第11张

姝ゆ椂锛屽姞閿佹垚鍔熺殑瀹㈡埛绔紝灏卞彲浠ュ幓鎿嶄綔銆屽叡浜祫婧愩€嶏紝渚嬪锛屼慨鏀?MySQL 鐨勬煇涓€琛屾暟鎹紝鎴栬€呰皟鐢ㄤ竴涓?API 璇锋眰銆?/p>

鎿嶄綔瀹屾垚鍚庯紝杩樿鍙婃椂閲婃斁閿侊紝缁欏悗鏉ヨ€呰鍑烘搷浣滃叡浜祫婧愮殑鏈轰細銆傚浣曢噴鏀鹃攣鍛紵

涔熷緢绠€鍗曪紝鐩存帴浣跨敤 DEL 鍛戒护鍒犻櫎杩欎釜 key 鍗冲彲锛?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第12张

杩欎釜閫昏緫闈炲父绠€鍗曪紝鏁翠綋鐨勮矾绋嬪氨鏄繖鏍凤細

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第13张

浣嗘槸锛屽畠瀛樺湪涓€涓緢澶х殑闂锛屽綋瀹㈡埛绔?1 鎷垮埌閿佸悗锛屽鏋滃彂鐢熶笅闈㈢殑鍦烘櫙锛屽氨浼氶€犳垚銆屾閿併€嶏細

  1. 绋嬪簭澶勭悊涓氬姟閫昏緫寮傚父锛屾病鍙婃椂閲婃斁閿?/li>
  2. 杩涚▼鎸備簡锛屾病鏈轰細閲婃斁閿?/li>

杩欐椂锛岃繖涓鎴风灏变細涓€鐩村崰鐢ㄨ繖涓攣锛岃€屽叾瀹冨鎴风灏便€屾案杩溿€嶆嬁涓嶅埌杩欐妸閿佷簡銆?/p>

鎬庝箞瑙e喅杩欎釜闂鍛紵

濡備綍閬垮厤姝婚攣锛?/h2>

鎴戜滑寰堝鏄撴兂鍒扮殑鏂规鏄紝鍦ㄧ敵璇烽攣鏃讹紝缁欒繖鎶婇攣璁剧疆涓€涓€岀鏈熴€嶃€?/p>

鍦?Redis 涓疄鐜版椂锛屽氨鏄粰杩欎釜 key 璁剧疆涓€涓€岃繃鏈熸椂闂淬€嶃€傝繖閲屾垜浠亣璁撅紝鎿嶄綔鍏变韩璧勬簮鐨勬椂闂翠笉浼氳秴杩?10s锛岄偅涔堝湪鍔犻攣鏃讹紝缁欒繖涓?key 璁剧疆 10s 杩囨湡鍗冲彲锛?/p>

127.0.0.1:6379> SETNX lock 1    // 鍔犻攣
(integer) 1
127.0.0.1:6379> EXPIRE lock 10  // 10s鍚庤嚜鍔ㄨ繃鏈?
(integer) 1

杩欐牱涓€鏉ワ紝鏃犺瀹㈡埛绔槸鍚﹀紓甯革紝杩欎釜閿侀兘鍙互鍦?10s 鍚庤銆岃嚜鍔ㄩ噴鏀俱€嶏紝鍏跺畠瀹㈡埛绔緷鏃у彲浠ユ嬁鍒伴攣銆?/p>

浣嗚繖鏍风湡鐨勬病闂鍚楋紵

杩樻槸鏈夐棶棰樸€?/p>

鐜板湪鐨勬搷浣滐紝鍔犻攣銆佽缃繃鏈熸槸 2 鏉″懡浠わ紝鏈夋病鏈夊彲鑳藉彧鎵ц浜嗙涓€鏉★紝绗簩鏉″嵈銆屾潵涓嶅強銆嶆墽琛岀殑鎯呭喌鍙戠敓鍛紵渚嬪锛?/p>

  1. SETNX 鎵ц鎴愬姛锛屾墽琛?EXPIRE 鏃剁敱浜庣綉缁滈棶棰橈紝鎵ц澶辫触
  2. SETNX 鎵ц鎴愬姛锛孯edis 寮傚父瀹曟満锛孍XPIRE 娌℃湁鏈轰細鎵ц
  3. SETNX 鎵ц鎴愬姛锛屽鎴风寮傚父宕╂簝锛孍XPIRE 涔熸病鏈夋満浼氭墽琛?/li>

鎬讳箣锛岃繖涓ゆ潯鍛戒护涓嶈兘淇濊瘉鏄師瀛愭搷浣滐紙涓€璧锋垚鍔燂級锛屽氨鏈夋綔鍦ㄧ殑椋庨櫓瀵艰嚧杩囨湡鏃堕棿璁剧疆澶辫触锛屼緷鏃у彂鐢熴€屾閿併€嶉棶棰樸€?/p>

鎬庝箞鍔烇紵

鍦?Redis 2.6.12 鐗堟湰涔嬪墠锛屾垜浠渶瑕佹兂灏藉姙娉曪紝淇濊瘉 SETNX 鍜?EXPIRE 鍘熷瓙鎬ф墽琛岋紝杩樿鑰冭檻鍚勭寮傚父鎯呭喌濡備綍澶勭悊銆?/p>

浣嗗湪 Redis 2.6.12 涔嬪悗锛孯edis 鎵╁睍浜?SET 鍛戒护鐨勫弬鏁帮紝鐢ㄨ繖涓€鏉″懡浠ゅ氨鍙互浜嗭細

// 涓€鏉″懡浠や繚璇佸師瀛愭€ф墽琛?
127.0.0.1:6379> SET lock 1 EX 10 NX
OK

杩欐牱灏辫В鍐充簡姝婚攣闂锛屼篃姣旇緝绠€鍗曘€?/p>

鎴戜滑鍐嶆潵鐪嬪垎鏋愪笅锛屽畠杩樻湁浠€涔堥棶棰橈紵

璇曟兂杩欐牱涓€绉嶅満鏅細

  1. 瀹㈡埛绔?1 鍔犻攣鎴愬姛锛屽紑濮嬫搷浣滃叡浜祫婧?/li>
  2. 瀹㈡埛绔?1 鎿嶄綔鍏变韩璧勬簮鐨勬椂闂达紝銆岃秴杩囥€嶄簡閿佺殑杩囨湡鏃堕棿锛岄攣琚€岃嚜鍔ㄩ噴鏀俱€?/li>
  3. 瀹㈡埛绔?2 鍔犻攣鎴愬姛锛屽紑濮嬫搷浣滃叡浜祫婧?/li>
  4. 瀹㈡埛绔?1 鎿嶄綔鍏变韩璧勬簮瀹屾垚锛岄噴鏀鹃攣锛堜絾閲婃斁鐨勬槸瀹㈡埛绔?2 鐨勯攣锛?/li>

鐪嬪埌浜嗕箞锛岃繖閲屽瓨鍦ㄤ袱涓弗閲嶇殑闂锛?/p>

  1. 閿佽繃鏈?/strong>锛氬鎴风 1 鎿嶄綔鍏变韩璧勬簮鑰楁椂澶箙锛屽鑷撮攣琚嚜鍔ㄩ噴鏀撅紝涔嬪悗琚鎴风 2 鎸佹湁
  2. 閲婃斁鍒汉鐨勯攣锛氬鎴风 1 鎿嶄綔鍏变韩璧勬簮瀹屾垚鍚庯紝鍗村張閲婃斁浜嗗鎴风 2 鐨勯攣

瀵艰嚧杩欎袱涓棶棰樼殑鍘熷洜鏄粈涔堬紵鎴戜滑涓€涓釜鏉ョ湅銆?/p>

绗竴涓棶棰橈紝鍙兘鏄垜浠瘎浼版搷浣滃叡浜祫婧愮殑鏃堕棿涓嶅噯纭鑷寸殑銆?/strong>

渚嬪锛屾搷浣滃叡浜祫婧愮殑鏃堕棿銆屾渶鎱€嶅彲鑳介渶瑕?15s锛岃€屾垜浠嵈鍙缃簡 10s 杩囨湡锛岄偅杩欏氨瀛樺湪閿佹彁鍓嶈繃鏈熺殑椋庨櫓銆?/p>

杩囨湡鏃堕棿澶煭锛岄偅澧炲ぇ鍐椾綑鏃堕棿锛屼緥濡傝缃繃鏈熸椂闂翠负 20s锛岃繖鏍锋€诲彲浠ヤ簡鍚э紵

杩欐牱纭疄鍙互銆岀紦瑙c€嶈繖涓棶棰橈紝闄嶄綆鍑洪棶棰樼殑姒傜巼锛屼絾渚濇棫鏃犳硶銆屽交搴曡В鍐炽€嶉棶棰樸€?/p>

涓轰粈涔堬紵

鍘熷洜鍦ㄤ簬锛屽鎴风鍦ㄦ嬁鍒伴攣涔嬪悗锛屽湪鎿嶄綔鍏变韩璧勬簮鏃讹紝閬囧埌鐨勫満鏅湁鍙兘鏄緢澶嶆潅鐨勶紝渚嬪锛岀▼搴忓唴閮ㄥ彂鐢熷紓甯搞€佺綉缁滆姹傝秴鏃剁瓑绛夈€?/p>

鏃㈢劧鏄€岄浼般€嶆椂闂达紝涔熷彧鑳芥槸澶ц嚧璁$畻锛岄櫎闈炰綘鑳介鏂欏苟瑕嗙洊鍒版墍鏈夊鑷磋€楁椂鍙橀暱鐨勫満鏅紝浣嗚繖鍏跺疄寰堥毦銆?/p>

鏈変粈涔堟洿濂界殑瑙e喅鏂规鍚楋紵

鍒€ワ紝鍏充簬杩欎釜闂锛屾垜浼氬湪鍚庨潰璇︾粏鏉ヨ瀵瑰簲鐨勮В鍐虫柟妗堛€?/p>

鎴戜滑缁х画鏉ョ湅绗簩涓棶棰樸€?/p>

绗簩涓棶棰樺湪浜庯紝涓€涓鎴风閲婃斁浜嗗叾瀹冨鎴风鎸佹湁鐨勯攣銆?/strong>

鎯充竴涓嬶紝瀵艰嚧杩欎釜闂鐨勫叧閿偣鍦ㄥ摢锛?/p>

閲嶇偣鍦ㄤ簬锛屾瘡涓鎴风鍦ㄩ噴鏀鹃攣鏃讹紝閮芥槸銆屾棤鑴戙€嶆搷浣滐紝骞舵病鏈夋鏌ヨ繖鎶婇攣鏄惁杩樸€屽綊鑷繁鎸佹湁銆嶏紝鎵€浠ュ氨浼氬彂鐢熼噴鏀惧埆浜洪攣鐨勯闄╋紝杩欐牱鐨勮В閿佹祦绋嬶紝寰堜笉銆屼弗璋ㄣ€嶏紒

濡備綍瑙e喅杩欎釜闂鍛紵

閿佽鍒汉閲婃斁鎬庝箞鍔?

瑙e喅鍔炴硶鏄細瀹㈡埛绔湪鍔犻攣鏃讹紝璁剧疆涓€涓彧鏈夎嚜宸辩煡閬撶殑銆屽敮涓€鏍囪瘑銆嶈繘鍘汇€?/p>

渚嬪锛屽彲浠ユ槸鑷繁鐨勭嚎绋?ID锛屼篃鍙互鏄竴涓?UUID锛堥殢鏈轰笖鍞竴锛夛紝杩欓噷鎴戜滑浠?UUID 涓句緥锛?/p>

// 閿佺殑VALUE璁剧疆涓篣UID
127.0.0.1:6379> SET lock $uuid EX 20 NX
OK

杩欓噷鍋囪 20s 鎿嶄綔鍏变韩鏃堕棿瀹屽叏瓒冲锛屽厛涓嶈€冭檻閿佽嚜鍔ㄨ繃鏈熺殑闂銆?/p>

涔嬪悗锛屽湪閲婃斁閿佹椂锛岃鍏堝垽鏂繖鎶婇攣鏄惁杩樺綊鑷繁鎸佹湁锛屼吉浠g爜鍙互杩欎箞鍐欙細

// 閿佹槸鑷繁鐨勶紝鎵嶉噴鏀?
if redis.get("lock") == $uuid:
    redis.del("lock")

杩欓噷閲婃斁閿佷娇鐢ㄧ殑鏄?GET + DEL 涓ゆ潯鍛戒护锛岃繖鏃讹紝鍙堜細閬囧埌鎴戜滑鍓嶉潰璁茬殑鍘熷瓙鎬ч棶棰樹簡銆?/p>

  1. 瀹㈡埛绔?1 鎵ц GET锛屽垽鏂攣鏄嚜宸辩殑
  2. 瀹㈡埛绔?2 鎵ц浜?SET 鍛戒护锛屽己鍒惰幏鍙栧埌閿侊紙铏界劧鍙戠敓姒傜巼姣旇緝浣庯紝浣嗘垜浠渶瑕佷弗璋ㄥ湴鑰冭檻閿佺殑瀹夊叏鎬фā鍨嬶級
  3. 瀹㈡埛绔?1 鎵ц DEL锛屽嵈閲婃斁浜嗗鎴风 2 鐨勯攣

鐢辨鍙锛岃繖涓や釜鍛戒护杩樻槸蹇呴』瑕佸師瀛愭墽琛屾墠琛屻€?/p>

鎬庢牱鍘熷瓙鎵ц鍛紵Lua 鑴氭湰銆?/p>

鎴戜滑鍙互鎶婅繖涓€昏緫锛屽啓鎴?Lua 鑴氭湰锛岃 Redis 鏉ユ墽琛屻€?/p>

鍥犱负 Redis 澶勭悊姣忎竴涓姹傛槸銆屽崟绾跨▼銆嶆墽琛岀殑锛屽湪鎵ц涓€涓?Lua 鑴氭湰鏃讹紝鍏跺畠璇锋眰蹇呴』绛夊緟锛岀洿鍒拌繖涓?Lua 鑴氭湰澶勭悊瀹屾垚锛岃繖鏍蜂竴鏉ワ紝GET + DEL 涔嬮棿灏变笉浼氭彃鍏ュ叾瀹冨懡浠や簡銆?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第14张

瀹夊叏閲婃斁閿佺殑 Lua 鑴氭湰濡備笅锛?/p>

// 鍒ゆ柇閿佹槸鑷繁鐨勶紝鎵嶉噴鏀?
if redis.call("GET",KEYS[1]) == ARGV[1]
then
    return redis.call("DEL",KEYS[1])
else
    return 0
end

濂戒簡锛岃繖鏍蜂竴璺紭鍖栵紝鏁翠釜鐨勫姞閿併€佽В閿佺殑娴佺▼灏辨洿銆屼弗璋ㄣ€嶄簡銆?/p>

杩欓噷鎴戜滑鍏堝皬缁撲竴涓嬶紝鍩轰簬 Redis 瀹炵幇鐨勫垎甯冨紡閿侊紝涓€涓弗璋ㄧ殑鐨勬祦绋嬪涓嬶細

  1. 鍔犻攣锛歋ET Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,lock_key,第15张unique_id EX $expire_time NX
  2. 鎿嶄綔鍏变韩璧勬簮
  3. 閲婃斁閿侊細Lua 鑴氭湰锛屽厛 GET 鍒ゆ柇閿佹槸鍚﹀綊灞炶嚜宸憋紝鍐?DEL 閲婃斁閿?/li>
Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第16张

濂斤紝鏈変簡杩欎釜瀹屾暣鐨勯攣妯″瀷锛岃鎴戜滑閲嶆柊鍥炲埌鍓嶉潰鎻愬埌鐨勭涓€涓棶棰樸€?/p>

閿佽繃鏈熸椂闂翠笉濂借瘎浼版€庝箞鍔烇紵

鍓嶉潰鎴戜滑鎻愬埌锛岄攣鐨勮繃鏈熸椂闂村鏋滆瘎浼颁笉濂斤紝杩欎釜閿佸氨浼氭湁銆屾彁鍓嶃€嶈繃鏈熺殑椋庨櫓銆?/p>

褰撴椂缁欑殑濡ュ崗鏂规鏄紝灏介噺銆屽啑浣欍€嶈繃鏈熸椂闂达紝闄嶄綆閿佹彁鍓嶈繃鏈熺殑姒傜巼銆?/p>

杩欎釜鏂规鍏跺疄涔熶笉鑳藉畬缇庤В鍐抽棶棰橈紝閭f€庝箞鍔炲憿锛?/p>

鐪嬮棬鐙?watch dog 鑷姩缁湡

鏄惁鍙互璁捐杩欐牱鐨勬柟妗堬細鍔犻攣鏃讹紝鍏堣缃竴涓繃鏈熸椂闂达紝鐒跺悗鎴戜滑寮€鍚竴涓€屽畧鎶ょ嚎绋嬨€嶏紝瀹氭椂鍘绘娴嬭繖涓攣鐨勫け鏁堟椂闂达紝濡傛灉閿佸揩瑕佽繃鏈熶簡锛屾搷浣滃叡浜祫婧愯繕鏈畬鎴愶紝閭d箞灏辫嚜鍔ㄥ閿佽繘琛屻€岀画鏈熴€嶏紝閲嶆柊璁剧疆杩囨湡鏃堕棿銆?/strong>

杩欑‘瀹炰竴绉嶆瘮杈冨ソ鐨勬柟妗堛€?/p>

濡傛灉浣犳槸 Java 鎶€鏈爤锛屽垢杩愮殑鏄紝宸茬粡鏈変竴涓簱鎶婅繖浜涘伐浣滈兘灏佽濂戒簡锛?strong>Redisson銆?/p>

Redisson 鏄竴涓?Java 璇█瀹炵幇鐨?Redis SDK 瀹㈡埛绔紝鍦ㄤ娇鐢ㄥ垎甯冨紡閿佹椂锛屽畠灏遍噰鐢ㄤ簡銆岃嚜鍔ㄧ画鏈熴€嶇殑鏂规鏉ラ伩鍏嶉攣杩囨湡锛岃繖涓畧鎶ょ嚎绋嬫垜浠竴鑸篃鎶婂畠鍙仛銆岀湅闂ㄧ嫍銆嶇嚎绋嬨€?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第17张

闄ゆ涔嬪锛岃繖涓?SDK 杩樺皝瑁呬簡寰堝鏄撶敤鐨勫姛鑳斤細

  • 鍙噸鍏ラ攣
  • 涔愯閿?/li>
  • 鍏钩閿?/li>
  • 璇诲啓閿?/li>
  • Redlock锛堢孩閿侊紝涓嬮潰浼氳缁嗚锛?/li>

杩欎釜 SDK 鎻愪緵鐨?API 闈炲父鍙嬪ソ锛屽畠鍙互鍍忔搷浣滄湰鍦伴攣鐨勬柟寮忥紝鎿嶄綔鍒嗗竷寮忛攣銆傚鏋滀綘鏄?Java 鎶€鏈爤锛屽彲浠ョ洿鎺ユ妸瀹冪敤璧锋潵銆?/p>

杩欓噷涓嶉噸鐐逛粙缁?Redisson 鐨勪娇鐢紝澶у鍙互鐪嬪畼鏂?Github 瀛︿範濡備綍浣跨敤锛屾瘮杈冪畝鍗曘€?/p>

鍒拌繖閲屾垜浠啀灏忕粨涓€涓嬶紝鍩轰簬 Redis 鐨勫疄鐜板垎甯冨紡閿侊紝鍓嶉潰閬囧埌鐨勯棶棰橈紝浠ュ強瀵瑰簲鐨勮В鍐虫柟妗堬細

  • 姝婚攣锛氳缃繃鏈熸椂闂?/li>
  • 杩囨湡鏃堕棿璇勪及涓嶅ソ锛岄攣鎻愬墠杩囨湡锛氬畧鎶ょ嚎绋嬶紝鑷姩缁湡
  • 閿佽鍒汉閲婃斁锛氶攣鍐欏叆鍞竴鏍囪瘑锛岄噴鏀鹃攣鍏堟鏌ユ爣璇嗭紝鍐嶉噴鏀?/li>

杩樻湁鍝簺闂鍦烘櫙锛屼細鍗卞 Redis 閿佺殑瀹夊叏鎬у憿锛?/p>

涔嬪墠鍒嗘瀽鐨勫満鏅兘鏄紝閿佸湪銆屽崟涓€峈edis 瀹炰緥涓彲鑳戒骇鐢熺殑闂锛屽苟娌℃湁娑夊強鍒?Redis 鐨勯儴缃叉灦鏋勭粏鑺傘€?/p>

鑰屾垜浠湪浣跨敤 Redis 鏃讹紝涓€鑸細閲囩敤涓讳粠闆嗙兢 + 鍝ㄥ叺鐨勬ā寮忛儴缃诧紝杩欐牱鍋氱殑濂藉鍦ㄤ簬锛屽綋涓诲簱寮傚父瀹曟満鏃讹紝鍝ㄥ叺鍙互瀹炵幇銆屾晠闅滆嚜鍔ㄥ垏鎹€嶏紝鎶婁粠搴撴彁鍗囦负涓诲簱锛岀户缁彁渚涙湇鍔★紝浠ユ淇濊瘉鍙敤鎬с€?/p>

閭e綋銆屼富浠庡彂鐢熷垏鎹€嶆椂锛岃繖涓垎甯冮攣浼氫緷鏃у畨鍏ㄥ悧锛?/strong>

璇曟兂杩欐牱鐨勫満鏅細

  1. 瀹㈡埛绔?1 鍦ㄤ富搴撲笂鎵ц SET 鍛戒护锛屽姞閿佹垚鍔?/li>
  2. 姝ゆ椂锛屼富搴撳紓甯稿畷鏈猴紝SET 鍛戒护杩樻湭鍚屾鍒颁粠搴撲笂锛堜富浠庡鍒舵槸寮傛鐨勶級
  3. 浠庡簱琚摠鍏垫彁鍗囦负鏂颁富搴擄紝杩欎釜閿佸湪鏂扮殑涓诲簱涓婏紝涓㈠け浜嗭紒
Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第18张

鍙锛屽綋寮曞叆 Redis 鍓湰鍚庯紝鍒嗗竷閿佽繕鏄彲鑳戒細鍙楀埌褰卞搷銆?/p>

鎬庝箞瑙e喅杩欎釜闂锛?/p>

Redlock锛堢孩閿侊級

涓烘锛孯edis 鐨勪綔鑰?Antirez 鎻愬嚭涓€绉嶈В鍐虫柟妗堬紝灏辨槸鎴戜滑缁忓父鍚埌鐨?Redlock锛堢孩閿侊級銆?/p>

瀹冪湡鐨勫彲浠ヨВ鍐充笂闈㈣繖涓棶棰樺悧锛?/p>

Redlock 鐪熺殑瀹夊叏鍚楋紵

濂斤紝缁堜簬鍒颁簡杩欑瘒鏂囩珷鐨勯噸澶存垙銆傚晩锛熶笂闈㈣鐨勯偅涔堝闂锛岄毦閬撳彧鏄熀纭€锛?/p>

鏄殑锛岄偅浜涘彧鏄紑鑳冭彍锛岀湡姝g殑纭彍锛屼粠杩欓噷鍒氬垰寮€濮嬨€?/p>

濡傛灉涓婇潰璁茬殑鍐呭锛屼綘杩樻病鏈夌悊瑙o紝鎴戝缓璁綘閲嶆柊闃呰涓€閬嶏紝鍏堢悊娓呮暣涓姞閿併€佽В閿佺殑鍩烘湰娴佺▼銆?/p>

濡傛灉浣犲凡缁忓 Redlock 鏈夋墍浜嗚В锛岃繖閲屽彲浠ヨ窡鐫€鎴戝啀澶嶄範涓€閬嶏紝濡傛灉浣犱笉浜嗚В Redlock锛屾病鍏崇郴锛屾垜浼氬甫浣犻噸鏂拌璇嗗畠銆?/p>

鍊煎緱鎻愰啋浣犵殑鏄紝鍚庨潰鎴戜笉浠呬粎鏄 Redlock 鐨勫師鐞嗭紝杩樹細寮曞嚭鏈夊叧銆屽垎甯冨紡绯荤粺銆嶄腑鐨勫緢澶氶棶棰橈紝浣犳渶濂借窡绱ф垜鐨勬€濊矾锛屽湪鑴戜腑涓€璧峰垎鏋愰棶棰樼殑绛旀銆?/strong>

鐜板湪鎴戜滑鏉ョ湅锛孉ntirez 鎻愬嚭鐨?Redlock 鏂规锛屾槸濡備綍瑙e喅涓讳粠鍒囨崲鍚庯紝閿佸け鏁堥棶棰樼殑銆?/p>

Redlock 鐨勬柟妗堝熀浜?2 涓墠鎻愶細

  1. 涓嶅啀闇€瑕侀儴缃?strong>浠庡簱鍜?strong>鍝ㄥ叺瀹炰緥锛屽彧閮ㄧ讲涓诲簱
  2. 浣嗕富搴撹閮ㄧ讲澶氫釜锛屽畼鏂规帹鑽愯嚦灏?5 涓疄渚?/li>

涔熷氨鏄锛屾兂鐢ㄤ娇鐢?Redlock锛屼綘鑷冲皯瑕侀儴缃?5 涓?Redis 瀹炰緥锛岃€屼笖閮芥槸涓诲簱锛屽畠浠箣闂存病鏈変换浣曞叧绯伙紝閮芥槸涓€涓釜瀛ょ珛鐨勫疄渚嬨€?/p>

娉ㄦ剰锛氫笉鏄儴缃?Redis Cluster锛屽氨鏄儴缃?5 涓畝鍗曠殑 Redis 瀹炰緥銆?/strong>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第19张

Redlock 鍏蜂綋濡備綍浣跨敤鍛紵

鏁翠綋鐨勬祦绋嬫槸杩欐牱鐨勶紝涓€鍏卞垎涓?5 姝ワ細

  1. 瀹㈡埛绔厛鑾峰彇銆屽綋鍓嶆椂闂存埑T1銆?/li>
  2. 瀹㈡埛绔緷娆″悜杩?5 涓?Redis 瀹炰緥鍙戣捣鍔犻攣璇锋眰锛堢敤鍓嶉潰璁插埌鐨?SET 鍛戒护锛夛紝涓旀瘡涓姹備細璁剧疆瓒呮椂鏃堕棿锛堟绉掔骇锛岃杩滃皬浜庨攣鐨勬湁鏁堟椂闂达級锛屽鏋滄煇涓€涓疄渚嬪姞閿佸け璐ワ紙鍖呮嫭缃戠粶瓒呮椂銆侀攣琚叾瀹冧汉鎸佹湁绛夊悇绉嶅紓甯告儏鍐碉級锛屽氨绔嬪嵆鍚戜笅涓€涓?Redis 瀹炰緥鐢宠鍔犻攣
  3. 濡傛灉瀹㈡埛绔粠 >=3 涓紙澶у鏁帮級浠ヤ笂 Redis 瀹炰緥鍔犻攣鎴愬姛锛屽垯鍐嶆鑾峰彇銆屽綋鍓嶆椂闂存埑T2銆嶏紝濡傛灉 T2 - T1 < 閿佺殑杩囨湡鏃堕棿锛屾鏃讹紝璁や负瀹㈡埛绔姞閿佹垚鍔燂紝鍚﹀垯璁や负鍔犻攣澶辫触
  4. 鍔犻攣鎴愬姛锛屽幓鎿嶄綔鍏变韩璧勬簮锛堜緥濡備慨鏀?MySQL 鏌愪竴琛岋紝鎴栧彂璧蜂竴涓?API 璇锋眰锛?/li>
  5. 鍔犻攣澶辫触锛屽悜銆屽叏閮ㄨ妭鐐广€嶅彂璧烽噴鏀鹃攣璇锋眰锛堝墠闈㈣鍒扮殑 Lua 鑴氭湰閲婃斁閿侊級

鎴戠畝鍗曞府浣犳€荤粨涓€涓嬶紝鏈?4 涓噸鐐癸細

  1. 瀹㈡埛绔湪澶氫釜 Redis 瀹炰緥涓婄敵璇峰姞閿?/li>
  2. 蹇呴』淇濊瘉澶у鏁拌妭鐐瑰姞閿佹垚鍔?/li>
  3. 澶у鏁拌妭鐐瑰姞閿佺殑鎬昏€楁椂锛岃灏忎簬閿佽缃殑杩囨湡鏃堕棿
  4. 閲婃斁閿侊紝瑕佸悜鍏ㄩ儴鑺傜偣鍙戣捣閲婃斁閿佽姹?/li>

绗竴娆$湅鍙兘涓嶅お瀹规槗鐞嗚В锛屽缓璁綘鎶婁笂闈㈢殑鏂囧瓧澶氱湅鍑犻亶锛屽姞娣辫蹇嗐€?/p>

鐒跺悗锛岃浣忚繖 5 姝ワ紝闈炲父閲嶈锛屼笅闈細鏍规嵁杩欎釜娴佺▼锛屽墫鏋愬悇绉嶅彲鑳藉鑷撮攣澶辨晥鐨勯棶棰樺亣璁俱€?/p>

濂斤紝鏄庣櫧浜?Redlock 鐨勬祦绋嬶紝鎴戜滑鏉ョ湅 Redlock 涓轰粈涔堣杩欎箞鍋氥€?/p>

1) 涓轰粈涔堣鍦ㄥ涓疄渚嬩笂鍔犻攣锛?/strong>

鏈川涓婃槸涓轰簡銆屽閿欍€嶏紝閮ㄥ垎瀹炰緥寮傚父瀹曟満锛屽墿浣欑殑瀹炰緥鍔犻攣鎴愬姛锛屾暣涓攣鏈嶅姟渚濇棫鍙敤銆?/p>

2) 涓轰粈涔堝ぇ澶氭暟鍔犻攣鎴愬姛锛屾墠绠楁垚鍔燂紵

澶氫釜 Redis 瀹炰緥涓€璧锋潵鐢紝鍏跺疄灏辩粍鎴愪簡涓€涓€屽垎甯冨紡绯荤粺銆嶃€?/p>

鍦ㄥ垎甯冨紡绯荤粺涓紝鎬讳細鍑虹幇銆屽紓甯歌妭鐐广€嶏紝鎵€浠ワ紝鍦ㄨ皥璁哄垎甯冨紡绯荤粺闂鏃讹紝闇€瑕佽€冭檻寮傚父鑺傜偣杈惧埌澶氬皯涓紝涔熶緷鏃т笉浼氬奖鍝嶆暣涓郴缁熺殑銆屾纭€с€嶃€?/p>

杩欐槸涓€涓垎甯冨紡绯荤粺銆屽閿欍€嶉棶棰橈紝杩欎釜闂鐨勭粨璁烘槸锛?strong>濡傛灉鍙瓨鍦ㄣ€屾晠闅溿€嶈妭鐐癸紝鍙澶у鏁拌妭鐐规甯革紝閭d箞鏁翠釜绯荤粺渚濇棫鏄彲浠ユ彁渚涙纭湇鍔$殑銆?/strong>

杩欎釜闂鐨勬ā鍨嬶紝灏辨槸鎴戜滑缁忓父鍚埌鐨勩€屾嫓鍗犲涵灏嗗啗銆嶉棶棰橈紝鎰熷叴瓒e彲浠ュ幓鐪嬬畻娉曠殑鎺ㄦ紨杩囩▼銆?/p>

3) 涓轰粈涔堟楠?3 鍔犻攣鎴愬姛鍚庯紝杩樿璁$畻鍔犻攣鐨勭疮璁¤€楁椂锛?/strong>

鍥犱负鎿嶄綔鐨勬槸澶氫釜鑺傜偣锛屾墍浠ヨ€楁椂鑲畾浼氭瘮鎿嶄綔鍗曚釜瀹炰緥鑰楁椂鏇翠箙锛岃€屼笖锛屽洜涓烘槸缃戠粶璇锋眰锛岀綉缁滄儏鍐垫槸澶嶆潅鐨勶紝鏈夊彲鑳藉瓨鍦?strong>寤惰繜銆佷涪鍖呫€佽秴鏃?/strong>绛夋儏鍐靛彂鐢燂紝缃戠粶璇锋眰瓒婂锛屽紓甯稿彂鐢熺殑姒傜巼灏辫秺澶с€?/p>

鎵€浠ワ紝鍗充娇澶у鏁拌妭鐐瑰姞閿佹垚鍔燂紝浣嗗鏋滃姞閿佺殑绱鑰楁椂宸茬粡銆岃秴杩囥€嶄簡閿佺殑杩囨湡鏃堕棿锛岄偅姝ゆ椂鏈変簺瀹炰緥涓婄殑閿佸彲鑳藉凡缁忓け鏁堜簡锛岃繖涓攣灏辨病鏈夋剰涔変簡銆?/p>

4) 涓轰粈涔堥噴鏀鹃攣锛岃鎿嶄綔鎵€鏈夎妭鐐癸紵

鍦ㄦ煇涓€涓?Redis 鑺傜偣鍔犻攣鏃讹紝鍙兘鍥犱负銆岀綉缁滃師鍥犮€嶅鑷村姞閿佸け璐ャ€?/p>

渚嬪锛屽鎴风鍦ㄤ竴涓?Redis 瀹炰緥涓婂姞閿佹垚鍔燂紝浣嗗湪璇诲彇鍝嶅簲缁撴灉鏃讹紝缃戠粶闂瀵艰嚧璇诲彇澶辫触锛岄偅杩欐妸閿佸叾瀹炲凡缁忓湪 Redis 涓婂姞閿佹垚鍔熶簡銆?/p>

鎵€浠ワ紝閲婃斁閿佹椂锛屼笉绠′箣鍓嶆湁娌℃湁鍔犻攣鎴愬姛锛岄渶瑕侀噴鏀俱€屾墍鏈夎妭鐐广€嶇殑閿侊紝浠ヤ繚璇佹竻鐞嗚妭鐐逛笂銆屾畫鐣欍€嶇殑閿併€?/p>

濂戒簡锛屾槑鐧戒簡 Redlock 鐨勬祦绋嬪拰鐩稿叧闂锛岀湅浼?Redlock 纭疄瑙e喅浜?Redis 鑺傜偣寮傚父瀹曟満閿佸け鏁堢殑闂锛屼繚璇佷簡閿佺殑銆屽畨鍏ㄦ€с€嶃€?/p>

浣嗕簨瀹炵湡鐨勫姝ゅ悧锛?/p>

Redlock 鐨勪簤璁鸿皝瀵硅皝閿欙紵

Redis 浣滆€呮妸杩欎釜鏂规涓€缁忔彁鍑猴紝灏遍┈涓婂彈鍒颁笟鐣岃憲鍚嶇殑鍒嗗竷寮忕郴缁熶笓瀹剁殑璐ㄧ枒锛?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第20张

杩欎釜涓撳鍙?Martin锛屾槸鑻卞浗鍓戞ˉ澶у鐨勪竴鍚嶅垎甯冨紡绯荤粺鐮旂┒鍛樸€傚湪姝や箣鍓嶄粬鏇炬槸杞欢宸ョ▼甯堝拰浼佷笟瀹讹紝浠庝簨澶ц妯℃暟鎹熀纭€璁炬柦鐩稿叧鐨勫伐浣溿€傚畠杩樼粡甯稿湪澶т細鍋氭紨璁诧紝鍐欏崥瀹紝鍐欎功锛屼篃鏄紑婧愯础鐚€呫€?/p>

浠栭┈涓婂啓浜嗙瘒鏂囩珷锛岃川鐤戣繖涓?Redlock 鐨勭畻娉曟ā鍨嬫槸鏈夐棶棰樼殑锛屽苟瀵瑰垎甯冨紡閿佺殑璁捐锛屾彁鍑轰簡鑷繁鐨勭湅娉曘€?/p>

涔嬪悗锛孯edis 浣滆€?Antirez 闈㈠璐ㄧ枒锛屼笉鐢樼ず寮憋紝涔熷啓浜嗕竴绡囨枃绔狅紝鍙嶉┏浜嗗鏂圭殑瑙傜偣锛屽苟璇︾粏鍓栨瀽浜?Redlock 绠楁硶妯″瀷鐨勬洿澶氳璁$粏鑺傘€?/p>

鑰屼笖锛屽叧浜庤繖涓棶棰樼殑浜夎锛屽湪褰撴椂浜掕仈缃戜笂涔熷紩璧蜂簡闈炲父婵€鐑堢殑璁ㄨ銆?/p>

浜屼汉鎬濊矾娓呮櫚锛岃鎹厖鍒嗭紝杩欐槸涓€鍦洪珮鎵嬭繃鎷涳紝涔熸槸鍒嗗竷寮忕郴缁熼鍩熼潪甯稿ソ鐨勪竴娆℃€濇兂鐨勭鎾烇紒鍙屾柟閮芥槸鍒嗗竷寮忕郴缁熼鍩熺殑涓撳锛屽嵈瀵瑰悓涓€涓棶棰樻彁鍑哄緢澶氱浉鍙嶇殑璁烘柇锛岀┒绔熸槸鎬庝箞鍥炰簨锛?/strong>

涓嬮潰鎴戜細浠庝粬浠殑浜夎鏂囩珷涓紝鎻愬彇閲嶈鐨勮鐐癸紝鏁寸悊鍛堢幇缁欎綘銆?/p>

鎻愰啋锛氬悗闈㈢殑淇℃伅閲忔瀬澶э紝鍙兘涓嶅疁鐞嗚В锛屾渶濂芥斁鎱㈤€熷害闃呰銆?/p>

鍒嗗竷寮忎笓瀹?Martin 瀵逛簬 Relock 鐨勮川鐤?/h2>

鍦ㄤ粬鐨勬枃绔犱腑锛屼富瑕侀槓杩颁簡 4 涓鐐癸細

1) 鍒嗗竷寮忛攣鐨勭洰鐨勬槸浠€涔堬紵

Martin 琛ㄧず锛屼綘蹇呴』鍏堟竻妤氫綘鍦ㄤ娇鐢ㄥ垎甯冨紡閿佺殑鐩殑鏄粈涔堬紵

浠栬涓烘湁涓や釜鐩殑銆?/p>

绗竴锛屾晥鐜囥€?/strong>

浣跨敤鍒嗗竷寮忛攣鐨勪簰鏂ヨ兘鍔涳紝鏄伩鍏嶄笉蹇呰鍦板仛鍚屾牱鐨勪袱娆″伐浣滐紙渚嬪涓€浜涙槀璐电殑璁$畻浠诲姟锛夈€傚鏋滈攣澶辨晥锛屽苟涓嶄細甯︽潵銆屾伓鎬с€嶇殑鍚庢灉锛屼緥濡傚彂浜?2 娆¢偖浠剁瓑锛屾棤浼ゅぇ闆呫€?/p>

绗簩锛屾纭€с€?/strong>

浣跨敤閿佺敤鏉ラ槻姝㈠苟鍙戣繘绋嬩簰鐩稿共鎵般€傚鏋滈攣澶辨晥锛屼細閫犳垚澶氫釜杩涚▼鍚屾椂鎿嶄綔鍚屼竴鏉℃暟鎹紝浜х敓鐨勫悗鏋滄槸鏁版嵁涓ラ噸閿欒銆佹案涔呮€т笉涓€鑷淬€佹暟鎹涪澶?/strong>绛夋伓鎬ч棶棰橈紝灏卞儚缁欐偅鑰呮湇鐢ㄩ噸澶嶅墏閲忕殑鑽墿涓€鏍凤紝鍚庢灉涓ラ噸銆?/p>

浠栬涓猴紝濡傛灉浣犳槸涓轰簡鍓嶈€呪€斺€旀晥鐜囷紝閭d箞浣跨敤鍗曟満鐗?Redis 灏卞彲浠ヤ簡锛屽嵆浣垮伓灏斿彂鐢熼攣澶辨晥锛堝畷鏈恒€佷富浠庡垏鎹級锛岄兘涓嶄細浜х敓涓ラ噸鐨勫悗鏋溿€傝€屼娇鐢?Redlock 澶噸浜嗭紝娌″繀瑕併€?/p>

鑰屽鏋滄槸涓轰簡姝g‘鎬э紝Martin 璁や负 Redlock 鏍规湰杈句笉鍒板畨鍏ㄦ€х殑瑕佹眰锛屼篃渚濇棫瀛樺湪閿佸け鏁堢殑闂锛?/strong>

2) 閿佸湪鍒嗗竷寮忕郴缁熶腑浼氶亣鍒扮殑闂

Martin 琛ㄧず锛屼竴涓垎甯冨紡绯荤粺锛屾洿鍍忎竴涓鏉傜殑銆岄噹鍏姐€嶏紝瀛樺湪鐫€浣犳兂涓嶅埌鐨勫悇绉嶅紓甯告儏鍐点€?/p>

杩欎簺寮傚父鍦烘櫙涓昏鍖呮嫭涓夊ぇ鍧楋紝杩欎篃鏄垎甯冨紡绯荤粺浼氶亣鍒扮殑涓夊骇澶у北锛?strong>NPC銆?/p>

  • N锛歂etwork Delay锛岀綉缁滃欢杩?/li>
  • P锛歅rocess Pause锛岃繘绋嬫殏鍋滐紙GC锛?/li>
  • C锛欳lock Drift锛屾椂閽熸紓绉?/li>

Martin 鐢ㄤ竴涓繘绋嬫殏鍋滐紙GC锛夌殑渚嬪瓙锛屾寚鍑轰簡 Redlock 瀹夊叏鎬ч棶棰橈細

  1. 瀹㈡埛绔?1 璇锋眰閿佸畾鑺傜偣 A銆丅銆丆銆丏銆丒
  2. 瀹㈡埛绔?1 鐨勬嬁鍒伴攣鍚庯紝杩涘叆 GC锛堟椂闂存瘮杈冧箙锛?/li>
  3. 鎵€鏈?Redis 鑺傜偣涓婄殑閿侀兘杩囨湡浜?/li>
  4. 瀹㈡埛绔?2 鑾峰彇鍒颁簡 A銆丅銆丆銆丏銆丒 涓婄殑閿?/li>
  5. 瀹㈡埛绔?1 GC 缁撴潫锛岃涓烘垚鍔熻幏鍙栭攣
  6. 瀹㈡埛绔?2 涔熻涓鸿幏鍙栧埌浜嗛攣锛屽彂鐢熴€屽啿绐併€?/li>
Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第21张

Martin 璁や负锛孏C 鍙兘鍙戠敓鍦ㄧ▼搴忕殑浠绘剰鏃跺埢锛岃€屼笖鎵ц鏃堕棿鏄笉鍙帶鐨勩€?/p>

娉細褰撶劧锛屽嵆浣挎槸浣跨敤娌℃湁 GC 鐨勭紪绋嬭瑷€锛屽湪鍙戠敓缃戠粶寤惰繜銆佹椂閽熸紓绉绘椂锛屼篃閮芥湁鍙兘瀵艰嚧 Redlock 鍑虹幇闂锛岃繖閲?Martin 鍙槸鎷?GC 涓句緥銆?/p>

3) 鍋囪鏃堕挓姝g‘鐨勬槸涓嶅悎鐞嗙殑

鍙堟垨鑰咃紝褰撳涓?Redis 鑺傜偣銆屾椂閽熴€嶅彂鐢熼棶棰樻椂锛屼篃浼氬鑷?Redlock 閿佸け鏁?/strong>銆?/p>

  1. 瀹㈡埛绔?1 鑾峰彇鑺傜偣 A銆丅銆丆 涓婄殑閿侊紝浣嗙敱浜庣綉缁滈棶棰橈紝鏃犳硶璁块棶 D 鍜?E
  2. 鑺傜偣 C 涓婄殑鏃堕挓銆屽悜鍓嶈烦璺冦€嶏紝瀵艰嚧閿佸埌鏈?/li>
  3. 瀹㈡埛绔?2 鑾峰彇鑺傜偣 C銆丏銆丒 涓婄殑閿侊紝鐢变簬缃戠粶闂锛屾棤娉曡闂?A 鍜?B
  4. 瀹㈡埛绔?1 鍜?2 鐜板湪閮界浉淇″畠浠寔鏈変簡閿侊紙鍐茬獊锛?/li>

Martin 瑙夊緱锛孯edlock 蹇呴』銆屽己渚濊禆銆嶅涓妭鐐圭殑鏃堕挓鏄繚鎸佸悓姝ョ殑锛屼竴鏃︽湁鑺傜偣鏃堕挓鍙戠敓閿欒锛岄偅杩欎釜绠楁硶妯″瀷灏卞け鏁堜簡銆?/p>

鍗充娇 C 涓嶆槸鏃堕挓璺宠穬锛岃€屾槸銆屽穿婧冨悗绔嬪嵆閲嶅惎銆嶏紝涔熶細鍙戠敓绫讳技鐨勯棶棰樸€?/p>

Martin 缁х画闃愯堪锛屾満鍣ㄧ殑鏃堕挓鍙戠敓閿欒锛屾槸寰堟湁鍙兘鍙戠敓鐨勶細

  • 绯荤粺绠$悊鍛樸€屾墜鍔ㄤ慨鏀广€嶄簡鏈哄櫒鏃堕挓
  • 鏈哄櫒鏃堕挓鍦ㄥ悓姝?NTP 鏃堕棿鏃讹紝鍙戠敓浜嗗ぇ鐨勩€岃烦璺冦€?/li>

鎬讳箣锛孧artin 璁や负锛孯edlock 鐨勭畻娉曟槸寤虹珛鍦ㄣ€屽悓姝ユā鍨嬨€嶅熀纭€涓婄殑锛屾湁澶ч噺璧勬枡鐮旂┒琛ㄦ槑锛屽悓姝ユā鍨嬬殑鍋囪锛屽湪鍒嗗竷寮忕郴缁熶腑鏄湁闂鐨勩€?/p>

鍦ㄦ贩涔辩殑鍒嗗竷寮忕郴缁熺殑涓紝浣犱笉鑳藉亣璁剧郴缁熸椂閽熷氨鏄鐨勶紝鎵€浠ワ紝浣犲繀椤婚潪甯稿皬蹇冧綘鐨勫亣璁俱€?/p>

4) 鎻愬嚭 fencing token 鐨勬柟妗堬紝淇濊瘉姝g‘鎬?/strong>

Token 鏄竾鑳界殑

鐩稿搴旂殑锛孧artin 鎻愬嚭涓€绉嶈鍙綔 fencing token 鐨勬柟妗堬紝淇濊瘉鍒嗗竷寮忛攣鐨勬纭€с€?/p>

杩欎釜妯″瀷娴佺▼濡備笅锛?/p>

  1. 瀹㈡埛绔湪鑾峰彇閿佹椂锛岄攣鏈嶅姟鍙互鎻愪緵涓€涓€岄€掑銆嶇殑 token
  2. 瀹㈡埛绔嬁鐫€杩欎釜 token 鍘绘搷浣滃叡浜祫婧?/li>
  3. 鍏变韩璧勬簮鍙互鏍规嵁 token 鎷掔粷銆屽悗鏉ヨ€呫€嶇殑璇锋眰
Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第22张

杩欐牱涓€鏉ワ紝鏃犺 NPC 鍝寮傚父鎯呭喌鍙戠敓锛岄兘鍙互淇濊瘉鍒嗗竷寮忛攣鐨勫畨鍏ㄦ€э紝鍥犱负瀹冩槸寤虹珛鍦ㄣ€屽紓姝ユā鍨嬨€嶄笂鐨勩€?/p>

鑰?Redlock 鏃犳硶鎻愪緵绫讳技 fencing token 鐨勬柟妗堬紝鎵€浠ュ畠鏃犳硶淇濊瘉瀹夊叏鎬с€?/p>

浠栬繕琛ㄧず锛?strong>涓€涓ソ鐨勫垎甯冨紡閿侊紝鏃犺 NPC 鎬庝箞鍙戠敓锛屽彲浠ヤ笉鍦ㄨ瀹氭椂闂村唴缁欏嚭缁撴灉锛屼絾骞朵笉浼氱粰鍑轰竴涓敊璇殑缁撴灉銆備篃灏辨槸鍙細褰卞搷鍒伴攣鐨勩€屾€ц兘銆嶏紙鎴栫О涔嬩负娲绘€э級锛岃€屼笉浼氬奖鍝嶅畠鐨勩€屾纭€с€嶃€?/strong>

Martin 鐨勭粨璁猴細

1銆丷edlock 涓嶄鸡涓嶇被锛氬畠瀵逛簬鏁堢巼鏉ヨ锛孯edlock 姣旇緝閲嶏紝娌″繀瑕佽繖涔堝仛锛岃€屽浜庢纭€ф潵璇达紝Redlock 鏄笉澶熷畨鍏ㄧ殑銆?/p>

2銆佹椂閽熷亣璁句笉鍚堢悊锛氳绠楁硶瀵圭郴缁熸椂閽熷仛鍑轰簡鍗遍櫓鐨勫亣璁撅紙鍋囪澶氫釜鑺傜偣鏈哄櫒鏃堕挓閮芥槸涓€鑷寸殑锛夛紝濡傛灉涓嶆弧瓒宠繖浜涘亣璁撅紝閿佸氨浼氬け鏁堛€?/p>

3銆佹棤娉曚繚璇佹纭€?/strong>锛歊edlock 涓嶈兘鎻愪緵绫讳技 fencing token 鐨勬柟妗堬紝鎵€浠ヨВ鍐充笉浜嗘纭€х殑闂銆備负浜嗘纭€э紝璇蜂娇鐢ㄦ湁銆屽叡璇嗙郴缁熴€嶇殑杞欢锛屼緥濡?Zookeeper銆?/p>

濂戒簡锛屼互涓婂氨鏄?Martin 鍙嶅浣跨敤 Redlock 鐨勮鐐癸紝鐪嬭捣鏉ユ湁鐞嗘湁鎹€?/p>

涓嬮潰鎴戜滑鏉ョ湅 Redis 浣滆€?Antirez 鏄浣曞弽椹崇殑銆?/p>

Redis 浣滆€?Antirez 鐨勫弽椹?/h2>

鍦?Redis 浣滆€呯殑鏂囩珷涓紝閲嶇偣鏈?3 涓細

1) 瑙i噴鏃堕挓闂

棣栧厛锛孉ntirez 涓€鐪煎氨鐪嬬┛浜嗗鏂规彁鍑虹殑鏈€涓烘牳蹇冪殑闂锛?strong>鏃堕挓闂銆?/p>

Antirez 琛ㄧず锛孯edlock 骞朵笉闇€瑕佸畬鍏ㄤ竴鑷寸殑鏃堕挓锛屽彧闇€瑕佸ぇ浣撲竴鑷村氨鍙互浜嗭紝鍏佽鏈夈€岃宸€嶃€?/p>

渚嬪瑕佽鏃?5s锛屼絾瀹為檯鍙兘璁颁簡 4.5s锛屼箣鍚庡張璁颁簡 5.5s锛屾湁涓€瀹氳宸紝浣嗗彧瑕佷笉瓒呰繃銆岃宸寖鍥淬€嶉攣澶辨晥鏃堕棿鍗冲彲锛岃繖绉嶅浜庢椂閽熺殑绮惧害鐨勮姹傚苟涓嶆槸寰堥珮锛岃€屼笖杩欎篃绗﹀悎鐜板疄鐜銆?/p>

瀵逛簬瀵规柟鎻愬埌鐨勩€屾椂閽熶慨鏀广€嶉棶棰橈紝Redis 浣滆€呭弽椹冲埌锛?/p>

  1. 鎵嬪姩淇敼鏃堕挓锛氫笉瑕佽繖涔堝仛灏卞ソ浜嗭紝鍚﹀垯浣犵洿鎺ヤ慨鏀?Raft 鏃ュ織锛岄偅 Raft 涔熶細鏃犳硶宸ヤ綔鈥?/li>
  2. 鏃堕挓璺宠穬锛氶€氳繃銆屾伆褰撶殑杩愮淮銆嶏紝淇濊瘉鏈哄櫒鏃堕挓涓嶄細澶у箙搴﹁烦璺冿紙姣忔閫氳繃寰皬鐨勮皟鏁存潵瀹屾垚锛夛紝瀹為檯涓婅繖鏄彲浠ュ仛鍒扮殑

涓轰粈涔?Antirez 浼樺厛瑙i噴鏃堕挓闂锛熷洜涓哄湪鍚庨潰鐨勫弽椹宠繃绋嬩腑锛岄渶瑕佷緷璧栬繖涓熀纭€鍋氳繘涓€姝ヨВ閲娿€?/p>

2) 瑙i噴缃戠粶寤惰繜銆丟C 闂

涔嬪悗锛孉ntirez 瀵逛簬瀵规柟鎻愬嚭鐨勶紝缃戠粶寤惰繜wan銆佽繘绋?GC 鍙兘瀵艰嚧 Redlock 澶辨晥鐨勯棶棰橈紝涔熷仛浜嗗弽椹筹細

鎴戜滑閲嶆柊鍥為【涓€涓嬶紝Martin 鎻愬嚭鐨勯棶棰樺亣璁撅細

  1. 瀹㈡埛绔?1 璇锋眰閿佸畾鑺傜偣 A銆丅銆丆銆丏銆丒
  2. 瀹㈡埛绔?1 鐨勬嬁鍒伴攣鍚庯紝杩涘叆 GC
  3. 鎵€鏈?Redis 鑺傜偣涓婄殑閿侀兘杩囨湡浜?/li>
  4. 瀹㈡埛绔?2 鑾峰彇鑺傜偣 A銆丅銆丆銆丏銆丒 涓婄殑閿?/li>
  5. 瀹㈡埛绔?1 GC 缁撴潫锛岃涓烘垚鍔熻幏鍙栭攣
  6. 瀹㈡埛绔?2 涔熻涓鸿幏鍙栧埌閿侊紝鍙戠敓銆屽啿绐併€?/li>
Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第23张

Redis 浣滆€呭弽椹冲埌锛岃繖涓亣璁惧叾瀹炴槸鏈夐棶棰樼殑锛孯edlock 鏄彲浠ヤ繚璇侀攣瀹夊叏鐨勩€?/p>

杩欐槸鎬庝箞鍥炰簨鍛紵

杩樿寰楀墠闈粙缁?Redlock 娴佺▼鐨勯偅 5 姝ュ悧锛熻繖閲屾垜鍐嶆嬁杩囨潵璁╀綘澶嶄範涓€涓嬨€?/p>

  1. 瀹㈡埛绔厛鑾峰彇銆屽綋鍓嶆椂闂存埑T1銆?/li>
  2. 瀹㈡埛绔緷娆″悜杩?5 涓?Redis 瀹炰緥鍙戣捣鍔犻攣璇锋眰锛堢敤鍓嶉潰璁插埌鐨?SET 鍛戒护锛夛紝涓旀瘡涓姹備細璁剧疆瓒呮椂鏃堕棿锛堟绉掔骇锛岃杩滃皬浜庨攣鐨勬湁鏁堟椂闂达級锛屽鏋滄煇涓€涓疄渚嬪姞閿佸け璐ワ紙鍖呮嫭缃戠粶瓒呮椂銆侀攣琚叾瀹冧汉鎸佹湁绛夊悇绉嶅紓甯告儏鍐碉級锛屽氨绔嬪嵆鍚戜笅涓€涓?Redis 瀹炰緥鐢宠鍔犻攣
  3. 濡傛灉瀹㈡埛绔粠 3 涓紙澶у鏁帮級浠ヤ笂 Redis 瀹炰緥鍔犻攣鎴愬姛锛屽垯鍐嶆鑾峰彇銆屽綋鍓嶆椂闂存埑T2銆嶏紝濡傛灉 T2 - T1 < 閿佺殑杩囨湡鏃堕棿锛屾鏃讹紝璁や负瀹㈡埛绔姞閿佹垚鍔燂紝鍚﹀垯璁や负鍔犻攣澶辫触
  4. 鍔犻攣鎴愬姛锛屽幓鎿嶄綔鍏变韩璧勬簮锛堜緥濡備慨鏀?MySQL 鏌愪竴琛岋紝鎴栧彂璧蜂竴涓?API 璇锋眰锛?/li>
  5. 鍔犻攣澶辫触锛屽悜銆屽叏閮ㄨ妭鐐广€嶅彂璧烽噴鏀鹃攣璇锋眰锛堝墠闈㈣鍒扮殑 Lua 鑴氭湰閲婃斁閿侊級

娉ㄦ剰锛岄噸鐐规槸 1-3锛屽湪姝ラ 3锛屽姞閿佹垚鍔熷悗涓轰粈涔堣閲嶆柊鑾峰彇銆屽綋鍓嶆椂闂存埑T2銆嶏紵杩樼敤 T2 - T1 鐨勬椂闂达紝涓庨攣鐨勮繃鏈熸椂闂村仛姣旇緝锛?/strong>

Antirez 寮鸿皟锛氬鏋滃湪 1-3 鍙戠敓浜嗙綉缁滃欢杩熴€佽繘绋?GC 绛夎€楁椂闀跨殑寮傚父鎯呭喌锛岄偅鍦ㄧ 3 姝?T2 - T1锛屾槸鍙互妫€娴嬪嚭鏉ョ殑锛屽鏋滆秴鍑轰簡閿佽缃殑杩囨湡鏃堕棿锛岄偅杩欐椂灏辫涓哄姞閿佷細澶辫触锛屼箣鍚庨噴鏀炬墍鏈夎妭鐐圭殑閿佸氨濂戒簡锛?/p>

Antirez 缁х画璁鸿堪锛屽鏋滃鏂硅涓猴紝鍙戠敓缃戠粶寤惰繜銆佽繘绋?GC 鏄湪姝ラ 3 涔嬪悗锛屼篃灏辨槸瀹㈡埛绔‘璁ゆ嬁鍒颁簡閿侊紝鍘绘搷浣滃叡浜祫婧愮殑閫斾腑鍙戠敓浜嗛棶棰橈紝瀵艰嚧閿佸け鏁堬紝閭h繖涓嶆鏄?Redlock 鐨勯棶棰橈紝浠讳綍鍏跺畠閿佹湇鍔′緥濡?Zookeeper锛岄兘鏈夌被浼肩殑闂锛岃繖涓嶅湪璁ㄨ鑼冪暣鍐?/strong>銆?/p>

杩欓噷鎴戜妇涓緥瀛愯В閲婁竴涓嬭繖涓棶棰橈細

  1. 瀹㈡埛绔€氳繃 Redlock 鎴愬姛鑾峰彇鍒伴攣锛堥€氳繃浜嗗ぇ澶氭暟鑺傜偣鍔犻攣鎴愬姛銆佸姞閿佽€楁椂妫€鏌ラ€昏緫锛?/li>
  2. 瀹㈡埛绔紑濮嬫搷浣滃叡浜祫婧愶紝姝ゆ椂鍙戠敓缃戠粶寤惰繜銆佽繘绋?GC 绛夎€楁椂寰堥暱鐨勬儏鍐?/li>
  3. 姝ゆ椂锛岄攣杩囨湡鑷姩閲婃斁
  4. 瀹㈡埛绔紑濮嬫搷浣?MySQL锛堟鏃剁殑閿佸彲鑳戒細琚埆浜烘嬁鍒帮紝閿佸け鏁堬級

Antirez 杩欓噷鐨勭粨璁哄氨鏄細

  • 瀹㈡埛绔湪鎷垮埌閿佷箣鍓嶏紝鏃犺缁忓巻浠€涔堣€楁椂闀块棶棰橈紝Redlock 閮借兘澶熷湪绗?3 姝ユ娴嬪嚭鏉?/li>
  • 瀹㈡埛绔湪鎷垮埌閿佷箣鍚庯紝鍙戠敓 NPC锛岄偅 Redlock銆乑ookeeper 閮芥棤鑳戒负鍔?/li>

鎵€浠ワ紝Antirez 璁や负 Redlock 鍦ㄤ繚璇佹椂閽熸纭殑鍩虹涓婏紝鏄彲浠ヤ繚璇佹纭€х殑銆?/p>

3) 璐ㄧ枒 fencing token 鏈哄埗

Antirez 瀵逛簬瀵规柟鎻愬嚭鐨?fencing token 鏈哄埗锛屼篃鎻愬嚭浜嗚川鐤戯紝涓昏鍒嗕负 2 涓棶棰樸€?/p>

绗竴锛岃繖涓柟妗堝繀椤昏姹傝鎿嶄綔鐨勩€屽叡浜祫婧愭湇鍔″櫒銆嶆湁鎷掔粷銆屾棫 token銆嶇殑鑳藉姏銆?/p>

渚嬪锛岃鎿嶄綔 MySQL锛屼粠閿佹湇鍔℃嬁鍒颁竴涓€掑鏁板瓧鐨?token锛岀劧鍚庡鎴风瑕佸甫鐫€杩欎釜 token 鍘绘敼 MySQL 鐨勬煇涓€琛岋紝杩欏氨闇€瑕佸埄鐢?MySQL 鐨勩€屼簨鐗╅殧绂绘€с€嶆潵鍋氥€?/p>

// 涓や釜瀹㈡埛绔繀椤诲埄鐢ㄤ簨鐗╁拰闅旂鎬ц揪鍒扮洰鐨?
// 娉ㄦ剰 token 鐨勫垽鏂潯浠?
UPDATE table T SET val = $new_val, current_token = $token WHERE id = $id AND current_token < $token

浣嗗鏋滄搷浣滅殑涓嶆槸 MySQL 鍛紵渚嬪鍚戠鐩樹笂鍐欎竴涓枃浠讹紝鎴栧彂璧蜂竴涓?HTTP 璇锋眰锛岄偅杩欎釜鏂规灏辨棤鑳戒负鍔涗簡锛岃繖瀵硅鎿嶄綔鐨勮祫婧愭湇鍔″櫒锛屾彁鍑轰簡鏇撮珮鐨勮姹傘€?/p>

涔熷氨鏄锛屽ぇ閮ㄥ垎瑕佹搷浣滅殑璧勬簮鏈嶅姟鍣紝閮芥槸娌℃湁杩欑浜掓枼鑳藉姏鐨勩€?/p>

鍐嶈€咃紝鏃㈢劧璧勬簮鏈嶅姟鍣ㄩ兘鏈変簡銆屼簰鏂ャ€嶈兘鍔涳紝閭h繕瑕佸垎甯冨紡閿佸共浠€涔堬紵

鎵€浠ワ紝Antirez 璁や负杩欎釜鏂规鏄珯涓嶄綇鑴氱殑銆?/p>

绗簩锛岄€€涓€姝ヨ锛屽嵆浣?Redlock 娌℃湁鎻愪緵 fencing token 鐨勮兘鍔涳紝浣?Redlock 宸茬粡鎻愪緵浜嗛殢鏈哄€硷紙灏辨槸鍓嶉潰璁茬殑 UUID锛夛紝鍒╃敤杩欎釜闅忔満鍊硷紝涔熷彲浠ヨ揪鍒颁笌 fencing token 鍚屾牱鐨勬晥鏋溿€?/p>

濡備綍鍋氬憿锛?/p>

Antirez 鍙槸鎻愬埌浜嗗彲浠ュ畬鎴?fencing token 绫讳技鐨勫姛鑳斤紝浣嗗嵈娌℃湁灞曞紑鐩稿叧缁嗚妭锛屾牴鎹垜鏌ラ槄鐨勮祫鏂欙紝澶ф娴佺▼搴旇濡備笅锛屽鏈夐敊璇紝娆㈣繋浜ゆ祦~

  1. 瀹㈡埛绔娇鐢?Redlock 鎷垮埌閿?/li>
  2. 瀹㈡埛绔湪鎿嶄綔鍏变韩璧勬簮涔嬪墠锛屽厛鎶婅繖涓攣鐨?VALUE锛屽湪瑕佹搷浣滅殑鍏变韩璧勬簮涓婂仛鏍囪
  3. 瀹㈡埛绔鐞嗕笟鍔¢€昏緫锛屾渶鍚庯紝鍦ㄤ慨鏀瑰叡浜祫婧愭椂锛屽垽鏂繖涓爣璁版槸鍚︿笌涔嬪墠涓€鏍凤紝涓€鏍锋墠淇敼锛堢被浼?CAS 鐨勬€濊矾锛?/li>

杩樻槸浠?MySQL 涓轰緥锛屼妇涓緥瀛愬氨鏄繖鏍风殑锛?/p>

  1. 瀹㈡埛绔娇鐢?Redlock 鎷垮埌閿?/li>
  2. 瀹㈡埛绔淇敼 MySQL 琛ㄤ腑鐨勬煇涓€琛屾暟鎹箣鍓嶏紝鍏堟妸閿佺殑 VALUE 鏇存柊鍒拌繖涓€琛岀殑鏌愪釜瀛楁涓紙杩欓噷鍋囪涓?current_token 瀛楁)
  3. 瀹㈡埛绔鐞嗕笟鍔¢€昏緫
  4. 瀹㈡埛绔慨鏀?MySQL 鐨勮繖涓€琛屾暟鎹紝鎶?VALUE 褰撳仛 WHERE 鏉′欢锛屽啀淇敼
UPDATE table T SET val = $new_val WHERE id = $id AND current_token = $redlock_value

鍙锛岃繖绉嶆柟妗堜緷璧?MySQL 鐨勪簨鍔℃満鍒讹紝涔熻揪鍒板鏂规彁鍒扮殑 fencing token 涓€鏍风殑鏁堟灉銆?/p>

浣嗚繖閲岃繕鏈変釜灏忛棶棰橈紝鏄綉鍙嬪弬涓庨棶棰樿璁烘椂鎻愬嚭鐨勶細涓や釜瀹㈡埛绔€氳繃杩欑鏂规锛屽厛銆屾爣璁般€嶅啀銆屾鏌?淇敼銆嶅叡浜祫婧愶紝閭h繖涓や釜瀹㈡埛绔殑鎿嶄綔椤哄簭鏃犳硶淇濊瘉鍟婏紵

鑰岀敤 Martin 鎻愬埌鐨?fencing token锛屽洜涓鸿繖涓?token 鏄崟璋冮€掑鐨勬暟瀛楋紝璧勬簮鏈嶅姟鍣ㄥ彲浠ユ嫆缁濆皬鐨?token 璇锋眰锛屼繚璇佷簡鎿嶄綔鐨勩€岄『搴忔€с€嶏紒

Antirez 瀵逛簬杩欎釜闂鍋氫簡涓嶅悓鐨勮В閲婏紝鎴戣寰楀緢鏈夐亾鐞嗭紝浠栬В閲婇亾锛?strong>鍒嗗竷寮忛攣鐨勬湰璐紝鏄负浜嗐€屼簰鏂ャ€嶏紝鍙鑳戒繚璇佷袱涓鎴风鍦ㄥ苟鍙戞椂锛屼竴涓垚鍔燂紝涓€涓け璐ュ氨濂戒簡锛屼笉闇€瑕佸叧蹇冦€岄『搴忔€с€嶃€?/strong>

鍓嶉潰 Martin 鐨勮川鐤戜腑锛屼竴鐩村緢鍏冲績杩欎釜椤哄簭鎬ч棶棰橈紝浣?Redis 鐨勪綔鑰呯殑鐪嬫硶鍗翠笉鍚屻€?/p>

缁间笂锛孉ntirez 鐨勭粨璁猴細

1銆丄ntirez 鍚屾剰Martin 鍏充簬銆屾椂閽熻烦璺冦€嶅 Redlock 鐨勫奖鍝嶏紝浣嗚涓烘椂閽熻烦璺冩槸鍙互閬垮厤鐨勶紝鍙栧喅浜庡熀纭€璁炬柦鍜岃繍缁淬€?/strong>

2銆丷edlock 鍦ㄨ璁℃椂锛屽厖鍒嗚€冭檻浜?NPC 闂锛屽湪 Redlock 姝ラ 3 涔嬪墠鍑虹幇 NPC锛屽彲浠ヤ繚璇侀攣鐨勬纭€э紝浣嗗湪姝ラ 3 涔嬪悗鍙戠敓 NPC锛屼笉姝㈡槸 Redlock 鏈夐棶棰橈紝鍏跺畠鍒嗗竷寮忛攣鏈嶅姟鍚屾牱涔熸湁闂锛屾墍浠ヤ笉鍦ㄨ璁鸿寖鐣村唴銆?/strong>

鏄笉鏄寰楀緢鏈夋剰鎬濓紵

鍦ㄥ垎甯冨紡绯荤粺涓紝涓€涓皬灏忕殑閿侊紝灞呯劧鍙兘浼氶亣鍒拌繖涔堝闂鍦烘櫙锛屽奖鍝嶅畠鐨勫畨鍏ㄦ€э紒

涓嶇煡閬撲綘鐪嬪畬鍙屾柟鐨勮鐐癸紝鏇磋禐鍚屽摢涓€鏂圭殑璇存硶鍛紵

鍒€ワ紝鍚庨潰鎴戣繕浼氱患鍚堜互涓婅鐐癸紝璋堣皥鑷繁鐨勭悊瑙c€?/p>

濂斤紝璁插畬浜嗗弻鏂瑰浜?Redis 鍒嗗竷閿佺殑浜夎锛屼綘鍙兘涔熸敞鎰忓埌浜嗭紝Martin 鍦ㄤ粬鐨勬枃绔犱腑锛屾帹鑽愪娇鐢?Zookeeper 瀹炵幇鍒嗗竷寮忛攣锛岃涓哄畠鏇村畨鍏紝纭疄濡傛鍚楋紵

鍩轰簬 Zookeeper 鐨勯攣瀹夊叏鍚楋紵

濡傛灉浣犳湁浜嗚В杩?Zookeeper锛屽熀浜庡畠瀹炵幇鐨勫垎甯冨紡閿佹槸杩欐牱鐨勶細

  1. 瀹㈡埛绔?1 鍜?2 閮藉皾璇曞垱寤恒€屼复鏃惰妭鐐广€嶏紝渚嬪 /lock
  2. 鍋囪瀹㈡埛绔?1 鍏堝埌杈撅紝鍒欏姞閿佹垚鍔燂紝瀹㈡埛绔?2 鍔犻攣澶辫触
  3. 瀹㈡埛绔?1 鎿嶄綔鍏变韩璧勬簮
  4. 瀹㈡埛绔?1 鍒犻櫎 /lock 鑺傜偣锛岄噴鏀鹃攣

浣犲簲璇ヤ篃鐪嬪埌浜嗭紝Zookeeper 涓嶅儚 Redis 閭f牱锛岄渶瑕佽€冭檻閿佺殑杩囨湡鏃堕棿闂锛屽畠鏄噰鐢ㄤ簡銆屼复鏃惰妭鐐广€嶏紝淇濊瘉瀹㈡埛绔?1 鎷垮埌閿佸悗锛屽彧瑕佽繛鎺ヤ笉鏂紝灏卞彲浠ヤ竴鐩存寔鏈夐攣銆?/p>

鑰屼笖锛屽鏋滃鎴风 1 寮傚父宕╂簝浜嗭紝閭d箞杩欎釜涓存椂鑺傜偣浼氳嚜鍔ㄥ垹闄わ紝淇濊瘉浜嗛攣涓€瀹氫細琚噴鏀俱€?/p>

涓嶉敊锛屾病鏈夐攣杩囨湡鐨勭儲鎭硷紝杩樿兘鍦ㄥ紓甯告椂鑷姩閲婃斁閿侊紝鏄笉鏄寰楀緢瀹岀編锛?/strong>

鍏跺疄涓嶇劧銆?/p>

鎬濊€冧竴涓嬶紝瀹㈡埛绔?1 鍒涘缓涓存椂鑺傜偣鍚庯紝Zookeeper 鏄浣曚繚璇佽杩欎釜瀹㈡埛绔竴鐩存寔鏈夐攣鍛紵

鍘熷洜灏卞湪浜庯紝瀹㈡埛绔?1 姝ゆ椂浼氫笌 Zookeeper 鏈嶅姟鍣ㄧ淮鎶や竴涓?Session锛岃繖涓?Session 浼氫緷璧栧鎴风銆屽畾鏃跺績璺炽€嶆潵缁存寔杩炴帴銆?/strong>

濡傛灉 Zookeeper 闀挎椂闂存敹涓嶅埌瀹㈡埛绔殑蹇冭烦锛屽氨璁や负杩欎釜 Session 杩囨湡浜嗭紝涔熶細鎶婅繖涓复鏃惰妭鐐瑰垹闄ゃ€?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第24张

鍚屾牱鍦帮紝鍩轰簬姝ら棶棰橈紝鎴戜滑涔熻璁轰竴涓?GC 闂瀵?Zookeeper 鐨勯攣鏈変綍褰卞搷锛?/p>

  1. 瀹㈡埛绔?1 鍒涘缓涓存椂鑺傜偣 /lock 鎴愬姛锛屾嬁鍒颁簡閿?/li>
  2. 瀹㈡埛绔?1 鍙戠敓闀挎椂闂?GC
  3. 瀹㈡埛绔?1 鏃犳硶缁?Zookeeper 鍙戦€佸績璺筹紝Zookeeper 鎶婁复鏃惰妭鐐广€屽垹闄ゃ€?/li>
  4. 瀹㈡埛绔?2 鍒涘缓涓存椂鑺傜偣 /lock 鎴愬姛锛屾嬁鍒颁簡閿?/li>
  5. 瀹㈡埛绔?1 GC 缁撴潫锛屽畠浠嶇劧璁や负鑷繁鎸佹湁閿侊紙鍐茬獊锛?/li>

鍙锛屽嵆浣挎槸浣跨敤 Zookeeper锛屼篃鏃犳硶淇濊瘉杩涚▼ GC銆佺綉缁滃欢杩熷紓甯稿満鏅笅鐨勫畨鍏ㄦ€с€?/p>

杩欏氨鏄墠闈?Antirez 鍦ㄥ弽椹崇殑鏂囩珷涓彁鍒扮殑锛氬鏋滃鎴风宸茬粡鎷垮埌浜嗛攣锛屼絾瀹㈡埛绔笌閿佹湇鍔″櫒鍙戠敓銆屽け鑱斻€嶏紙渚嬪 GC锛夛紝閭d笉姝?Redlock 鏈夐棶棰橈紝鍏跺畠閿佹湇鍔¢兘鏈夌被浼肩殑闂锛孼ookeeper 涔熸槸涓€鏍凤紒

鎵€浠ワ紝杩欓噷鎴戜滑灏辫兘寰楀嚭缁撹浜嗭細涓€涓垎甯冨紡閿侊紝鍦ㄦ瀬绔儏鍐典笅锛屼笉涓€瀹氭槸瀹夊叏鐨勩€?/strong>

濡傛灉浣犵殑涓氬姟鏁版嵁闈炲父鏁忔劅锛屽湪浣跨敤鍒嗗竷寮忛攣鏃讹紝涓€瀹氳娉ㄦ剰杩欎釜闂锛屼笉鑳藉亣璁惧垎甯冨紡閿?100% 瀹夊叏銆?/p>

濂斤紝鐜板湪鎴戜滑鏉ユ€荤粨涓€涓?Zookeeper 鍦ㄤ娇鐢ㄥ垎甯冨紡閿佹椂浼樺姡锛?/p>

Zookeeper 鐨勪紭鐐癸細

  1. 涓嶉渶瑕佽€冭檻閿佺殑杩囨湡鏃堕棿
  2. watch 鏈哄埗锛屽姞閿佸け璐ワ紝鍙互 watch 绛夊緟閿侀噴鏀撅紝瀹炵幇涔愯閿?/li>

浣嗗畠鐨勫姡鍔挎槸锛?/p>

  1. 鎬ц兘涓嶅 Redis
  2. 閮ㄧ讲鍜岃繍缁存垚鏈珮
  3. 瀹㈡埛绔笌 Zookeeper 鐨勯暱鏃堕棿澶辫仈锛岄攣琚噴鏀鹃棶棰?/li>

鎴戝鍒嗗竷寮忛攣鐨勭悊瑙?/h2>

濂戒簡锛屽墠闈㈣缁嗕粙缁嶄簡鍩轰簬 Redis 鐨?Redlock 鍜?Zookeeper 瀹炵幇鐨勫垎甯冮攣锛屽湪鍚勭寮傚父鎯呭喌涓嬬殑瀹夊叏鎬ч棶棰橈紝涓嬮潰鎴戞兂鍜屼綘鑱婁竴鑱婃垜鐨勭湅娉曪紝浠呬緵鍙傝€冿紝涓嶅枩鍕垮柗銆?/p>

1) 鍒板簳瑕佷笉瑕佺敤 Redlock锛?/strong>

鍓嶉潰涔熷垎鏋愪簡锛孯edlock 鍙湁寤虹珛鍦ㄣ€屾椂閽熸纭€嶇殑鍓嶆彁涓嬶紝鎵嶈兘姝e父宸ヤ綔锛屽鏋滀綘鍙互淇濊瘉杩欎釜鍓嶆彁锛岄偅涔堝彲浠ユ嬁鏉ヤ娇鐢ㄣ€?/p>

浣嗕繚璇佹椂閽熸纭紝鎴戣涓哄苟涓嶆槸浣犳兂鐨勯偅涔堢畝鍗曞氨鑳藉仛鍒扮殑銆?/p>

绗竴锛屼粠纭欢瑙掑害鏉ヨ锛屾椂閽熷彂鐢熷亸绉绘槸鏃舵湁鍙戠敓锛屾棤娉曢伩鍏嶇殑銆?/p>

渚嬪锛孋PU 娓╁害銆佹満鍣ㄨ礋杞姐€佽姱鐗囨潗鏂欓兘鏄湁鍙兘瀵艰嚧鏃堕挓鍙戠敓鍋忕Щ銆?/p>

绗簩锛屼粠鎴戠殑宸ヤ綔缁忓巻鏉ヨ锛屾浘缁忓氨閬囧埌杩囨椂閽熼敊璇€佽繍缁存毚鍔涗慨鏀规椂閽熺殑鎯呭喌鍙戠敓锛岃繘鑰屽奖鍝嶄簡绯荤粺鐨勬纭€э紝鎵€浠ワ紝浜轰负閿欒涔熸槸寰堥毦瀹屽叏閬垮厤鐨勩€?/p>

鎵€浠ワ紝鎴戝 Redlock 鐨勪釜浜虹湅娉曟槸锛屽敖閲忎笉鐢ㄥ畠锛岃€屼笖瀹冪殑鎬ц兘涓嶅鍗曟満鐗?Redis锛岄儴缃叉垚鏈篃楂橈紝鎴戣繕鏄細浼樺厛鑰冭檻浣跨敤 Redis銆屼富浠?鍝ㄥ叺銆嶇殑妯″紡锛屽疄鐜板垎甯冨紡閿併€?/p>

閭f纭€у浣曚繚璇佸憿锛熺浜岀偣缁欎綘绛旀銆?/p>

2) 濡備綍姝g‘浣跨敤鍒嗗竷寮忛攣锛?/strong>

鍦ㄥ垎鏋?Martin 瑙傜偣鏃讹紝瀹冩彁鍒颁簡 fencing token 鐨勬柟妗堬紝缁欐垜浜嗗緢澶х殑鍚彂锛岃櫧鐒惰繖绉嶆柟妗堟湁寰堝ぇ鐨勫眬闄愭€э紝浣嗗浜庝繚璇併€屾纭€с€嶇殑鍦烘櫙锛屾槸涓€涓潪甯稿ソ鐨勬€濊矾銆?/p>

鎵€浠ワ紝鎴戜滑鍙互鎶婅繖涓よ€呯粨鍚堣捣鏉ョ敤锛?/p>

1銆佷娇鐢ㄥ垎甯冨紡閿侊紝鍦ㄤ笂灞傚畬鎴愩€屼簰鏂ャ€嶇洰鐨勶紝铏界劧鏋佺鎯呭喌涓嬮攣浼氬け鏁堬紝浣嗗畠鍙互鏈€澶х▼搴︽妸骞跺彂璇锋眰闃绘尅鍦ㄦ渶涓婂眰锛屽噺杞绘搷浣滆祫婧愬眰鐨勫帇鍔涖€?/strong>

2銆佷絾瀵逛簬瑕佹眰鏁版嵁缁濆姝g‘鐨勪笟鍔★紝鍦ㄨ祫婧愬眰涓€瀹氳鍋氬ソ銆屽厹搴曘€嶏紝璁捐鎬濊矾鍙互鍊熼壌 fencing token 鐨勬柟妗堟潵鍋氥€?/strong>

涓ょ鎬濊矾缁撳悎锛屾垜璁や负瀵逛簬澶у鏁颁笟鍔″満鏅紝宸茬粡鍙互婊¤冻瑕佹眰浜嗐€?/p>

鎬荤粨

濂戒簡锛屾€荤粨涓€涓嬨€?/p>

杩欑瘒鏂囩珷锛屾垜浠富瑕佹帰璁ㄤ簡鍩轰簬 Redis 瀹炵幇鐨勫垎甯冨紡閿侊紝绌剁珶鏄惁瀹夊叏杩欎釜闂銆?/p>

浠庢渶绠€鍗曞垎甯冨紡閿佺殑瀹炵幇锛屽埌澶勭悊鍚勭寮傚父鍦烘櫙锛屽啀鍒板紩鍑?Redlock锛屼互鍙婁袱涓垎甯冨紡涓撳鐨勮京璁猴紝寰楀嚭浜?Redlock 鐨勯€傜敤鍦烘櫙銆?/p>

鏈€鍚庯紝鎴戜滑杩樺姣斾簡 Zookeeper 鍦ㄥ仛鍒嗗竷寮忛攣鏃讹紝鍙兘浼氶亣鍒扮殑闂锛屼互鍙婁笌 Redis 鐨勫樊寮傘€?/p>

杩欓噷鎴戞妸杩欎簺鍐呭鎬荤粨鎴愪簡鎬濈淮瀵煎浘锛屾柟渚夸綘鐞嗚В銆?/p>

Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析 &amp; 七种方案!探讨Redis分布式锁的正确使用姿势!,第25张

鍚庤

杩欑瘒鏂囩珷鐨勪俊鎭噺鍏跺疄鏄潪甯稿ぇ鐨勶紝鎴戣寰楀簲璇ユ妸鍒嗗竷閿佺殑闂锛屽交搴曡娓呮浜嗐€?/p>

濡傛灉浣犳病鏈夌悊瑙o紝鎴戝缓璁綘澶氳鍑犻亶锛屽苟鍦ㄨ剳娴蜂腑鏋勫缓鍚勭鍋囧畾鐨勫満鏅紝鍙嶅鎬濊鲸銆?/p>

鍦ㄥ啓杩欑瘒鏂囩珷鏃讹紝鎴戝張閲嶆柊鐮旇浜嗕袱浣嶅ぇ绁炲叧浜?Redlock 浜夎京鐨勮繖涓ょ瘒鏂囩珷锛屽彲璋撴槸鏄敹鑾锋弧婊★紝鍦ㄨ繖閲屼篃鍒嗕韩涓€浜涘績寰楃粰浣犮€?/p>

1銆佸湪鍒嗗竷寮忕郴缁熺幆澧冧笅锛岀湅浼煎畬缇庣殑璁捐鏂规锛屽彲鑳藉苟涓嶆槸閭d箞銆屼弗涓濆悎缂濄€嶏紝濡傛灉绋嶅姞鎺ㄦ暡锛屽氨浼氬彂鐜板悇绉嶉棶棰樸€傛墍浠ワ紝鍦ㄦ€濊€冨垎甯冨紡绯荤粺闂鏃讹紝涓€瀹氳璋ㄦ厧鍐嶈皑鎱?/strong>銆?/p>

2銆佷粠 Redlock 鐨勪簤杈╀腑锛屾垜浠笉瑕佽繃澶氬叧娉ㄥ閿欙紝鑰屾槸瑕佸瀛︿範澶х鐨勬€濊€冩柟寮忥紝浠ュ強瀵逛竴涓棶棰樹弗鏍煎鏌ョ殑涓ヨ皑绮剧銆?/p>

鎴戞槸涓€涓浜庢妧鏈湁鎬濊€冪殑璧勬繁鍚庣绋嬪簭鍛橈紝鍦ㄦ垜鐨勬枃绔犱腑锛屾垜涓嶄粎浼氬憡璇変綘涓€涓妧鏈偣鏄粈涔堬紝杩樹細鍛婅瘔浣犱负浠€涔堣繖涔堝仛锛熸垜杩樹細灏濊瘯鎶婅繖浜涙€濊€冭繃绋嬶紝鎻愮偧鎴愰€氱敤鐨勬柟娉曡锛岃浣犲彲浠ュ簲鐢ㄥ湪鍏跺畠棰嗗煙涓紝鍋氬埌涓句竴鍙嶄笁銆?/strong>

鏈€鍚庯紝鐢?Martin 鍦ㄥ浜?Redlock 浜夎杩囧悗锛屽啓涓嬬殑鎰熸偀鏉ョ粨灏撅細

鈥?strong>鍓嶄汉宸茬粡涓烘垜浠垱閫犲嚭浜嗚澶氫紵澶х殑鎴愭灉锛氱珯鍦ㄥ法浜虹殑鑲╄唨涓婏紝鎴戜滑鍙互鎵嶅緱浠ユ瀯寤烘洿濂界殑杞欢銆傛棤璁哄浣曪紝閫氳繃浜夎鍜屾鏌ュ畠浠槸鍚︾粡寰楄捣鍒汉鐨勮缁嗗鏌ワ紝杩欐槸瀛︿範杩囩▼鐨勪竴閮ㄥ垎銆備絾鐩爣搴旇鏄幏鍙栫煡璇嗭紝鑰屼笉鏄负浜嗚鏈嶅埆浜猴紝璁╁埆浜虹浉淇′綘鏄鐨勩€傛湁鏃跺€欙紝閭e彧鏄剰鍛崇潃鍋滀笅鏉ワ紝濂藉ソ鍦版兂涓€鎯炽€?/strong>鈥?/p>

鍏卞媺銆?/p>

鍙傝€冩枃鐚細

  • http://kaito-kidd.com/2021/06/08/is-redis-distributed-lock-really-safe

  • https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html

  • http://antirez.com/news/101

  • http://zhangtielei.com/posts/blog-redlock-reasoning.html

  • http://zhangtielei.com/posts/blog-redlock-reasoning-part2.html


https://www.xamrdz.com/backend/3rs1931784.html

相关文章: