Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵

Posted 寮€鍙戣€呮妧鏈墠绾?/a>

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵相关的知识,希望对你有一定的参考价值。


鐐瑰嚮鈥?/span> 寮€鍙戣€呮妧鏈墠绾?/span> 鈥濓紝閫夋嫨鈥滄槦鏍囸煍濃€?/span>

鍦ㄧ湅|鏄熸爣|鐣欒█,  鐪熺埍


浣滆€咃細jianfeng
鏉ユ簮锛氱煶鏉夌殑鏋舵瀯绗旇

涓轰粈涔堢敤鍒嗗竷寮忛攣锛?/span>

鍦ㄨ璁鸿繖涓棶棰樹箣鍓嶏紝鎴戜滑鍏堟潵鐪嬩竴涓笟鍔″満鏅細
绯荤粺A鏄竴涓數鍟嗙郴缁燂紝鐩墠鏄竴鍙版満鍣ㄩ儴缃诧紝绯荤粺涓湁涓€涓敤鎴蜂笅璁㈠崟鐨勬帴鍙o紝浣嗘槸鐢ㄦ埛涓嬭鍗曚箣鍓嶄竴瀹氳鍘绘鏌ヤ竴涓嬪簱瀛橈紝纭繚搴撳瓨瓒冲浜嗘墠浼氱粰鐢ㄦ埛涓嬪崟銆?/span>
鐢变簬绯荤粺鏈変竴瀹氱殑骞跺彂锛屾墍浠ヤ細棰勫厛灏嗗晢鍝佺殑搴撳瓨淇濆瓨鍦╮edis涓紝鐢ㄦ埛涓嬪崟鐨勬椂鍊欎細鏇存柊redis鐨勫簱瀛樸€?/span>
姝ゆ椂绯荤粺鏋舵瀯濡備笅锛?/span>
Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵
浣嗘槸杩欐牱涓€鏉ヤ細浜х敓涓€涓棶棰?/strong>锛氬亣濡傛煇涓椂鍒伙紝redis閲岄潰鐨勬煇涓晢鍝佸簱瀛樹负1锛屾鏃朵袱涓姹傚悓鏃跺埌鏉ワ紝鍏朵腑涓€涓姹傛墽琛屽埌涓婂浘鐨勭3姝ワ紝鏇存柊鏁版嵁搴撶殑搴撳瓨涓?锛屼絾鏄4姝ヨ繕娌℃湁鎵ц銆?/span>
鑰屽彟澶栦竴涓姹傛墽琛屽埌浜嗙2姝ワ紝鍙戠幇搴撳瓨杩樻槸1锛屽氨缁х画鎵ц绗?姝ャ€?/span>
杩欐牱鐨勭粨鏋滐紝鏄鑷村崠鍑轰簡2涓晢鍝侊紝鐒惰€屽叾瀹炲簱瀛樺彧鏈?涓€?/span>
寰?/span> 鏄庢樉涓嶅鍟婏紒杩欏氨鏄吀鍨嬬殑 搴撳瓨瓒呭崠闂
姝ゆ椂锛屾垜浠緢瀹规槗鎯冲埌瑙e喅鏂规锛氱敤閿佹妸2銆?銆?姝ラ攣浣忥紝璁╀粬浠墽琛屽畬涔嬪悗锛屽彟涓€涓嚎绋嬫墠鑳借繘鏉ユ墽琛岀2姝ャ€?/span>
Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵
鎸夌収涓婇潰鐨勫浘锛屽湪鎵ц绗?姝ユ椂锛屼娇鐢↗ava鎻愪緵鐨剆ynchronized鎴栬€匯eentrantLock鏉ラ攣浣忥紝鐒跺悗鍦ㄧ4姝ユ墽琛屽畬涔嬪悗鎵嶉噴鏀鹃攣銆?/span>
杩欐牱涓€鏉ワ紝2銆?銆? 杩?涓楠ゅ氨琚€滈攣鈥濅綇浜嗭紝澶氫釜绾跨▼涔嬮棿鍙兘涓茶鍖栨墽琛屻€?/span>
浣嗘槸濂芥櫙涓嶉暱锛屾暣涓郴缁熺殑骞跺彂椋欏崌锛屼竴鍙版満鍣ㄦ墰涓嶄綇浜嗐€傜幇鍦ㄨ澧炲姞涓€鍙版満鍣紝濡備笅鍥撅細
Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵

