Redis鍒嗗竷寮忛攣鍩烘湰鍘熺悊
閲囩敤 redis 瀹炵幇鍒嗗竷寮忛攣锛屼富瑕佹槸鍒╃敤鍏跺崟绾跨▼鍛戒护鎵ц鐨勭壒鎬э紝涓€鑸槸 setnx锛?鍙細鏈変竴涓嚎绋嬩細鎵ц鎴愬姛锛屼篃灏辨槸鍙湁涓€涓嚎绋嬭兘鎴愬姛鑾峰彇閿侊紱 鐪嬬潃寰堝畬缇庛€傜劧鑰岋紝銆傘€傘€?/p>
鐪嬬湅鍙兘鏈変粈涔堥棶棰橈紵
涓€鑸敓浜х幆澧冧负浜嗗彲鐢ㄦ€э紝redis 浼氶儴缃?master-slave + sentinel 鐨勭粨鏋勶紝 濡傦細
master 鎻愪緵鏈嶅姟銆乻lave standby 浣滀负澶囦唤鑺傜偣涓嶆彁渚涙湇鍔★紝 master寮傛灏嗘暟鎹鍒剁粰 slave 浠ヤ繚璇佹暟鎹竴鑷达紝 sentinel鍝ㄥ叺妫€鏌?master鑺傜偣锛屽綋master鑺傜偣鏁呴殰鏃?灏唖lave鑺傜偣鎻愬崌涓?鏂扮殑master 瀵瑰鎻愪緵鏈嶅姟锛?/p>
姝e父鎯呭喌涓嬶紝閮芥槸褰撳墠 master 瀵瑰鎻愪緵鏈嶅姟锛屽涓嚎绋?setnx 鍙細鏈変竴涓垚鍔?/p>
褰?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>
鍙傝€冮摼鎺ワ細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>
鎴戜滑鍏堟潵鐪嬩笅锛屼竴鎶婇潬璋辩殑鍒嗗竷寮忛攣搴旇鏈夊摢浜涚壒寰侊細
-
浜掓枼鎬?/strong>: 浠绘剰鏃跺埢锛屽彧鏈変竴涓鎴风鑳芥寔鏈夐攣銆?/li>
- 閿佽秴鏃堕噴鏀?/strong>锛氭寔鏈夐攣瓒呮椂锛屽彲浠ラ噴鏀撅紝闃叉涓嶅繀瑕佺殑璧勬簮娴垂锛屼篃鍙互闃叉姝婚攣銆?/li>
- 鍙噸鍏ユ€?/strong>:涓€涓嚎绋嬪鏋滆幏鍙栦簡閿佷箣鍚?鍙互鍐嶆瀵瑰叾璇锋眰鍔犻攣銆?/li>
- 楂樻€ц兘鍜岄珮鍙敤锛氬姞閿佸拰瑙i攣闇€瑕佸紑閿€灏藉彲鑳戒綆锛屽悓鏃朵篃瑕佷繚璇侀珮鍙敤锛岄伩鍏嶅垎甯冨紡閿佸け鏁堛€?/li>
- 瀹夊叏鎬?/strong>锛氶攣鍙兘琚寔鏈夌殑瀹㈡埛绔垹闄わ紝涓嶈兘琚叾浠栧鎴风鍒犻櫎
- 閿佽秴鏃堕噴鏀?/strong>锛氭寔鏈夐攣瓒呮椂锛屽彲浠ラ噴鏀撅紝闃叉涓嶅繀瑕佺殑璧勬簮娴垂锛屼篃鍙互闃叉姝婚攣銆?/li>
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>
涓轰簡鏇翠弗璋紝涓€鑸篃鏄敤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>
鍙绾跨▼涓€鍔犻攣鎴愬姛锛屽氨浼氬惎鍔ㄤ竴涓?code>watch dog鐪嬮棬鐙楋紝瀹冩槸涓€涓悗鍙扮嚎绋嬶紝浼氭瘡闅?0绉掓鏌ヤ竴涓嬶紝濡傛灉绾跨▼1杩樻寔鏈夐攣锛岄偅涔堝氨浼氫笉鏂殑寤堕暱閿乲ey鐨勭敓瀛樻椂闂淬€傚洜姝わ紝Redisson灏辨槸浣跨敤Redisson瑙e喅浜?strong>閿佽繃鏈熼噴鏀撅紝涓氬姟娌℃墽琛屽畬闂銆?/p>
Redis鍒嗗竷寮忛攣鏂规涓冿細澶氭満瀹炵幇鐨勫垎甯冨紡閿?Redlock+Redisson
鍓嶉潰鍏鏂规閮藉彧鏄熀浜庡崟鏈虹増鐨勮璁猴紝杩樹笉鏄緢瀹岀編銆傚叾瀹濺edis涓€鑸兘鏄泦缇ら儴缃茬殑锛?/p>
濡傛灉绾跨▼涓€鍦≧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>
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>
娆㈣繋鍏虫敞鍏紬鍙凤細绂呬笌璁$畻鏈虹▼搴忚璁¤壓鏈?/p>
杩欑瘒鏂囩珷鎴戞兂鍜屼綘鑱婁竴鑱婏紝鍏充簬 Redis 鍒嗗竷寮忛攣鐨勩€屽畨鍏ㄦ€с€嶉棶棰樸€?/p>
Redis 鍒嗗竷寮忛攣鐨勮瘽棰橈紝寰堝鏂囩珷宸茬粡鍐欑儌浜嗭紝鎴戜负浠€涔堣繕瑕佸啓杩欑瘒鏂囩珷鍛紵
鍥犱负鎴戝彂鐜扮綉涓?99% 鐨勬枃绔狅紝骞舵病鏈夋妸杩欎釜闂鐪熸璁叉竻妤氥€傚鑷村緢澶氳鑰呯湅浜嗗緢澶氭枃绔狅紝渚濇棫浜戦噷闆鹃噷銆備緥濡備笅闈㈣繖浜涢棶棰橈紝浣犺兘娓呮櫚鍦板洖绛斾笂鏉ュ悧锛?/p>
- 鍩轰簬 Redis 濡備綍瀹炵幇涓€涓垎甯冨紡閿侊紵
- Redis 鍒嗗竷寮忛攣鐪熺殑瀹夊叏鍚楋紵
- Redis 鐨?Redlock 鏈変粈涔堥棶棰橈紵涓€瀹氬畨鍏ㄥ悧锛?/li>
- 涓氱晫浜夎 Redlock锛屽埌搴曞湪浜夎浠€涔堬紵鍝瑙傜偣鏄鐨勶紵
- 鍒嗗竷寮忛攣鍒板簳鐢?Redis 杩樻槸 Zookeeper锛?/li>
- 瀹炵幇涓€涓湁銆屽閿欐€с€嶇殑鍒嗗竷寮忛攣锛岄兘闇€瑕佽€冭檻鍝簺闂锛?/li>
杩欑瘒鏂囩珷锛屾垜灏辨潵鎶婅繖浜涢棶棰樺交搴曡娓呮銆?/p>
璇诲畬杩欑瘒鏂囩珷锛屼綘涓嶄粎鍙互褰诲簳浜嗚В鍒嗗竷寮忛攣锛岃繕浼氬銆屽垎甯冨紡绯荤粺銆嶆湁鏇村姞娣卞埢鐨勭悊瑙c€?/p>
鏂囩珷鏈夌偣闀匡紝浣嗗共璐у緢澶氾紝甯屾湜浣犲彲浠ヨ€愬績璇诲畬銆?/strong>
涓轰粈涔堥渶瑕佸垎甯冨紡閿侊紵
鍦ㄥ紑濮嬭鍒嗗竷寮忛攣涔嬪墠锛屾湁蹇呰绠€鍗曚粙缁嶄竴涓嬶紝涓轰粈涔堥渶瑕佸垎甯冨紡閿侊紵
涓庡垎甯冨紡閿佺浉瀵瑰簲鐨勬槸銆屽崟鏈洪攣銆嶏紝鎴戜滑鍦ㄥ啓澶氱嚎绋嬬▼搴忔椂锛岄伩鍏嶅悓鏃舵搷浣滀竴涓叡浜彉閲忎骇鐢熸暟鎹棶棰橈紝閫氬父浼氫娇鐢ㄤ竴鎶婇攣鏉ャ€屼簰鏂ャ€嶏紝浠ヤ繚璇佸叡浜彉閲忕殑姝g‘鎬э紝鍏朵娇鐢ㄨ寖鍥存槸鍦ㄣ€屽悓涓€涓繘绋嬨€嶄腑銆?/p>
濡傛灉鎹㈠仛鏄涓繘绋嬶紝闇€瑕佸悓鏃舵搷浣滀竴涓叡浜祫婧愶紝濡備綍浜掓枼鍛紵
渚嬪锛岀幇鍦ㄧ殑涓氬姟搴旂敤閫氬父閮芥槸寰湇鍔℃灦鏋勶紝杩欎篃鎰忓懗鐫€涓€涓簲鐢ㄤ細閮ㄧ讲澶氫釜杩涚▼锛岄偅杩欏涓繘绋嬪鏋滈渶瑕佷慨鏀?MySQL 涓殑鍚屼竴琛岃褰曟椂锛屼负浜嗛伩鍏嶆搷浣滀贡搴忓鑷存暟鎹敊璇紝姝ゆ椂锛屾垜浠氨闇€瑕佸紩鍏ャ€屽垎甯冨紡閿併€嶆潵瑙e喅杩欎釜闂浜嗐€?/p>
鎯宠瀹炵幇鍒嗗竷寮忛攣锛屽繀椤诲€熷姪涓€涓閮ㄧ郴缁燂紝鎵€鏈夎繘绋嬮兘鍘昏繖涓郴缁熶笂鐢宠銆屽姞閿併€嶃€?/p>
鑰岃繖涓閮ㄧ郴缁燂紝蹇呴』瑕佸疄鐜般€屼簰鏂ャ€嶇殑鑳藉姏锛屽嵆涓や釜璇锋眰鍚屾椂杩涙潵锛屽彧浼氱粰涓€涓繘绋嬭繑鍥炴垚鍔燂紝鍙︿竴涓繑鍥炲け璐ワ紙鎴栫瓑寰咃級銆?/p>
杩欎釜澶栭儴绯荤粺锛屽彲浠ユ槸 MySQL锛屼篃鍙互鏄?Redis 鎴?Zookeeper銆備絾涓轰簡杩芥眰鏇村ソ鐨勬€ц兘锛屾垜浠€氬父浼氶€夋嫨浣跨敤 Redis 鎴?Zookeeper 鏉ュ仛銆?/p>
涓嬮潰鎴戝氨浠?Redis 涓轰富绾匡紝鐢辨祬鍏ユ繁锛屽甫浣犳繁搴﹀墫鏋愪竴涓嬶紝鍒嗗竷寮忛攣鐨勫悇绉嶃€屽畨鍏ㄦ€с€嶉棶棰橈紝甯綘褰诲簳鐞嗚В鍒嗗竷寮忛攣銆?/p>
鍒嗗竷寮忛攣鎬庝箞瀹炵幇锛?/h2>
鎴戜滑浠庢渶绠€鍗曠殑寮€濮嬭璧枫€?/p>
鎯宠瀹炵幇鍒嗗竷寮忛攣锛屽繀椤昏姹?Redis 鏈夈€屼簰鏂ャ€嶇殑鑳藉姏锛屾垜浠彲浠ヤ娇鐢?SETNX 鍛戒护锛岃繖涓懡浠よ〃绀?strong>SET if Not eXists锛屽嵆濡傛灉 key 涓嶅瓨鍦紝鎵嶄細璁剧疆瀹冪殑鍊硷紝鍚﹀垯浠€涔堜篃涓嶅仛銆?/p>
涓や釜瀹㈡埛绔繘绋嬪彲浠ユ墽琛岃繖涓懡浠わ紝杈惧埌浜掓枼锛屽氨鍙互瀹炵幇涓€涓垎甯冨紡閿併€?/p>
姝ゆ椂锛屽姞閿佹垚鍔熺殑瀹㈡埛绔紝灏卞彲浠ュ幓鎿嶄綔銆屽叡浜祫婧愩€嶏紝渚嬪锛屼慨鏀?MySQL 鐨勬煇涓€琛屾暟鎹紝鎴栬€呰皟鐢ㄤ竴涓?API 璇锋眰銆?/p>
鎿嶄綔瀹屾垚鍚庯紝杩樿鍙婃椂閲婃斁閿侊紝缁欏悗鏉ヨ€呰鍑烘搷浣滃叡浜祫婧愮殑鏈轰細銆傚浣曢噴鏀鹃攣鍛紵
涔熷緢绠€鍗曪紝鐩存帴浣跨敤 DEL 鍛戒护鍒犻櫎杩欎釜 key 鍗冲彲锛?/p>
杩欎釜閫昏緫闈炲父绠€鍗曪紝鏁翠綋鐨勮矾绋嬪氨鏄繖鏍凤細
浣嗘槸锛屽畠瀛樺湪涓€涓緢澶х殑闂锛屽綋瀹㈡埛绔?1 鎷垮埌閿佸悗锛屽鏋滃彂鐢熶笅闈㈢殑鍦烘櫙锛屽氨浼氶€犳垚銆屾閿併€嶏細
- 绋嬪簭澶勭悊涓氬姟閫昏緫寮傚父锛屾病鍙婃椂閲婃斁閿?/li>
- 杩涚▼鎸備簡锛屾病鏈轰細閲婃斁閿?/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>
- SETNX 鎵ц鎴愬姛锛屾墽琛?EXPIRE 鏃剁敱浜庣綉缁滈棶棰橈紝鎵ц澶辫触
- SETNX 鎵ц鎴愬姛锛孯edis 寮傚父瀹曟満锛孍XPIRE 娌℃湁鏈轰細鎵ц
- 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 鍔犻攣鎴愬姛锛屽紑濮嬫搷浣滃叡浜祫婧?/li>
- 瀹㈡埛绔?1 鎿嶄綔鍏变韩璧勬簮鐨勬椂闂达紝銆岃秴杩囥€嶄簡閿佺殑杩囨湡鏃堕棿锛岄攣琚€岃嚜鍔ㄩ噴鏀俱€?/li>
- 瀹㈡埛绔?2 鍔犻攣鎴愬姛锛屽紑濮嬫搷浣滃叡浜祫婧?/li>
- 瀹㈡埛绔?1 鎿嶄綔鍏变韩璧勬簮瀹屾垚锛岄噴鏀鹃攣锛堜絾閲婃斁鐨勬槸瀹㈡埛绔?2 鐨勯攣锛?/li>
鐪嬪埌浜嗕箞锛岃繖閲屽瓨鍦ㄤ袱涓弗閲嶇殑闂锛?/p>
- 閿佽繃鏈?/strong>锛氬鎴风 1 鎿嶄綔鍏变韩璧勬簮鑰楁椂澶箙锛屽鑷撮攣琚嚜鍔ㄩ噴鏀撅紝涔嬪悗琚鎴风 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 鎵ц GET锛屽垽鏂攣鏄嚜宸辩殑
- 瀹㈡埛绔?2 鎵ц浜?SET 鍛戒护锛屽己鍒惰幏鍙栧埌閿侊紙铏界劧鍙戠敓姒傜巼姣旇緝浣庯紝浣嗘垜浠渶瑕佷弗璋ㄥ湴鑰冭檻閿佺殑瀹夊叏鎬фā鍨嬶級
- 瀹㈡埛绔?1 鎵ц DEL锛屽嵈閲婃斁浜嗗鎴风 2 鐨勯攣
鐢辨鍙锛岃繖涓や釜鍛戒护杩樻槸蹇呴』瑕佸師瀛愭墽琛屾墠琛屻€?/p>
鎬庢牱鍘熷瓙鎵ц鍛紵Lua 鑴氭湰銆?/p>
鎴戜滑鍙互鎶婅繖涓€昏緫锛屽啓鎴?Lua 鑴氭湰锛岃 Redis 鏉ユ墽琛屻€?/p>
鍥犱负 Redis 澶勭悊姣忎竴涓姹傛槸銆屽崟绾跨▼銆嶆墽琛岀殑锛屽湪鎵ц涓€涓?Lua 鑴氭湰鏃讹紝鍏跺畠璇锋眰蹇呴』绛夊緟锛岀洿鍒拌繖涓?Lua 鑴氭湰澶勭悊瀹屾垚锛岃繖鏍蜂竴鏉ワ紝GET + DEL 涔嬮棿灏变笉浼氭彃鍏ュ叾瀹冨懡浠や簡銆?/p>
瀹夊叏閲婃斁閿佺殑 Lua 鑴氭湰濡備笅锛?/p>
// 鍒ゆ柇閿佹槸鑷繁鐨勶紝鎵嶉噴鏀?
if redis.call("GET",KEYS[1]) == ARGV[1]
then
return redis.call("DEL",KEYS[1])
else
return 0
end
濂戒簡锛岃繖鏍蜂竴璺紭鍖栵紝鏁翠釜鐨勫姞閿併€佽В閿佺殑娴佺▼灏辨洿銆屼弗璋ㄣ€嶄簡銆?/p>
杩欓噷鎴戜滑鍏堝皬缁撲竴涓嬶紝鍩轰簬 Redis 瀹炵幇鐨勫垎甯冨紡閿侊紝涓€涓弗璋ㄧ殑鐨勬祦绋嬪涓嬶細
- 鍔犻攣锛歋ET unique_id EX $expire_time NX
- 鎿嶄綔鍏变韩璧勬簮
- 閲婃斁閿侊細Lua 鑴氭湰锛屽厛 GET 鍒ゆ柇閿佹槸鍚﹀綊灞炶嚜宸憋紝鍐?DEL 閲婃斁閿?/li>
濂斤紝鏈変簡杩欎釜瀹屾暣鐨勯攣妯″瀷锛岃鎴戜滑閲嶆柊鍥炲埌鍓嶉潰鎻愬埌鐨勭涓€涓棶棰樸€?/p>
閿佽繃鏈熸椂闂翠笉濂借瘎浼版€庝箞鍔烇紵
鍓嶉潰鎴戜滑鎻愬埌锛岄攣鐨勮繃鏈熸椂闂村鏋滆瘎浼颁笉濂斤紝杩欎釜閿佸氨浼氭湁銆屾彁鍓嶃€嶈繃鏈熺殑椋庨櫓銆?/p>
褰撴椂缁欑殑濡ュ崗鏂规鏄紝灏介噺銆屽啑浣欍€嶈繃鏈熸椂闂达紝闄嶄綆閿佹彁鍓嶈繃鏈熺殑姒傜巼銆?/p>
杩欎釜鏂规鍏跺疄涔熶笉鑳藉畬缇庤В鍐抽棶棰橈紝閭f€庝箞鍔炲憿锛?/p>
鐪嬮棬鐙?watch dog 鑷姩缁湡
鏄惁鍙互璁捐杩欐牱鐨勬柟妗堬細鍔犻攣鏃讹紝鍏堣缃竴涓繃鏈熸椂闂达紝鐒跺悗鎴戜滑寮€鍚竴涓€屽畧鎶ょ嚎绋嬨€嶏紝瀹氭椂鍘绘娴嬭繖涓攣鐨勫け鏁堟椂闂达紝濡傛灉閿佸揩瑕佽繃鏈熶簡锛屾搷浣滃叡浜祫婧愯繕鏈畬鎴愶紝閭d箞灏辫嚜鍔ㄥ閿佽繘琛屻€岀画鏈熴€嶏紝閲嶆柊璁剧疆杩囨湡鏃堕棿銆?/strong>
杩欑‘瀹炰竴绉嶆瘮杈冨ソ鐨勬柟妗堛€?/p>
濡傛灉浣犳槸 Java 鎶€鏈爤锛屽垢杩愮殑鏄紝宸茬粡鏈変竴涓簱鎶婅繖浜涘伐浣滈兘灏佽濂戒簡锛?strong>Redisson銆?/p>
Redisson 鏄竴涓?Java 璇█瀹炵幇鐨?Redis SDK 瀹㈡埛绔紝鍦ㄤ娇鐢ㄥ垎甯冨紡閿佹椂锛屽畠灏遍噰鐢ㄤ簡銆岃嚜鍔ㄧ画鏈熴€嶇殑鏂规鏉ラ伩鍏嶉攣杩囨湡锛岃繖涓畧鎶ょ嚎绋嬫垜浠竴鑸篃鎶婂畠鍙仛銆岀湅闂ㄧ嫍銆嶇嚎绋嬨€?/p>
闄ゆ涔嬪锛岃繖涓?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 鍦ㄤ富搴撲笂鎵ц SET 鍛戒护锛屽姞閿佹垚鍔?/li>
- 姝ゆ椂锛屼富搴撳紓甯稿畷鏈猴紝SET 鍛戒护杩樻湭鍚屾鍒颁粠搴撲笂锛堜富浠庡鍒舵槸寮傛鐨勶級
- 浠庡簱琚摠鍏垫彁鍗囦负鏂颁富搴擄紝杩欎釜閿佸湪鏂扮殑涓诲簱涓婏紝涓㈠け浜嗭紒
鍙锛屽綋寮曞叆 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 涓墠鎻愶細
- 涓嶅啀闇€瑕侀儴缃?strong>浠庡簱鍜?strong>鍝ㄥ叺瀹炰緥锛屽彧閮ㄧ讲涓诲簱
- 浣嗕富搴撹閮ㄧ讲澶氫釜锛屽畼鏂规帹鑽愯嚦灏?5 涓疄渚?/li>
涔熷氨鏄锛屾兂鐢ㄤ娇鐢?Redlock锛屼綘鑷冲皯瑕侀儴缃?5 涓?Redis 瀹炰緥锛岃€屼笖閮芥槸涓诲簱锛屽畠浠箣闂存病鏈変换浣曞叧绯伙紝閮芥槸涓€涓釜瀛ょ珛鐨勫疄渚嬨€?/p>
娉ㄦ剰锛氫笉鏄儴缃?Redis Cluster锛屽氨鏄儴缃?5 涓畝鍗曠殑 Redis 瀹炰緥銆?/strong>
Redlock 鍏蜂綋濡備綍浣跨敤鍛紵
鏁翠綋鐨勬祦绋嬫槸杩欐牱鐨勶紝涓€鍏卞垎涓?5 姝ワ細
- 瀹㈡埛绔厛鑾峰彇銆屽綋鍓嶆椂闂存埑T1銆?/li>
- 瀹㈡埛绔緷娆″悜杩?5 涓?Redis 瀹炰緥鍙戣捣鍔犻攣璇锋眰锛堢敤鍓嶉潰璁插埌鐨?SET 鍛戒护锛夛紝涓旀瘡涓姹備細璁剧疆瓒呮椂鏃堕棿锛堟绉掔骇锛岃杩滃皬浜庨攣鐨勬湁鏁堟椂闂达級锛屽鏋滄煇涓€涓疄渚嬪姞閿佸け璐ワ紙鍖呮嫭缃戠粶瓒呮椂銆侀攣琚叾瀹冧汉鎸佹湁绛夊悇绉嶅紓甯告儏鍐碉級锛屽氨绔嬪嵆鍚戜笅涓€涓?Redis 瀹炰緥鐢宠鍔犻攣
- 濡傛灉瀹㈡埛绔粠 >=3 涓紙澶у鏁帮級浠ヤ笂 Redis 瀹炰緥鍔犻攣鎴愬姛锛屽垯鍐嶆鑾峰彇銆屽綋鍓嶆椂闂存埑T2銆嶏紝濡傛灉 T2 - T1 < 閿佺殑杩囨湡鏃堕棿锛屾鏃讹紝璁や负瀹㈡埛绔姞閿佹垚鍔燂紝鍚﹀垯璁や负鍔犻攣澶辫触
- 鍔犻攣鎴愬姛锛屽幓鎿嶄綔鍏变韩璧勬簮锛堜緥濡備慨鏀?MySQL 鏌愪竴琛岋紝鎴栧彂璧蜂竴涓?API 璇锋眰锛?/li>
- 鍔犻攣澶辫触锛屽悜銆屽叏閮ㄨ妭鐐广€嶅彂璧烽噴鏀鹃攣璇锋眰锛堝墠闈㈣鍒扮殑 Lua 鑴氭湰閲婃斁閿侊級
鎴戠畝鍗曞府浣犳€荤粨涓€涓嬶紝鏈?4 涓噸鐐癸細
- 瀹㈡埛绔湪澶氫釜 Redis 瀹炰緥涓婄敵璇峰姞閿?/li>
- 蹇呴』淇濊瘉澶у鏁拌妭鐐瑰姞閿佹垚鍔?/li>
- 澶у鏁拌妭鐐瑰姞閿佺殑鎬昏€楁椂锛岃灏忎簬閿佽缃殑杩囨湡鏃堕棿
- 閲婃斁閿侊紝瑕佸悜鍏ㄩ儴鑺傜偣鍙戣捣閲婃斁閿佽姹?/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>
杩欎釜涓撳鍙?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
- N锛歂etwork Delay锛岀綉缁滃欢杩?/li>
- P锛歅rocess Pause锛岃繘绋嬫殏鍋滐紙GC锛?/li>
- C锛欳lock Drift锛屾椂閽熸紓绉?/li>
Martin 鐢ㄤ竴涓繘绋嬫殏鍋滐紙GC锛夌殑渚嬪瓙锛屾寚鍑轰簡 Redlock 瀹夊叏鎬ч棶棰橈細
- 瀹㈡埛绔?1 璇锋眰閿佸畾鑺傜偣 A銆丅銆丆銆丏銆丒
- 瀹㈡埛绔?1 鐨勬嬁鍒伴攣鍚庯紝杩涘叆 GC锛堟椂闂存瘮杈冧箙锛?/li>
- 鎵€鏈?Redis 鑺傜偣涓婄殑閿侀兘杩囨湡浜?/li>
- 瀹㈡埛绔?2 鑾峰彇鍒颁簡 A銆丅銆丆銆丏銆丒 涓婄殑閿?/li>
- 瀹㈡埛绔?1 GC 缁撴潫锛岃涓烘垚鍔熻幏鍙栭攣
- 瀹㈡埛绔?2 涔熻涓鸿幏鍙栧埌浜嗛攣锛屽彂鐢熴€屽啿绐併€?/li>
Martin 璁や负锛孏C 鍙兘鍙戠敓鍦ㄧ▼搴忕殑浠绘剰鏃跺埢锛岃€屼笖鎵ц鏃堕棿鏄笉鍙帶鐨勩€?/p>
娉細褰撶劧锛屽嵆浣挎槸浣跨敤娌℃湁 GC 鐨勭紪绋嬭瑷€锛屽湪鍙戠敓缃戠粶寤惰繜銆佹椂閽熸紓绉绘椂锛屼篃閮芥湁鍙兘瀵艰嚧 Redlock 鍑虹幇闂锛岃繖閲?Martin 鍙槸鎷?GC 涓句緥銆?/p>
3) 鍋囪鏃堕挓姝g‘鐨勬槸涓嶅悎鐞嗙殑
鍙堟垨鑰咃紝褰撳涓?Redis 鑺傜偣銆屾椂閽熴€嶅彂鐢熼棶棰樻椂锛屼篃浼氬鑷?Redlock 閿佸け鏁?/strong>銆?/p>
Martin 瑙夊緱锛孯edlock 蹇呴』銆屽己渚濊禆銆嶅涓妭鐐圭殑鏃堕挓鏄繚鎸佸悓姝ョ殑锛屼竴鏃︽湁鑺傜偣鏃堕挓鍙戠敓閿欒锛岄偅杩欎釜绠楁硶妯″瀷灏卞け鏁堜簡銆?/p>
鍗充娇 C 涓嶆槸鏃堕挓璺宠穬锛岃€屾槸銆屽穿婧冨悗绔嬪嵆閲嶅惎銆嶏紝涔熶細鍙戠敓绫讳技鐨勯棶棰樸€?/p>
Martin 缁х画闃愯堪锛屾満鍣ㄧ殑鏃堕挓鍙戠敓閿欒锛屾槸寰堟湁鍙兘鍙戠敓鐨勶細 鎬讳箣锛孧artin 璁や负锛孯edlock 鐨勭畻娉曟槸寤虹珛鍦ㄣ€屽悓姝ユā鍨嬨€嶅熀纭€涓婄殑锛屾湁澶ч噺璧勬枡鐮旂┒琛ㄦ槑锛屽悓姝ユā鍨嬬殑鍋囪锛屽湪鍒嗗竷寮忕郴缁熶腑鏄湁闂鐨勩€?/p>
鍦ㄦ贩涔辩殑鍒嗗竷寮忕郴缁熺殑涓紝浣犱笉鑳藉亣璁剧郴缁熸椂閽熷氨鏄鐨勶紝鎵€浠ワ紝浣犲繀椤婚潪甯稿皬蹇冧綘鐨勫亣璁俱€?/p>
4) 鎻愬嚭 fencing token 鐨勬柟妗堬紝淇濊瘉姝g‘鎬?/strong> 鐩稿搴旂殑锛孧artin 鎻愬嚭涓€绉嶈鍙綔 fencing token 鐨勬柟妗堬紝淇濊瘉鍒嗗竷寮忛攣鐨勬纭€с€?/p>
杩欎釜妯″瀷娴佺▼濡備笅锛?/p>
杩欐牱涓€鏉ワ紝鏃犺 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 浣滆€呯殑鏂囩珷涓紝閲嶇偣鏈?3 涓細 1) 瑙i噴鏃堕挓闂 棣栧厛锛孉ntirez 涓€鐪煎氨鐪嬬┛浜嗗鏂规彁鍑虹殑鏈€涓烘牳蹇冪殑闂锛?strong>鏃堕挓闂 Antirez 琛ㄧず锛孯edlock 骞朵笉闇€瑕佸畬鍏ㄤ竴鑷寸殑鏃堕挓锛屽彧闇€瑕佸ぇ浣撲竴鑷村氨鍙互浜嗭紝鍏佽鏈夈€岃宸€嶃€?/p>
渚嬪瑕佽鏃?5s锛屼絾瀹為檯鍙兘璁颁簡 4.5s锛屼箣鍚庡張璁颁簡 5.5s锛屾湁涓€瀹氳宸紝浣嗗彧瑕佷笉瓒呰繃銆岃宸寖鍥淬€嶉攣澶辨晥鏃堕棿鍗冲彲锛岃繖绉嶅浜庢椂閽熺殑绮惧害鐨勮姹傚苟涓嶆槸寰堥珮锛岃€屼笖杩欎篃绗﹀悎鐜板疄鐜銆?/p>
瀵逛簬瀵规柟鎻愬埌鐨勩€屾椂閽熶慨鏀广€嶉棶棰橈紝Redis 浣滆€呭弽椹冲埌锛?/p>
涓轰粈涔?Antirez 浼樺厛瑙i噴鏃堕挓闂锛熷洜涓哄湪鍚庨潰鐨勫弽椹宠繃绋嬩腑锛岄渶瑕佷緷璧栬繖涓熀纭€鍋氳繘涓€姝ヨВ閲娿€?/p>
2) 瑙i噴缃戠粶寤惰繜銆丟C 闂 涔嬪悗锛孉ntirez 瀵逛簬瀵规柟鎻愬嚭鐨勶紝缃戠粶寤惰繜wan銆佽繘绋?GC 鍙兘瀵艰嚧 Redlock 澶辨晥鐨勯棶棰橈紝涔熷仛浜嗗弽椹筹細 鎴戜滑閲嶆柊鍥為【涓€涓嬶紝Martin 鎻愬嚭鐨勯棶棰樺亣璁撅細 Redis 浣滆€呭弽椹冲埌锛岃繖涓亣璁惧叾瀹炴槸鏈夐棶棰樼殑锛孯edlock 鏄彲浠ヤ繚璇侀攣瀹夊叏鐨勩€?/p>
杩欐槸鎬庝箞鍥炰簨鍛紵 杩樿寰楀墠闈粙缁?Redlock 娴佺▼鐨勯偅 5 姝ュ悧锛熻繖閲屾垜鍐嶆嬁杩囨潵璁╀綘澶嶄範涓€涓嬨€?/p>
娉ㄦ剰锛岄噸鐐规槸 1-3锛屽湪姝ラ 3锛屽姞閿佹垚鍔熷悗涓轰粈涔堣閲嶆柊鑾峰彇銆屽綋鍓嶆椂闂存埑T2銆嶏紵杩樼敤 T2 - T1 鐨勬椂闂达紝涓庨攣鐨勮繃鏈熸椂闂村仛姣旇緝锛?/strong> Antirez 寮鸿皟锛氬鏋滃湪 1-3 鍙戠敓浜嗙綉缁滃欢杩熴€佽繘绋?GC 绛夎€楁椂闀跨殑寮傚父鎯呭喌锛岄偅鍦ㄧ 3 姝?T2 - T1锛屾槸鍙互妫€娴嬪嚭鏉ョ殑锛屽鏋滆秴鍑轰簡閿佽缃殑杩囨湡鏃堕棿锛岄偅杩欐椂灏辫涓哄姞閿佷細澶辫触锛屼箣鍚庨噴鏀炬墍鏈夎妭鐐圭殑閿佸氨濂戒簡锛?/p>
Antirez 缁х画璁鸿堪锛屽鏋滃鏂硅涓猴紝鍙戠敓缃戠粶寤惰繜銆佽繘绋?GC 鏄湪姝ラ 3 涔嬪悗锛屼篃灏辨槸瀹㈡埛绔‘璁ゆ嬁鍒颁簡閿侊紝鍘绘搷浣滃叡浜祫婧愮殑閫斾腑鍙戠敓浜嗛棶棰橈紝瀵艰嚧閿佸け鏁堬紝閭h繖涓嶆鏄?Redlock 鐨勯棶棰橈紝浠讳綍鍏跺畠閿佹湇鍔′緥濡?Zookeeper锛岄兘鏈夌被浼肩殑闂锛岃繖涓嶅湪璁ㄨ鑼冪暣鍐?/strong>銆?/p>
杩欓噷鎴戜妇涓緥瀛愯В閲婁竴涓嬭繖涓棶棰橈細 Antirez 杩欓噷鐨勭粨璁哄氨鏄細 鎵€浠ワ紝Antirez 璁や负 Redlock 鍦ㄤ繚璇佹椂閽熸纭殑鍩虹涓婏紝鏄彲浠ヤ繚璇佹纭€х殑銆?/p>
3) 璐ㄧ枒 fencing token 鏈哄埗 Antirez 瀵逛簬瀵规柟鎻愬嚭鐨?fencing token 鏈哄埗锛屼篃鎻愬嚭浜嗚川鐤戯紝涓昏鍒嗕负 2 涓棶棰樸€?/p>
绗竴锛岃繖涓柟妗堝繀椤昏姹傝鎿嶄綔鐨勩€屽叡浜祫婧愭湇鍔″櫒銆嶆湁鎷掔粷銆屾棫 token銆嶇殑鑳藉姏銆?/p>
渚嬪锛岃鎿嶄綔 MySQL锛屼粠閿佹湇鍔℃嬁鍒颁竴涓€掑鏁板瓧鐨?token锛岀劧鍚庡鎴风瑕佸甫鐫€杩欎釜 token 鍘绘敼 MySQL 鐨勬煇涓€琛岋紝杩欏氨闇€瑕佸埄鐢?MySQL 鐨勩€屼簨鐗╅殧绂绘€с€嶆潵鍋氥€?/p>
浣嗗鏋滄搷浣滅殑涓嶆槸 MySQL 鍛紵渚嬪鍚戠鐩樹笂鍐欎竴涓枃浠讹紝鎴栧彂璧蜂竴涓?HTTP 璇锋眰锛岄偅杩欎釜鏂规灏辨棤鑳戒负鍔涗簡锛岃繖瀵硅鎿嶄綔鐨勮祫婧愭湇鍔″櫒锛屾彁鍑轰簡鏇撮珮鐨勮姹傘€?/p>
涔熷氨鏄锛屽ぇ閮ㄥ垎瑕佹搷浣滅殑璧勬簮鏈嶅姟鍣紝閮芥槸娌℃湁杩欑浜掓枼鑳藉姏鐨勩€?/p>
鍐嶈€咃紝鏃㈢劧璧勬簮鏈嶅姟鍣ㄩ兘鏈変簡銆屼簰鏂ャ€嶈兘鍔涳紝閭h繕瑕佸垎甯冨紡閿佸共浠€涔堬紵 鎵€浠ワ紝Antirez 璁や负杩欎釜鏂规鏄珯涓嶄綇鑴氱殑銆?/p>
绗簩锛岄€€涓€姝ヨ锛屽嵆浣?Redlock 娌℃湁鎻愪緵 fencing token 鐨勮兘鍔涳紝浣?Redlock 宸茬粡鎻愪緵浜嗛殢鏈哄€硷紙灏辨槸鍓嶉潰璁茬殑 UUID锛夛紝鍒╃敤杩欎釜闅忔満鍊硷紝涔熷彲浠ヨ揪鍒颁笌 fencing token 鍚屾牱鐨勬晥鏋溿€?/p>
濡備綍鍋氬憿锛?/p>
Antirez 鍙槸鎻愬埌浜嗗彲浠ュ畬鎴?fencing token 绫讳技鐨勫姛鑳斤紝浣嗗嵈娌℃湁灞曞紑鐩稿叧缁嗚妭锛屾牴鎹垜鏌ラ槄鐨勮祫鏂欙紝澶ф娴佺▼搴旇濡備笅锛屽鏈夐敊璇紝娆㈣繋浜ゆ祦~ 杩樻槸浠?MySQL 涓轰緥锛屼妇涓緥瀛愬氨鏄繖鏍风殑锛?/p>
鍙锛岃繖绉嶆柟妗堜緷璧?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 涓嶅儚 Redis 閭f牱锛岄渶瑕佽€冭檻閿佺殑杩囨湡鏃堕棿闂锛屽畠鏄噰鐢ㄤ簡銆屼复鏃惰妭鐐广€嶏紝淇濊瘉瀹㈡埛绔?1 鎷垮埌閿佸悗锛屽彧瑕佽繛鎺ヤ笉鏂紝灏卞彲浠ヤ竴鐩存寔鏈夐攣銆?/p>
鑰屼笖锛屽鏋滃鎴风 1 寮傚父宕╂簝浜嗭紝閭d箞杩欎釜涓存椂鑺傜偣浼氳嚜鍔ㄥ垹闄わ紝淇濊瘉浜嗛攣涓€瀹氫細琚噴鏀俱€?/p>
涓嶉敊锛屾病鏈夐攣杩囨湡鐨勭儲鎭硷紝杩樿兘鍦ㄥ紓甯告椂鑷姩閲婃斁閿侊紝鏄笉鏄寰楀緢瀹岀編锛?/strong> 鍏跺疄涓嶇劧銆?/p>
鎬濊€冧竴涓嬶紝瀹㈡埛绔?1 鍒涘缓涓存椂鑺傜偣鍚庯紝Zookeeper 鏄浣曚繚璇佽杩欎釜瀹㈡埛绔竴鐩存寔鏈夐攣鍛紵 鍘熷洜灏卞湪浜庯紝瀹㈡埛绔?1 姝ゆ椂浼氫笌 Zookeeper 鏈嶅姟鍣ㄧ淮鎶や竴涓?Session锛岃繖涓?Session 浼氫緷璧栧鎴风銆屽畾鏃跺績璺炽€嶆潵缁存寔杩炴帴銆?/strong> 濡傛灉 Zookeeper 闀挎椂闂存敹涓嶅埌瀹㈡埛绔殑蹇冭烦锛屽氨璁や负杩欎釜 Session 杩囨湡浜嗭紝涔熶細鎶婅繖涓复鏃惰妭鐐瑰垹闄ゃ€?/p>
鍚屾牱鍦帮紝鍩轰簬姝ら棶棰橈紝鎴戜滑涔熻璁轰竴涓?GC 闂瀵?Zookeeper 鐨勯攣鏈変綍褰卞搷锛?/p>
鍙锛屽嵆浣挎槸浣跨敤 Zookeeper锛屼篃鏃犳硶淇濊瘉杩涚▼ GC銆佺綉缁滃欢杩熷紓甯稿満鏅笅鐨勫畨鍏ㄦ€с€?/p>
杩欏氨鏄墠闈?Antirez 鍦ㄥ弽椹崇殑鏂囩珷涓彁鍒扮殑锛氬鏋滃鎴风宸茬粡鎷垮埌浜嗛攣锛屼絾瀹㈡埛绔笌閿佹湇鍔″櫒鍙戠敓銆屽け鑱斻€嶏紙渚嬪 GC锛夛紝閭d笉姝?Redlock 鏈夐棶棰橈紝鍏跺畠閿佹湇鍔¢兘鏈夌被浼肩殑闂锛孼ookeeper 涔熸槸涓€鏍凤紒 鎵€浠ワ紝杩欓噷鎴戜滑灏辫兘寰楀嚭缁撹浜嗭細涓€涓垎甯冨紡閿侊紝鍦ㄦ瀬绔儏鍐典笅锛屼笉涓€瀹氭槸瀹夊叏鐨勩€?/strong> 濡傛灉浣犵殑涓氬姟鏁版嵁闈炲父鏁忔劅锛屽湪浣跨敤鍒嗗竷寮忛攣鏃讹紝涓€瀹氳娉ㄦ剰杩欎釜闂锛屼笉鑳藉亣璁惧垎甯冨紡閿?100% 瀹夊叏銆?/p>
濂斤紝鐜板湪鎴戜滑鏉ユ€荤粨涓€涓?Zookeeper 鍦ㄤ娇鐢ㄥ垎甯冨紡閿佹椂浼樺姡锛?/p>
Zookeeper 鐨勪紭鐐癸細 浣嗗畠鐨勫姡鍔挎槸锛?/p>
濂戒簡锛屽墠闈㈣缁嗕粙缁嶄簡鍩轰簬 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>
杩欑瘒鏂囩珷鐨勪俊鎭噺鍏跺疄鏄潪甯稿ぇ鐨勶紝鎴戣寰楀簲璇ユ妸鍒嗗竷閿佺殑闂锛屽交搴曡娓呮浜嗐€?/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
Token 鏄竾鑳界殑
Redis 浣滆€?Antirez 鐨勫弽椹?/h2>
// 涓や釜瀹㈡埛绔繀椤诲埄鐢ㄤ簨鐗╁拰闅旂鎬ц揪鍒扮洰鐨?
// 娉ㄦ剰 token 鐨勫垽鏂潯浠?
UPDATE table T SET val = $new_val, current_token = $token WHERE id = $id AND current_token < $token
UPDATE table T SET val = $new_val WHERE id = $id AND current_token = $redlock_value
鍩轰簬 Zookeeper 鐨勯攣瀹夊叏鍚楋紵
鎴戝鍒嗗竷寮忛攣鐨勭悊瑙?/h2>
鎬荤粨
鍚庤
鍙傝€冩枃鐚細