<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jinfeng_wang

    G-G-S,D-D-U!

    BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
      400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
    http://www.cnblogs.com/leesf456/p/6103870.html


    一、前言

      前面分析了Zookeeper客戶端的細(xì)節(jié),接著繼續(xù)學(xué)習(xí)Zookeeper中的一個(gè)非常重要的概念:會(huì)話。

    二、會(huì)話

      客戶端與服務(wù)端之間任何交互操作都與會(huì)話息息相關(guān),如臨時(shí)節(jié)點(diǎn)的生命周期、客戶端請(qǐng)求的順序執(zhí)行、Watcher通知機(jī)制等。Zookeeper的連接與會(huì)話就是客戶端通過(guò)實(shí)例化Zookeeper對(duì)象來(lái)實(shí)現(xiàn)客戶端與服務(wù)端創(chuàng)建并保持TCP連接的過(guò)程.

      2.1 會(huì)話狀態(tài)

      在Zookeeper客戶端與服務(wù)端成功完成連接創(chuàng)建后,就創(chuàng)建了一個(gè)會(huì)話,Zookeeper會(huì)話在整個(gè)運(yùn)行期間的生命周期中,會(huì)在不同的會(huì)話狀態(tài)中之間進(jìn)行切換,這些狀態(tài)可以分為CONNECTING、CONNECTED、RECONNECTING、RECONNECTED、CLOSE等。

      一旦客戶端開(kāi)始創(chuàng)建Zookeeper對(duì)象,那么客戶端狀態(tài)就會(huì)變成CONNECTING狀態(tài),同時(shí)客戶端開(kāi)始嘗試連接服務(wù)端,連接成功后,客戶端狀態(tài)變?yōu)镃ONNECTED,通常情況下,由于斷網(wǎng)或其他原因,客戶端與服務(wù)端之間會(huì)出現(xiàn)斷開(kāi)情況,一旦碰到這種情況,Zookeeper客戶端會(huì)自動(dòng)進(jìn)行重連服務(wù),同時(shí)客戶端狀態(tài)再次變成CONNCTING,直到重新連上服務(wù)端后,狀態(tài)又變?yōu)镃ONNECTED,在通常情況下,客戶端的狀態(tài)總是介于CONNECTING和CONNECTED之間。但是,如果出現(xiàn)諸如會(huì)話超時(shí)、權(quán)限檢查或是客戶端主動(dòng)退出程序等情況,客戶端的狀態(tài)就會(huì)直接變更為CLOSE狀態(tài)。

      2.2 會(huì)話創(chuàng)建

      Session是Zookeeper中的會(huì)話實(shí)體,代表了一個(gè)客戶端會(huì)話,其包含了如下四個(gè)屬性

      1. sessionID。會(huì)話ID,唯一標(biāo)識(shí)一個(gè)會(huì)話,每次客戶端創(chuàng)建新的會(huì)話時(shí),Zookeeper都會(huì)為其分配一個(gè)全局唯一的sessionID。

      2. TimeOut。會(huì)話超時(shí)時(shí)間,客戶端在構(gòu)造Zookeeper實(shí)例時(shí),會(huì)配置sessionTimeout參數(shù)用于指定會(huì)話的超時(shí)時(shí)間,Zookeeper客戶端向服務(wù)端發(fā)送這個(gè)超時(shí)時(shí)間后,服務(wù)端會(huì)根據(jù)自己的超時(shí)時(shí)間限制最終確定會(huì)話的超時(shí)時(shí)間。

      3. TickTime。下次會(huì)話超時(shí)時(shí)間點(diǎn),為了便于Zookeeper對(duì)會(huì)話實(shí)行"分桶策略"管理,同時(shí)為了高效低耗地實(shí)現(xiàn)會(huì)話的超時(shí)檢查與清理,Zookeeper會(huì)為每個(gè)會(huì)話標(biāo)記一個(gè)下次會(huì)話超時(shí)時(shí)間點(diǎn),其值大致等于當(dāng)前時(shí)間加上TimeOut。

      4. isClosing。標(biāo)記一個(gè)會(huì)話是否已經(jīng)被關(guān)閉,當(dāng)服務(wù)端檢測(cè)到會(huì)話已經(jīng)超時(shí)失效時(shí),會(huì)將該會(huì)話的isClosing標(biāo)記為"已關(guān)閉",這樣就能確保不再處理來(lái)自該會(huì)話的心情求了。

      Zookeeper為了保證請(qǐng)求會(huì)話的全局唯一性,在SessionTracker初始化時(shí),調(diào)用initializeNextSession方法生成一個(gè)sessionID,之后在Zookeeper運(yùn)行過(guò)程中,會(huì)在該sessionID的基礎(chǔ)上為每個(gè)會(huì)話進(jìn)行分配,初始化算法如下

    復(fù)制代碼
    public static long initializeNextSession(long id) {     long nextSid = 0;     // 無(wú)符號(hào)右移8位使為了避免左移24后,再右移8位出現(xiàn)負(fù)數(shù)而無(wú)法通過(guò)高8位確定sid值     nextSid = (System.currentTimeMillis() << 24) >>> 8;     nextSid = nextSid | (id << 56);     return nextSid; }
    復(fù)制代碼

      其中的id表示配置在myid文件中的值,通常是一個(gè)整數(shù),如1、2、3。該算法的高8位確定了所在機(jī)器,后56位使用當(dāng)前時(shí)間的毫秒表示進(jìn)行隨機(jī)。SessionTracker是Zookeeper服務(wù)端的會(huì)話管理器,負(fù)責(zé)會(huì)話的創(chuàng)建、管理和清理等工作。

      2.3 會(huì)話管理

      Zookeeper的會(huì)話管理主要是通過(guò)SessionTracker來(lái)負(fù)責(zé),其采用了分桶策略(將類似的會(huì)話放在同一區(qū)塊中進(jìn)行管理)進(jìn)行管理,以便Zookeeper對(duì)會(huì)話進(jìn)行不同區(qū)塊的隔離處理以及同一區(qū)塊的統(tǒng)一處理。

      Zookeeper將所有的會(huì)話都分配在不同的區(qū)塊一種,分配的原則是每個(gè)會(huì)話的下次超時(shí)時(shí)間點(diǎn)(ExpirationTime)。ExpirationTime指該會(huì)話最近一次可能超時(shí)的時(shí)間點(diǎn)。同時(shí),Zookeeper Leader服務(wù)器在運(yùn)行過(guò)程中會(huì)定時(shí)地進(jìn)行會(huì)話超時(shí)檢查,時(shí)間間隔是ExpirationInterval,默認(rèn)為tickTime的值,ExpirationTime的計(jì)算時(shí)間如下

      ExpirationTime = ((CurrentTime + SessionTimeOut) / ExpirationInterval + 1) * ExpirationInterval

      會(huì)了保持客戶端會(huì)話的有效性,客戶端會(huì)在會(huì)話超時(shí)時(shí)間過(guò)期范圍內(nèi)向服務(wù)端發(fā)送PING請(qǐng)求來(lái)保持會(huì)話的有效性(心跳檢測(cè))。同時(shí),服務(wù)端需要不斷地接收來(lái)自客戶端的心跳檢測(cè),并且需要重新激活對(duì)應(yīng)的客戶端會(huì)話,這個(gè)重新激活過(guò)程稱為TouchSession。會(huì)話激活不僅能夠使服務(wù)端檢測(cè)到對(duì)應(yīng)客戶端的存貨性,同時(shí)也能讓客戶端自己保持連接狀態(tài),其流程如下  


      如上圖所示,整個(gè)流程分為四步

      1. 檢查該會(huì)話是否已經(jīng)被關(guān)閉。若已經(jīng)被關(guān)閉,則直接返回即可。

      2. 計(jì)算該會(huì)話新的超時(shí)時(shí)間ExpirationTime_New。使用上面提到的公式計(jì)算下一次超時(shí)時(shí)間點(diǎn)。

      3. 獲取該會(huì)話上次超時(shí)時(shí)間ExpirationTime_Old。計(jì)算該值是為了定位其所在的區(qū)塊。

      3. 遷移會(huì)話。將該會(huì)話從老的區(qū)塊中取出,放入ExpirationTime_New對(duì)應(yīng)的新區(qū)塊中。

      在上面會(huì)話激活過(guò)程中,只要客戶端發(fā)送心跳檢測(cè),服務(wù)端就會(huì)進(jìn)行一次會(huì)話激活,心跳檢測(cè)由客戶端主動(dòng)發(fā)起,以PING請(qǐng)求形式向服務(wù)端發(fā)送,在Zookeeper的實(shí)際設(shè)計(jì)中,只要客戶端有請(qǐng)求發(fā)送到服務(wù)端,那么就會(huì)觸發(fā)一次會(huì)話激活,以下兩種情況都會(huì)觸發(fā)會(huì)話激活。

      1. 客戶端向服務(wù)端發(fā)送請(qǐng)求,包括讀寫請(qǐng)求,就會(huì)觸發(fā)會(huì)話激活。

      2. 客戶端發(fā)現(xiàn)在sessionTimeout/3時(shí)間內(nèi)尚未和服務(wù)端進(jìn)行任何通信,那么就會(huì)主動(dòng)發(fā)起PING請(qǐng)求,服務(wù)端收到該請(qǐng)求后,就會(huì)觸發(fā)會(huì)話激活。

      對(duì)于會(huì)話的超時(shí)檢查而言,Zookeeper使用SessionTracker來(lái)負(fù)責(zé),SessionTracker使用單獨(dú)的線程(超時(shí)檢查線程)專門進(jìn)行會(huì)話超時(shí)檢查,即逐個(gè)一次地對(duì)會(huì)話桶中剩下的會(huì)話進(jìn)行清理。如果一個(gè)會(huì)話被激活,那么Zookeeper就會(huì)將其從上一個(gè)會(huì)話桶遷移到下一個(gè)會(huì)話桶中,如ExpirationTime 1 的session n 遷移到ExpirationTime n 中,此時(shí)ExpirationTime 1中留下的所有會(huì)話都是尚未被激活的,超時(shí)檢查線程就定時(shí)檢查這個(gè)會(huì)話桶中所有剩下的未被遷移的會(huì)話,超時(shí)檢查線程只需要在這些指定時(shí)間點(diǎn)(ExpirationTime 1、ExpirationTime 2...)上進(jìn)行檢查即可,這樣提高了檢查的效率,性能也非常好。

      2.4 會(huì)話清理

      當(dāng)SessionTracker的會(huì)話超時(shí)線程檢查出已經(jīng)過(guò)期的會(huì)話后,就開(kāi)始進(jìn)行會(huì)話清理工作,大致可以分為如下七步。

      1. 標(biāo)記會(huì)話狀態(tài)為已關(guān)閉。由于會(huì)話清理過(guò)程需要一段時(shí)間,為了保證在此期間不再處理來(lái)自該客戶端的請(qǐng)求,SessionTracker會(huì)首先將該會(huì)話的isClosing標(biāo)記為true,這樣在會(huì)話清理期間接收到該客戶端的心情求也無(wú)法繼續(xù)處理了。

      2. 發(fā)起會(huì)話關(guān)閉請(qǐng)求。為了使對(duì)該會(huì)話的關(guān)閉操作在整個(gè)服務(wù)端集群都生效,Zookeeper使用了提交會(huì)話關(guān)閉請(qǐng)求的方式,并立即交付給PreRequestProcessor進(jìn)行處理。

      3. 收集需要清理的臨時(shí)節(jié)點(diǎn)。一旦某個(gè)會(huì)話失效后,那么和該會(huì)話相關(guān)的臨時(shí)節(jié)點(diǎn)都需要被清理,因此,在清理之前,首先需要將服務(wù)器上所有和該會(huì)話相關(guān)的臨時(shí)節(jié)點(diǎn)都整理出來(lái)。Zookeeper在內(nèi)存數(shù)據(jù)庫(kù)中會(huì)為每個(gè)會(huì)話都單獨(dú)保存了一份由該會(huì)話維護(hù)的所有臨時(shí)節(jié)點(diǎn)集合,在Zookeeper處理會(huì)話關(guān)閉請(qǐng)求之前,若正好有以下兩類請(qǐng)求到達(dá)了服務(wù)端并正在處理中。

        · 節(jié)點(diǎn)刪除請(qǐng)求,刪除的目標(biāo)節(jié)點(diǎn)正好是上述臨時(shí)節(jié)點(diǎn)中的一個(gè)。

        · 臨時(shí)節(jié)點(diǎn)創(chuàng)建請(qǐng)求,創(chuàng)建的目標(biāo)節(jié)點(diǎn)正好是上述臨時(shí)節(jié)點(diǎn)中的一個(gè)。

      對(duì)于第一類請(qǐng)求,需要將所有請(qǐng)求對(duì)應(yīng)的數(shù)據(jù)節(jié)點(diǎn)路徑從當(dāng)前臨時(shí)節(jié)點(diǎn)列表中移出,以避免重復(fù)刪除,對(duì)于第二類請(qǐng)求,需要將所有這些請(qǐng)求對(duì)應(yīng)的數(shù)據(jù)節(jié)點(diǎn)路徑添加到當(dāng)前臨時(shí)節(jié)點(diǎn)列表中,以刪除這些即將被創(chuàng)建但是尚未保存到內(nèi)存數(shù)據(jù)庫(kù)中的臨時(shí)節(jié)點(diǎn)。

      4. 添加節(jié)點(diǎn)刪除事務(wù)變更。完成該會(huì)話相關(guān)的臨時(shí)節(jié)點(diǎn)收集后,Zookeeper會(huì)逐個(gè)將這些臨時(shí)節(jié)點(diǎn)轉(zhuǎn)換成"節(jié)點(diǎn)刪除"請(qǐng)求,并放入事務(wù)變更隊(duì)列outstandingChanges中。

      5. 刪除臨時(shí)節(jié)點(diǎn)。FinalRequestProcessor會(huì)觸發(fā)內(nèi)存數(shù)據(jù)庫(kù),刪除該會(huì)話對(duì)應(yīng)的所有臨時(shí)節(jié)點(diǎn)。

      6. 移除會(huì)話。完成節(jié)點(diǎn)刪除后,需要將會(huì)話從SessionTracker中刪除。

      7. 關(guān)閉NIOServerCnxn。最后,從NIOServerCnxnFactory找到該會(huì)話對(duì)應(yīng)的NIOServerCnxn,將其關(guān)閉。

      2.5 重連

      當(dāng)客戶端與服務(wù)端之間的網(wǎng)絡(luò)連接斷開(kāi)時(shí),Zookeeper客戶端會(huì)自動(dòng)進(jìn)行反復(fù)的重連,直到最終成功連接上Zookeeper集群中的一臺(tái)機(jī)器。此時(shí),再次連接上服務(wù)端的客戶端有可能處于以下兩種狀態(tài)之一

      1. CONNECTED。如果在會(huì)話超時(shí)時(shí)間內(nèi)重新連接上集群中一臺(tái)服務(wù)器 。

      2. EXPIRED。如果在會(huì)話超時(shí)時(shí)間以外重新連接上,那么服務(wù)端其實(shí)已經(jīng)對(duì)該會(huì)話進(jìn)行了會(huì)話清理操作,此時(shí)會(huì)話被視為非法會(huì)話。

      在客戶端與服務(wù)端之間維持的是一個(gè)長(zhǎng)連接,在sessionTimeout時(shí)間內(nèi),服務(wù)端會(huì)不斷地檢測(cè)該客戶端是否還處于正常連接,服務(wù)端會(huì)將客戶端的每次操作視為一次有效的心跳檢測(cè)來(lái)反復(fù)地進(jìn)行會(huì)話激活。因此,在正常情況下,客戶端會(huì)話時(shí)一直有效的。然而,當(dāng)客戶端與服務(wù)端之間的連接斷開(kāi)后,用戶在客戶端可能主要看到兩類異常:CONNECTION_LOSS(連接斷開(kāi))和SESSION_EXPIRED(會(huì)話過(guò)期)

      1. CONNECTION_LOSS。此時(shí),客戶端會(huì)自動(dòng)從地址列表中重新逐個(gè)選取新的地址并嘗試進(jìn)行重新連接,直到最終成功連接上服務(wù)器。若客戶端在setData時(shí)出現(xiàn)了CONNECTION_LOSS現(xiàn)象,此時(shí)客戶端會(huì)收到None-Disconnected通知,同時(shí)會(huì)拋出異常。應(yīng)用程序需要捕捉異常并且等待Zookeeper客戶端自動(dòng)完成重連,一旦重連成功,那么客戶端會(huì)收到None-SyncConnected通知,之后就可以重試setData操作。

      2. SESSION_EXPIRED。客戶端與服務(wù)端斷開(kāi)連接后,重連時(shí)間耗時(shí)太長(zhǎng),超過(guò)了會(huì)話超時(shí)時(shí)間限制后沒(méi)有成功連上服務(wù)器,服務(wù)器會(huì)進(jìn)行會(huì)話清理,此時(shí),客戶端不知道會(huì)話已經(jīng)失效,狀態(tài)還是DISCONNECTED,如果客戶端重新連上了服務(wù)器,此時(shí)狀態(tài)為SESSION_EXPIRED,用于需要重新實(shí)例化Zookeeper對(duì)象,并且看應(yīng)用的復(fù)雜情況,重新恢復(fù)臨時(shí)數(shù)據(jù)。

      3. SESSION_MOVED。客戶端會(huì)話從一臺(tái)服務(wù)器轉(zhuǎn)移到另一臺(tái)服務(wù)器,即客戶端與服務(wù)端S1斷開(kāi)連接后,重連上了服務(wù)端S2,此時(shí)會(huì)話就從S1轉(zhuǎn)移到了S2。當(dāng)多個(gè)客戶端使用相同的sessionId/sessionPasswd創(chuàng)建會(huì)話時(shí),會(huì)收到SessionMovedException異常。因?yàn)橐坏┯械诙€(gè)客戶端連接上了服務(wù)端,就被認(rèn)為是會(huì)話轉(zhuǎn)移了。

    三、總結(jié)

      本篇博文介紹了Zookeeper會(huì)話的相關(guān)細(xì)節(jié),通過(guò)本篇的學(xué)習(xí)理解了會(huì)話的細(xì)節(jié),也謝謝各位園友的觀看~

    posted on 2016-12-27 14:05 jinfeng_wang 閱讀(149) 評(píng)論(0)  編輯  收藏 所屬分類: 2016-zookeeper
    主站蜘蛛池模板: avtt亚洲天堂| 亚洲成a人在线看天堂无码| 亚洲国产成人久久精品影视| 国产免费区在线观看十分钟| 亚洲欧洲中文日韩久久AV乱码| 国产亚洲精品2021自在线| 国产成人精品免费直播| 曰批全过程免费视频免费看 | 免费一级毛片不卡在线播放| 久久亚洲AV成人无码国产电影| 巨胸喷奶水视频www网免费| 亚洲人成电影网站久久| 全免费a级毛片免费看不卡| 亚洲αⅴ无码乱码在线观看性色| 国产传媒在线观看视频免费观看| 国产精品观看在线亚洲人成网| 亚洲AV无码之日韩精品| 你懂的在线免费观看| 无码专区—VA亚洲V天堂| 18未年禁止免费观看| 亚洲一区二区三区91| 国产男女猛烈无遮挡免费视频网站 | 国产亚洲精品仙踪林在线播放| 亚洲精品无码99在线观看| 中文字幕乱码一区二区免费| 亚洲综合激情九月婷婷| 狠狠久久永久免费观看| 精品国产污污免费网站入口在线| 亚洲av日韩av激情亚洲| 成熟女人牲交片免费观看视频| 美女一级毛片免费观看| 亚洲AV无码AV男人的天堂| 91麻豆最新在线人成免费观看 | 九九综合VA免费看| 亚洲男人第一av网站| 狼友av永久网站免费观看| a毛片免费观看完整| 亚洲一区二区三区丝袜| 亚洲一区二区三区影院 | 毛片免费全部免费观看| 搜日本一区二区三区免费高清视频|