澧炲姞鏈哄櫒涔嬪悗锛岀郴缁熷彉鎴愪笂鍥炬墍绀猴紝鎴戠殑澶╋紒
鍋囪姝ゆ椂涓や釜鐢ㄦ埛鐨勮姹傚悓鏃跺埌鏉ワ紝浣嗘槸钀藉湪浜嗕笉鍚岀殑鏈哄櫒涓婏紝閭d箞杩欎袱涓姹傛槸鍙互鍚屾椂鎵ц浜嗭紝杩樻槸浼氬嚭鐜?span class="mq-60">搴撳瓨瓒呭崠鐨勯棶棰樸€?/span>
涓轰粈涔堝憿锛熷洜涓轰笂鍥句腑鐨勪袱涓狝绯荤粺锛岃繍琛屽湪涓や釜涓嶅悓鐨凧VM閲岄潰锛屼粬浠姞鐨勯攣鍙灞炰簬鑷繁JVM閲岄潰鐨勭嚎绋嬫湁鏁堬紝瀵逛簬鍏朵粬JVM鐨勭嚎绋嬫槸鏃犳晥鐨勩€?/span>
鍥犳锛岃繖閲岀殑闂鏄細Java鎻愪緵鐨勫師鐢熼攣鏈哄埗鍦ㄥ鏈洪儴缃插満鏅笅澶辨晥浜?/span>
杩欐槸鍥犱负涓ゅ彴鏈哄櫒鍔犵殑閿佷笉鏄悓涓€涓攣(涓や釜閿佸湪涓嶅悓鐨凧VM閲岄潰)銆?/span>
閭d箞锛?span class="mq-70">鎴戜滑鍙淇濊瘉涓ゅ彴鏈哄櫒鍔犵殑閿佹槸鍚屼竴涓攣锛岄棶棰樹笉灏辫В鍐充簡鍚楋紵
姝ゆ椂锛屽氨璇?span class="mq-73">鍒嗗竷寮忛攣闅嗛噸鐧诲満浜嗭紝鍒嗗竷寮忛攣鐨勬€濊矾鏄細
鍦ㄦ暣涓郴缁熸彁渚涗竴涓?span>鍏ㄥ眬銆佸敮涓€鐨勮幏鍙栭攣鐨勨€滀笢瑗库€濓紝鐒跺悗姣忎釜绯荤粺鍦ㄩ渶瑕佸姞閿佹椂锛岄兘鍘婚棶杩欎釜鈥滀笢瑗库€濇嬁鍒颁竴鎶婇攣锛岃繖鏍蜂笉鍚岀殑绯荤粺鎷垮埌鐨勫氨鍙互璁や负鏄悓涓€鎶婇攣銆?/span>
鑷充簬杩欎釜鈥滀笢瑗库€濓紝鍙互鏄疪edis銆乑ookeeper锛屼篃鍙互鏄暟鎹簱銆?/span>
鏂囧瓧鎻忚堪涓嶅お鐩磋锛屾垜浠潵鐪嬩笅鍥撅細
Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵
閫氳繃涓婇潰鐨勫垎鏋愶紝鎴戜滑鐭ラ亾浜嗗簱瀛樿秴鍗栧満鏅湪鍒嗗竷寮忛儴缃茬郴缁熺殑鎯呭喌涓嬩娇鐢↗ava鍘熺敓鐨勯攣鏈哄埗鏃犳硶淇濊瘉绾跨▼瀹夊叏锛屾墍浠ユ垜浠渶瑕佺敤鍒板垎甯冨紡閿佺殑鏂规銆?/span>
閭d箞锛屽浣曞疄鐜板垎甯冨紡閿佸憿锛熸帴鐫€寰€涓嬬湅锛?/span>

鍩轰簬Redis瀹炵幇鍒嗗竷寮忛攣

涓婇潰鍒嗘瀽涓哄暐瑕佷娇鐢ㄥ垎甯冨紡閿佷簡锛岃繖閲屾垜浠潵鍏蜂綋鐪嬬湅鍒嗗竷寮忛攣钀藉湴鐨勬椂鍊欏簲璇ユ€庝箞鏍峰鐞嗐€傛墿灞曪細

鏈€甯歌鐨勪竴绉嶆柟妗堝氨鏄娇鐢?/span> Redis鍋氬垎甯冨紡閿?/span>
浣跨敤Redis鍋氬垎甯冨紡閿佺殑鎬濊矾澶ф鏄繖鏍风殑锛氬湪redis涓缃竴涓€艰〃绀哄姞浜嗛攣锛岀劧鍚庨噴鏀鹃攣鐨勬椂鍊欏氨鎶婅繖涓猭ey鍒犻櫎銆?/span>
鍏蜂綋浠g爜鏄繖鏍风殑锛?/span>
   
     
     
   
// 鑾峰彇閿?/span>
// NX鏄寚濡傛灉key涓嶅瓨鍦ㄥ氨鎴愬姛锛宬ey瀛樺湪杩斿洖false锛孭X鍙互鎸囧畾杩囨湡鏃堕棿
SET anyLock unique_value NX PX  30000


// 閲婃斁閿侊細閫氳繃鎵ц涓€娈祃ua鑴氭湰
// 閲婃斁閿佹秹鍙婂埌涓ゆ潯鎸囦护锛岃繖涓ゆ潯鎸囦护涓嶆槸鍘熷瓙鎬х殑
// 闇€瑕佺敤鍒皉edis鐨刲ua鑴氭湰鏀寔鐗规€э紝redis鎵цlua鑴氭湰鏄師瀛愭€х殑
if redis.call( "get",KEYS[ 1]) == ARGV[ 1] then
return redis.call( "del",KEYS[ 1])
else
return  0
end

杩欑鏂瑰紡鏈夊嚑澶ц鐐癸細
  • 涓€瀹氳鐢⊿ET key value NX PX milliseconds 鍛戒护

    濡傛灉涓嶇敤锛屽厛璁剧疆浜嗗€硷紝鍐嶈缃繃鏈熸椂闂达紝杩欎釜涓嶆槸鍘熷瓙鎬ф搷浣滐紝鏈夊彲鑳藉湪璁剧疆杩囨湡鏃堕棿涔嬪墠瀹曟満锛屼細閫犳垚姝婚攣(key姘镐箙瀛樺湪)

  • value瑕佸叿鏈夊敮涓€鎬?/span>

    杩欎釜鏄负浜嗗湪瑙i攣鐨勬椂鍊欙紝闇€瑕侀獙璇乿alue鏄拰鍔犻攣鐨勪竴鑷存墠鍒犻櫎key銆?/span>

    杩欐槸閬垮厤浜嗕竴绉嶆儏鍐碉細鍋囪A鑾峰彇浜嗛攣锛岃繃鏈熸椂闂?0s锛屾鏃?5s涔嬪悗锛岄攣宸茬粡鑷姩閲婃斁浜嗭紝A鍘婚噴鏀鹃攣锛屼絾鏄鏃跺彲鑳紹鑾峰彇浜嗛攣銆侫瀹㈡埛绔氨涓嶈兘鍒犻櫎B鐨勯攣浜嗐€?/span>

Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵
闄や簡瑕佽€冭檻瀹㈡埛绔鎬庝箞瀹炵幇鍒嗗竷寮忛攣涔嬪锛岃繕闇€瑕佽€冭檻redis鐨勯儴缃查棶棰樸€?/span>
redis鏈?绉嶉儴缃叉柟寮忥細
  • 鍗曟満妯″紡

  • master-slave + sentinel閫変妇妯″紡

  • redis cluster妯″紡


浣跨敤redis鍋氬垎甯冨紡閿佺殑缂虹偣鍦ㄤ簬锛?/span> 濡傛灉閲囩敤鍗曟満閮ㄧ讲妯″紡锛屼細瀛樺湪鍗曠偣闂锛屽彧瑕乺edis鏁呴殰浜嗐€傚姞閿佸氨涓嶈浜嗐€?/span>
閲囩敤master-slave妯″紡锛屽姞閿佺殑鏃跺€欏彧瀵逛竴涓妭鐐瑰姞閿侊紝鍗充究閫氳繃sentinel鍋氫簡楂樺彲鐢紝浣嗘槸濡傛灉master鑺傜偣鏁呴殰浜嗭紝鍙戠敓涓讳粠鍒囨崲锛屾鏃跺氨浼氭湁鍙兘鍑虹幇閿佷涪澶辩殑闂銆?/span>
鍩轰簬浠ヤ笂鐨勮€冭檻锛屽叾瀹瀝edis鐨勪綔鑰呬篃鑰冭檻鍒拌繖涓棶棰橈紝浠栨彁鍑轰簡涓€涓猂edLock鐨勭畻娉曪紝杩欎釜绠楁硶鐨勬剰鎬濆ぇ姒傛槸杩欐牱鐨勶細
鍋囪redis鐨勯儴缃叉ā寮忔槸redis cluster锛屾€诲叡鏈?涓猰aster鑺傜偣锛岄€氳繃浠ヤ笅姝ラ鑾峰彇涓€鎶婇攣锛?/span>
  • 鑾峰彇褰撳墠鏃堕棿鎴筹紝鍗曚綅鏄绉?/span>

  • 杞祦灏濊瘯鍦ㄦ瘡涓猰aster鑺傜偣涓婂垱寤洪攣锛岃繃鏈熸椂闂磋缃緝鐭紝涓€鑸氨鍑犲崄姣

  • 灏濊瘯鍦ㄥぇ澶氭暟鑺傜偣涓婂缓绔嬩竴涓攣锛屾瘮濡?涓妭鐐瑰氨瑕佹眰鏄?涓妭鐐癸紙n / 2 +1锛?/span>

  • 瀹㈡埛绔绠楀缓绔嬪ソ閿佺殑鏃堕棿锛屽鏋滃缓绔嬮攣鐨勬椂闂村皬浜庤秴鏃舵椂闂达紝灏辩畻寤虹珛鎴愬姛浜?/span>

  • 瑕佹槸閿佸缓绔嬪け璐ヤ簡锛岄偅涔堝氨渚濇鍒犻櫎杩欎釜閿?/span>

  • 鍙鍒汉寤虹珛浜嗕竴鎶婂垎甯冨紡閿侊紝浣犲氨寰椾笉鏂疆璇㈠幓灏濊瘯鑾峰彇閿?/span>


浣嗘槸杩欐牱鐨勮繖绉嶇畻娉曡繕鏄鍏蜂簤璁殑锛屽彲鑳借繕浼氬瓨鍦ㄤ笉灏戠殑闂锛屾棤娉曚繚璇佸姞閿佺殑杩囩▼涓€瀹氭纭€?/span>
Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵

鍙︿竴绉嶆柟寮忥細Redisson

姝ゅ锛屽疄鐜癛edis鐨勫垎甯冨紡閿侊紝闄や簡鑷繁鍩轰簬redis client鍘熺敓api鏉ュ疄鐜颁箣澶栵紝杩樺彲浠ヤ娇鐢ㄥ紑婧愭鏋讹細Redission
Redisson鏄竴涓紒涓氱骇鐨勫紑婧怰edis Client锛屼篃鎻愪緵浜嗗垎甯冨紡閿佺殑鏀寔銆傛垜涔熼潪甯告帹鑽愬ぇ瀹朵娇鐢紝涓轰粈涔堝憿锛?/span>
鍥炴兂涓€涓嬩笂闈㈣鐨勶紝濡傛灉鑷繁鍐欎唬鐮佹潵閫氳繃redis璁剧疆涓€涓€硷紝鏄€氳繃涓嬮潰杩欎釜鍛戒护璁剧疆鐨勩€?/span>
  • SET anyLock unique_value NX PX 30000

杩欓噷璁剧疆鐨勮秴鏃舵椂闂存槸30s锛屽亣濡傛垜瓒呰繃30s閮借繕娌℃湁瀹屾垚涓氬姟閫昏緫鐨勬儏鍐典笅锛宬ey浼氳繃鏈燂紝鍏朵粬绾跨▼鏈夊彲鑳戒細鑾峰彇鍒伴攣銆?/span>
杩欐牱涓€鏉ョ殑璇濓紝 绗竴涓嚎绋嬭繕娌℃墽琛屽畬涓氬姟閫昏緫锛岀浜屼釜绾跨▼杩涙潵浜嗕篃浼氬嚭鐜扮嚎绋嬪畨鍏ㄩ棶棰樸€傛墍浠ユ垜浠繕闇€瑕侀澶栫殑鍘荤淮鎶よ繖涓繃鏈熸椂闂达紝澶夯鐑︿簡~
鎴戜滑鏉ョ湅鐪媟edisson鏄€庝箞瀹炵幇鐨勶紵鍏堟劅鍙椾竴涓嬩娇鐢╮edission鐨勭埥锛?/span>
   
     
     
   
Config config =  new Config();
config.useClusterServers()
.addNodeAddress( "redis://192.168.31.101:7001")
.addNodeAddress( "redis://192.168.31.101:7002")
.addNodeAddress( "redis://192.168.31.101:7003")
.addNodeAddress( "redis://192.168.31.102:7001")
.addNodeAddress( "redis://192.168.31.102:7002")
.addNodeAddress( "redis://192.168.31.102:7003");

RedissonClient redisson = Redisson.create(config);


RLock  lock = redisson.getLock( "anyLock");
lock. lock();
lock.unlock();

灏辨槸杩欎箞绠€鍗曪紝鎴戜滑鍙渶瑕侀€氳繃瀹冪殑api涓殑lock鍜寀nlock鍗冲彲瀹屾垚鍒嗗竷寮忛攣锛屼粬甯垜浠€冭檻浜嗗緢澶氱粏鑺傦細
  • redisson鎵€鏈夋寚浠ら兘閫氳繃lua鑴氭湰鎵ц锛宺edis鏀寔lua鑴氭湰鍘熷瓙鎬ф墽琛?/span>

  • redisson璁剧疆涓€涓猭ey鐨勯粯璁よ繃鏈熸椂闂翠负30s,濡傛灉鏌愪釜瀹㈡埛绔寔鏈変竴涓攣瓒呰繃浜?0s鎬庝箞鍔烇紵

    redisson涓湁涓€涓?/span>watchdog鐨勬蹇碉紝缈昏瘧杩囨潵灏辨槸鐪嬮棬鐙楋紝瀹冧細鍦ㄤ綘鑾峰彇閿佷箣鍚庯紝姣忛殧10绉掑府浣犳妸key鐨勮秴鏃舵椂闂磋涓?0s

    杩欐牱鐨勮瘽锛屽氨绠椾竴鐩存寔鏈夐攣涔熶笉浼氬嚭鐜発ey杩囨湡浜嗭紝鍏朵粬绾跨▼鑾峰彇鍒伴攣鐨勯棶棰樹簡銆?/span>

  • redisson鐨勨€滅湅闂ㄧ嫍鈥濋€昏緫淇濊瘉浜嗘病鏈夋閿佸彂鐢熴€?/span>

    (濡傛灉鏈哄櫒瀹曟満浜嗭紝鐪嬮棬鐙椾篃灏辨病浜嗐€傛鏃跺氨涓嶄細寤堕暱key鐨勮繃鏈熸椂闂达紝鍒颁簡30s涔嬪悗灏变細鑷姩杩囨湡浜嗭紝鍏朵粬绾跨▼鍙互鑾峰彇鍒伴攣)

Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵
杩欓噷绋嶅井璐村嚭鏉ュ叾瀹炵幇浠g爜锛?/span>
   
     
     
   
// 鍔犻攣閫昏緫
private <T>  RFuture<Long> tryAcquireAsync(long leaseTime, TimeUnit unit, final long threadId) {
     if (leaseTime != - 1) {
         return tryLockInnerAsync(leaseTime, unit, threadId, RedisCommands.EVAL_LONG);
    }
     // 璋冪敤涓€娈祃ua鑴氭湰锛岃缃竴浜沰ey銆佽繃鏈熸椂闂?/span>
    RFuture<Long> ttlRemainingFuture = tryLockInnerAsync(commandExecutor.getConnectionManager().getCfg().getLockWatchdogTimeout(), TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);
    ttlRemainingFuture.addListener( new FutureListener<Long>() {
         @Override
         public void operationComplete(Future<Long> future) throws Exception {
             if (!future.isSuccess()) {
                 return;
            }

            Long ttlRemaining = future.getNow();
             // lock acquired
             if (ttlRemaining ==  null) {
                 // 鐪嬮棬鐙楅€昏緫
                scheduleExpirationRenewal(threadId);
            }
        }
    });
     return ttlRemainingFuture;
}


<T>  RFuture<T> tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
    internalLockLeaseTime = unit.toMillis(leaseTime);

     return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, command,
               "if (redis.call('exists', KEYS[1]) == 0) then " +
                   "redis.call('hset', KEYS[1], ARGV[2], 1); " +
                   "redis.call('pexpire', KEYS[1], ARGV[1]); " +
                   "return nil; " +
               "end; " +
               "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
                   "redis.call('hincrby', KEYS[1], ARGV[2], 1); " +
                   "redis.call('pexpire', KEYS[1], ARGV[1]); " +
                   "return nil; " +
               "end; " +
               "return redis.call('pttl', KEYS[1]);",
                Collections.<Object>singletonList(getName()), internalLockLeaseTime, getLockName(threadId));
}



// 鐪嬮棬鐙楁渶缁堜細璋冪敤浜嗚繖閲?/span>
private void scheduleExpirationRenewal(final long threadId) {
     if (expirationRenewalMap.containsKey(getEntryName())) {
         return;
    }

     // 杩欎釜浠诲姟浼氬欢杩?0s鎵ц
    Timeout task = commandExecutor.getConnectionManager().newTimeout( new TimerTask() {
         @Override
         public void run(Timeout timeout) throws Exception {

             // 杩欎釜鎿嶄綔浼氬皢key鐨勮繃鏈熸椂闂撮噸鏂拌缃负30s
            RFuture<Boolean> future = renewExpirationAsync(threadId);

            future.addListener( new FutureListener<Boolean>() {
                 @Override
                 public void operationComplete(Future<Boolean> future) throws Exception {
                    expirationRenewalMap.remove(getEntryName());
                     if (!future.isSuccess()) {
                        log.error( "Can't update lock " + getName() +  " expiration", future.cause());
                         return;
                    }

                     if (future.getNow()) {
                         // reschedule itself
                         // 閫氳繃閫掑綊璋冪敤鏈柟娉曪紝鏃犻檺寰幆寤堕暱杩囨湡鏃堕棿
                        scheduleExpirationRenewal(threadId);
                    }
                }
            });
        }

    }, internalLockLeaseTime /  3, TimeUnit.MILLISECONDS);

     if (expirationRenewalMap.putIfAbsent(getEntryName(),  new ExpirationEntry(threadId, task)) !=  null) {
        task.cancel();
    }
}

  
    
    
  
鍙﹀锛宺edisson杩樻彁渚涗簡瀵箁edlock绠楁硶鐨勬敮鎸?
瀹冪殑鐢ㄦ硶涔熷緢绠€鍗曪細
   
     
     
   
    
      
      
    
RedissonClient redisson = Redisson.create(config);
RLock lock1 = redisson.getFairLock( "lock1");
RLock lock2 = redisson.getFairLock( "lock2");
RLock lock3 = redisson.getFairLock( "lock3");
RedissonRedLock multiLock =  new RedissonRedLock(lock1, lock2, lock3);
multiLock. lock();
multiLock.unlock();

灏忕粨锛?/span>

鏈妭鍒嗘瀽浜嗕娇鐢╮edis浣滀负鍒嗗竷寮忛攣鐨勫叿浣撹惤鍦版柟 妗?/span>
浠ュ強 鍏朵竴浜涘眬闄愭€?/span>
鐒跺悗浠嬬粛浜嗕竴涓猺edis鐨勫鎴风妗嗘灦redisson锛?/span>
杩欎篃鏄垜鎺ㄨ崘澶у浣跨敤鐨勶紝
姣旇嚜宸卞啓浠g爜瀹炵幇浼氬皯care寰堝缁嗚妭銆?/span>

鍩轰簬zookeeper瀹炵幇鍒嗗竷寮忛攣


甯歌鐨勫垎甯冨紡閿佸疄鐜版柟妗堥噷闈紝闄や簡浣跨敤redis鏉ュ疄鐜颁箣澶栵紝浣跨敤zookeeper涔熷彲浠ュ疄鐜板垎甯冨紡閿併€?/span>
鍦ㄤ粙缁峼ookeeper(涓嬫枃鐢▃k浠f浛)瀹炵幇鍒嗗竷寮忛攣鐨勬満鍒朵箣鍓嶏紝鍏堢矖鐣ヤ粙缁嶄竴涓媧k鏄粈涔堜笢瑗匡細
Zookeeper鏄竴绉嶆彁渚涢厤缃鐞嗐€佸垎甯冨紡鍗忓悓浠ュ強鍛藉悕鐨勪腑蹇冨寲鏈嶅姟銆?/span>
zk鐨勬ā鍨嬫槸杩欐牱鐨勶細zk鍖呭惈涓€绯诲垪鐨勮妭鐐癸紝鍙仛znode锛屽氨濂藉儚鏂囦欢绯荤粺涓€鏍锋瘡涓獄node琛ㄧず涓€涓洰褰曪紝鐒跺悗znode鏈変竴浜涚壒鎬э細
  • 鏈夊簭鑺傜偣锛氬亣濡傚綋鍓嶆湁涓€涓埗鑺傜偣涓?/span>/lock锛屾垜浠彲浠ュ湪杩欎釜鐖惰妭鐐逛笅闈㈠垱寤哄瓙鑺傜偣锛?/span>

    zookeeper鎻愪緵浜嗕竴涓彲閫夌殑鏈夊簭鐗规€э紝渚嬪鎴戜滑鍙互鍒涘缓瀛愯妭鐐光€?lock/node-鈥濆苟涓旀寚鏄庢湁搴忥紝閭d箞zookeeper鍦ㄧ敓鎴愬瓙鑺傜偣鏃朵細鏍规嵁褰撳墠鐨勫瓙鑺傜偣鏁伴噺鑷姩娣诲姞鏁存暟搴忓彿

    涔熷氨鏄锛屽鏋滄槸绗竴涓垱寤虹殑瀛愯妭鐐癸紝閭d箞鐢熸垚鐨勫瓙鑺傜偣涓?/span>/lock/node-0000000000锛屼笅涓€涓妭鐐瑰垯涓?/span>/lock/node-0000000001锛屼緷娆$被鎺ㄣ€?/span>


  • 涓存椂鑺傜偣锛氬鎴风鍙互寤虹珛涓€涓复鏃惰妭鐐癸紝鍦ㄤ細璇濈粨鏉熸垨鑰呬細璇濊秴鏃跺悗锛寊ookeeper浼氳嚜鍔ㄥ垹闄よ鑺傜偣銆?/span>

  • 浜嬩欢鐩戝惉锛氬湪璇诲彇鏁版嵁鏃讹紝鎴戜滑鍙互鍚屾椂瀵硅妭鐐硅缃簨浠剁洃鍚紝褰撹妭鐐规暟鎹垨缁撴瀯鍙樺寲鏃讹紝zookeeper浼氶€氱煡瀹㈡埛绔€傚綋鍓峼ookeeper鏈夊涓嬪洓绉嶄簨浠讹細

    • 鑺傜偣鍒涘缓

    • 鑺傜偣鍒犻櫎

    • 鑺傜偣鏁版嵁淇敼

    • 瀛愯妭鐐瑰彉鏇?/span>

鍩轰簬浠ヤ笂鐨勪竴浜泎k鐨勭壒鎬э紝鎴戜滑寰堝鏄撳緱鍑轰娇鐢▃k瀹炵幇鍒嗗竷寮忛攣鐨勮惤鍦版柟妗堬細
  1. 浣跨敤zk鐨勪复鏃惰妭鐐瑰拰鏈夊簭鑺傜偣锛屾瘡涓嚎绋嬭幏鍙栭攣灏辨槸鍦▃k鍒涘缓涓€涓复鏃舵湁搴忕殑鑺傜偣锛屾瘮濡傚湪/lock/鐩綍涓嬨€?/span>

  2. 鍒涘缓鑺傜偣鎴愬姛鍚庯紝鑾峰彇/lock鐩綍涓嬬殑鎵€鏈変复鏃惰妭鐐癸紝鍐嶅垽鏂綋鍓嶇嚎绋嬪垱寤虹殑鑺傜偣鏄惁鏄墍鏈夌殑鑺傜偣鐨勫簭鍙锋渶灏忕殑鑺傜偣

  3. 濡傛灉褰撳墠绾跨▼鍒涘缓鐨勮妭鐐规槸鎵€鏈夎妭鐐瑰簭鍙锋渶灏忕殑鑺傜偣锛屽垯璁や负鑾峰彇閿佹垚鍔熴€?/span>

  4. 濡傛灉褰撳墠绾跨▼鍒涘缓鐨勮妭鐐逛笉鏄墍鏈夎妭鐐瑰簭鍙锋渶灏忕殑鑺傜偣锛屽垯瀵硅妭鐐瑰簭鍙风殑鍓嶄竴涓妭鐐规坊鍔犱竴涓簨浠剁洃鍚€?/span>

    姣斿褰撳墠绾跨▼鑾峰彇鍒扮殑鑺傜偣搴忓彿涓?/span>/lock/003,鐒跺悗鎵€鏈夌殑鑺傜偣鍒楄〃涓?/span>[/lock/001,/lock/002,/lock/003],鍒欏/lock/002杩欎釜鑺傜偣娣诲姞涓€涓簨浠剁洃鍚櫒銆?/span>


濡傛灉閿侀噴鏀句簡锛屼細鍞ら啋涓嬩竴涓簭鍙风殑鑺傜偣锛岀劧鍚庨噸鏂版墽琛岀3姝ワ紝鍒ゆ柇鏄惁鑷繁鐨勮妭鐐瑰簭鍙锋槸鏈€灏忋€?/span>
姣斿 /lock/001 閲婃斁浜嗭紝 /lock/002 鐩戝惉鍒版椂闂达紝姝ゆ椂鑺傜偣闆嗗悎涓?/span> [/lock/002,/lock/003] ,鍒?/span> /lock/002 涓烘渶灏忓簭鍙疯妭鐐癸紝鑾峰彇鍒伴攣銆?/span>

鏁翠釜杩囩▼濡備笅锛?/span>
Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵
鍏蜂綋鐨勫疄鐜版€濊矾灏辨槸杩欐牱锛岃嚦浜庝唬鐮佹€庝箞鍐欙紝杩欓噷姣旇緝澶嶆潅灏变笉璐村嚭鏉ヤ簡銆?/span>

Curator浠嬬粛

Curator鏄竴涓獄ookeeper鐨勫紑婧愬鎴风锛屼篃鎻愪緵浜嗗垎甯冨紡閿佺殑瀹炵幇銆?/span>
浠栫殑浣跨敤鏂瑰紡涔熸瘮杈冪畝鍗曪細
  
    
    
  
InterProcessMutex interProcessMutex =  new InterProcessMutex(client, "/anyLock");
interProcessMutex.acquire();
interProcessMutex.release();

鍏跺疄鐜板垎甯冨紡閿佺殑鏍稿績婧愮爜濡備笅锛?/span>

  
    
    
  
private boolean internalLockLoop(long startMillis, Long millisToWait, String ourPath) throws Exception
{
     boolean  haveTheLock =  false;
     boolean  doDelete =  false;
     try {
         if ( revocable.get() !=  null ) {
            client.getData().usingWatcher(revocableWatcher).forPath(ourPath);
        }

         while ( (client.getState() == CuratorFrameworkState.STARTED) && !haveTheLock ) {
             // 鑾峰彇褰撳墠鎵€鏈夎妭鐐规帓搴忓悗鐨勯泦鍚?/span>
            List<String>        children = getSortedChildren();
             // 鑾峰彇褰撳墠鑺傜偣鐨勫悕绉?/span>
            String              sequenceNodeName = ourPath.substring(basePath.length() +  1);  // +1 to include the slash
             // 鍒ゆ柇褰撳墠鑺傜偣鏄惁鏄渶灏忕殑鑺傜偣
            PredicateResults    predicateResults = driver.getsTheLock(client, children, sequenceNodeName, maxLeases);
             if ( predicateResults.getsTheLock() ) {
                 // 鑾峰彇鍒伴攣
                haveTheLock =  true;
            }  else {
                 // 娌¤幏鍙栧埌閿侊紝瀵瑰綋鍓嶈妭鐐圭殑涓婁竴涓妭鐐规敞鍐屼竴涓洃鍚櫒
                String  previousSequencePath = basePath +  "/" + predicateResults.getPathToWatch();
                 synchronized( this){
                    Stat stat = client.checkExists().usingWatcher(watcher).forPath(previousSequencePath);
                     if ( stat !=  null ){
                         if ( millisToWait !=  null ){
                            millisToWait -= (System.currentTimeMillis() - startMillis);
                            startMillis = System.currentTimeMillis();
                             if ( millisToWait <=  0 ){
                                doDelete =  true;     // timed out - delete our node
                                 break;
                            }
                            wait(millisToWait);
                        } else{
                            wait();
                        }
                    }
                }
                 // else it may have been deleted (i.e. lock released). Try to acquire again
            }
        }
    }
     catch ( Exception e ) {
        doDelete =  true;
         throw e;
    }  finally{
         if ( doDelete ){
            deleteOurPath(ourPath);
        }
    }
     return haveTheLock;
}

鍏?/span> 瀹瀋urator瀹炵幇鍒嗗竷寮忛攣鐨勫簳灞傚師鐞嗗拰涓婇潰鍒嗘瀽鐨勬槸宸笉澶氱殑銆?/span> 杩欓噷鎴戜滑鐢ㄤ竴寮犲浘璇︾粏鎻忚堪鍏跺師鐞嗭細
Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵
灏忕粨锛?/span>
鏈妭浠嬬粛浜唞ookeeperr瀹炵幇鍒嗗竷寮忛攣鐨勬柟妗堜互鍙妟k鐨勫紑婧愬鎴风鐨勫熀鏈娇鐢紝绠€瑕佺殑浠嬬粛浜嗗叾瀹炵幇鍘熺悊銆傜浉鍏冲彲浠ュ弬鑰冿細

涓ょ鏂规鐨勪紭缂虹偣姣旇緝

瀛﹀畬浜嗕袱绉嶅垎甯冨紡閿佺殑瀹炵幇鏂规涔嬪悗锛屾湰鑺傞渶瑕佽璁虹殑鏄痳edis鍜寊k鐨勫疄鐜版柟妗堜腑鍚勮嚜鐨勪紭缂虹偣銆?/span>
瀵逛簬redis鐨勫垎甯冨紡閿佽€岃█锛屽畠鏈変互涓嬬己鐐癸細
  • 瀹冭幏鍙栭攣鐨勬柟寮忕畝鍗曠矖鏆达紝鑾峰彇涓嶅埌閿佺洿鎺ヤ笉鏂皾璇曡幏鍙栭攣锛屾瘮杈冩秷鑰楁€ц兘銆?/span>

  • 鍙﹀鏉ヨ鐨勮瘽锛宺edis鐨勮璁″畾浣嶅喅瀹氫簡瀹冪殑鏁版嵁骞朵笉鏄己涓€鑷存€х殑锛屽湪鏌愪簺鏋佺鎯呭喌涓嬶紝鍙兘浼氬嚭鐜伴棶棰樸€傞攣鐨勬ā鍨嬩笉澶熷仴澹?/span>

  • 鍗充究浣跨敤redlock绠楁硶鏉ュ疄鐜帮紝鍦ㄦ煇浜涘鏉傚満鏅笅锛屼篃鏃犳硶淇濊瘉鍏跺疄鐜?00%娌℃湁闂锛屽叧浜巖edlock鐨勮璁哄彲浠ョ湅How to do distributed locking

  • redis鍒嗗竷寮忛攣锛屽叾瀹為渶瑕佽嚜宸变笉鏂幓灏濊瘯鑾峰彇閿侊紝姣旇緝娑堣€楁€ц兘銆?/span>


浣嗘槸鍙︿竴鏂归潰浣跨敤redis瀹炵幇鍒嗗竷寮忛攣鍦ㄥ緢澶氫紒涓氫腑闈炲父甯歌锛岃€屼笖澶ч儴鍒嗘儏鍐典笅閮戒笉浼氶亣鍒版墍璋撶殑鈥滄瀬绔鏉傚満鏅€?/span>
鎵€浠ヤ娇鐢╮edis浣滀负鍒嗗竷寮忛攣涔熶笉澶变负涓€绉嶅ソ鐨勬柟妗堬紝鏈€閲嶈鐨勪竴鐐规槸redis鐨勬€ц兘寰堥珮锛屽彲浠ユ敮鎾戦珮骞跺彂鐨勮幏鍙栥€侀噴鏀鹃攣鎿嶄綔銆?/span>

瀵逛簬zk鍒嗗竷寮忛攣鑰岃█:
  • zookeeper澶╃敓璁捐瀹氫綅灏辨槸鍒嗗竷寮忓崗璋冿紝寮轰竴鑷存€с€傞攣鐨勬ā鍨嬪仴澹€佺畝鍗曟槗鐢ㄣ€侀€傚悎鍋氬垎甯冨紡閿併€?/span>

  • 濡傛灉鑾峰彇涓嶅埌閿侊紝鍙渶瑕佹坊鍔犱竴涓洃鍚櫒灏卞彲浠ヤ簡锛屼笉鐢ㄤ竴鐩磋疆璇紝鎬ц兘娑堣€楄緝灏忋€?/span>


浣嗘槸zk涔熸湁鍏剁己鐐癸細 濡?/span> 鏋滄湁杈冨鐨勫鎴风棰戠箒鐨勭敵璇峰姞閿併€侀噴鏀鹃攣锛屽浜巣k闆嗙兢鐨勫帇鍔涗細姣旇緝澶с€?/span>

灏忕粨锛?/span>
缁间笂鎵€杩帮紝redis鍜寊ookeeper閮芥湁鍏朵紭缂虹偣銆傛垜浠湪鍋氭妧鏈€夊瀷鐨勬椂鍊欏彲浠ユ牴鎹繖浜涢棶棰樹綔涓哄弬鑰冨洜绱犮€?/span>

寤鸿

閫氳繃鍓嶉潰鐨勫垎鏋愶紝瀹炵幇鍒嗗竷寮忛攣鐨勪袱绉嶅父瑙佹柟妗堬細redis鍜寊ookeeper锛屼粬浠悇鏈夊崈绉嬨€傚簲璇ュ浣曢€夊瀷鍛紵
灏变釜浜鸿€岃█鐨勮瘽锛?span>鎴戞瘮杈冩帹宕噝k瀹炵幇鐨勯攣锛?/strong>
鍥犱负redis鏄湁鍙兘瀛樺湪闅愭偅鐨勶紝鍙兘浼氬鑷存暟鎹笉瀵圭殑鎯呭喌銆備絾鏄紝鎬庝箞閫夌敤瑕佺湅鍏蜂綋鍦ㄥ叕鍙哥殑鍦烘櫙浜嗐€?/span>
濡傛灉鍏徃閲岄潰鏈墇k闆嗙兢鏉′欢锛屼紭鍏堥€夌敤zk瀹炵幇锛屼絾鏄鏋滆鍏徃閲岄潰鍙湁redis闆嗙兢锛屾病鏈夋潯浠舵惌寤簔k闆嗙兢銆?/span>
閭d箞鍏跺疄鐢╮edis鏉ュ疄鐜颁篃鍙互锛屽彟澶栬繕鍙兘鏄郴缁熻璁¤€呰€冭檻鍒颁簡绯荤粺宸茬粡鏈塺edis锛屼絾鏄張涓嶅笇鏈涘啀娆″紩鍏ヤ竴浜涘閮ㄤ緷璧栫殑鎯呭喌涓嬶紝鍙互閫夌敤redis銆?/span>
杩欎釜鏄绯荤粺璁捐鑰呭熀浜庢灦鏋勭殑鑰冭檻浜?/span>

 鍐欏湪鏈€鍚庯細

 鏈€鍚庣粰璇昏€呮暣鐞嗕簡涓€浠藉ぇ鍘傞潰璇曠湡棰橈紝闇€瑕佺殑鍙壂鐮佸洖澶嶁€?span class="mq-578">澶у巶闈㈣瘯鈥濊幏鍙栥€?/p>

Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵

Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵

         
           
           
         



END


鍚庡彴鍥炲鈥?/span>闈㈣瘯鈥?nbsp;鈥滆祫鏂欌€?nbsp;棰嗗彇涓€浠藉共璐э紝鏁扮櫨鎶€鏈潰璇曟墜鍐岀瓑浣?/span>
寮€鍙戣€呮妧鏈墠绾?锛屾眹闆嗘妧鏈墠绾垮揩璁拰鍏虫敞琛屼笟瓒嬪娍锛屽ぇ鍘傚共璐э紝鏄紑鍙戣€呯粡鍘嗗拰鎴愰暱鐨勪紭绉€鎸囧崡 銆?/span>
鍘嗗彶鎺ㄨ崘





Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵
Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵
濂芥枃鐐逛釜鍦ㄧ湅鍚э紒

以上是关于Redis 鍜?Zookeeper 鍒板簳璋佹洿鐗涳紵的主要内容,如果未能解决你的问题,请参考以下文章

fastjson鍒板簳鍋氶敊浜嗕粈涔堬紵涓轰粈涔堜細琚绻佺垎鍑烘紡娲烇紵

浣庝唬鐮佸紑鍙戝钩鍙板垎鏋愶紝鎴戜滑鍒板簳闇€瑕佷粈涔堟牱鐨勪綆浠g爜骞冲彴

Redis 鍜?Memcached 鐨勫尯鍒?Tair

涓€鏂囧甫浣犱簡瑙ue涔嬭櫄鎷焏om

鎺㈢储STL锛氬爢鏁版嵁缁撴瀯鍙婄畻娉?/h1>