中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

確保zookeeper一定收到通知消息的方法

發布時間:2020-07-14 21:44:13 來源:網絡 閱讀:1733 作者:myxxdyl 欄目:開發技術

  zookeeper能夠同步同步各節點的znode數據,client可以使用getChildren,getData,exists方法在znode tree路徑上設置watch,當watch路徑上發生節點create、delete、update的時候,會通知到client。client可以得到通知后,再獲取數據,執行業務邏輯操作。

  但是因為沒有消息接收后的確認機制,這個通知機制是不可靠的,也就是說znode的修改者并不知道是否所有的client都被通知到了,或者說client也不知道自己是否錯過了哪些通知消息。這種現象可能由網絡原因引起,也可能是client剛觸發了watch事件,還沒有來得及重新設置watch,下個事件就發生了(zookeeper只提供了一次性watch)。

  在筆者的使用場景中,這是有問題的。在我們分布式配置管理的場景中,有3份配置副本,管理節點本地數據庫中有一份,zookeeper中保存了一份,使用配置的軟件引擎進程中保存了一份。當下發配置時,是需要全部軟件引擎都生效最新的配置,而如果有某個引擎錯過了通知,那么就會漏掉某個配置,導致問題,而到底誰沒有成功生效,這些節點都不知道,甚至錯過通知的節點自身也不知道。

  因此我提出一種設計,至少讓錯過通知的節點自身知道錯過了消息,并采取主動同步配置的方式,來補救。這樣能夠保證,配置下發后,至少一段時間后所有軟件引擎的都使用了最新的配置。

  這利用了zookeeper自身的幾個特性:

  1)zookeeper維護一個全局的操作id,zxid,每一個create,delete,update操作都會使該id加1。

  2)zookeeper為每個路徑(znode)節點都保存了它的修改版本dataversion,和最新一次修改zxid——mzxid。

  3)zookeeper保證每個client連接的session中,看到的通知順序與這些事件發生的先后順序是嚴格一致的。

  我們來假設要在/group/policy下增加、刪除、修改配置,每個配置有1個節點,配置數量可以很多、而且不固定。client要知道增加了什么配置,修改了什么,刪除了什么配置,因此設定了watch。其中A復雜修改這些配置,N1,N2,...Nm這些節點監聽通知,并更新軟件引擎的變量,使其生效配置。

  首先A在/group/policy下做create、delete、update操作后,都要set 一次 /group/policy節點。這會導致/group/policy的dataversion加1。并且可以知道有幾次操作,dataversion就增加幾。

  偽代碼如下:

  doSomeOperion();

  setData("/group/policy","")

  Ni節點要對/group/policy下節點發生修改的事件進行watch,還要對/group/policy節點自身的修改進行watch。因此如果Ni沒有錯過通知的話,它將一次觸發兩個通知:1)配置變化通知;2)/group/policy數據更新通知。

  Ni要在本地保存三個變量current_dataversion,current_zxid

  在Ni client初始化時:

  current_dataversion=/group/policy的dataversion;

  current_zxid=/group/policy的mzxid;

  然后在watch到配置發生變化的回調函數中:

   doSometing(); //生效具體配置

   current_dataversion += 1; //期待/group/policy的下一個dataversion增加1

  在watch到/group/policy的數據發生變化后回調函數中:

   if current_dataversion == /group/policy的dataversion: //意味著沒有漏掉消息

      current_zxid = /group/policy的mzxid

   elif next_dataversion < /group/policy的dataversion: //一位置有配置變化的消息沒有收到

      遍歷/group/policy子節點

        if /group/policy/znodei的mzxid > current_zxid:

          使用znodei中的配置。

      刪除已經不存在znode的配置項;

     同步完成;

     next_dataversion = /group/policy的dataversion

     current_zxid = /group/policy的mzxid

  這樣就可以保證client能夠發現自己錯過了消息,并發現哪些znode的修改被自己錯過了。那么至少在下一次發生修改配置后,client能夠完全與當前配置一致。

  我們可以寫一個場景驗證下:

  初始時/group/policy下為空,/group/policy的stat為(mzxid=2,dataversion=0)

 

    current_dataversion=0;
    current_zxid=2
 1)create /group/policy/n1(mzxid=3,dataversion=0) 收到通知 current_dataversion+=1 (等于1)
 2)set /group/policy (mzxid=4,dataversion=1) 收到通知 curren_dataversion==/group/policy.dataversion,沒有漏掉通知
                                                      current_zxid=/group/policy.mzxid (等于4)
 情形一)                                                     
 3.1) create /group/policy/n2 (mzxid=5,dataversion=0) 沒有收到通知 current_dataversion不變(等于1)
 4.1)set /group/policy (mzxid=6,dataversion=2) 收到通知 current_data < /group/policy.dataversion,得知漏掉了通知,并且知道漏掉1個
                                                         同步mzxid大于current_zxid(值為4)的節點(即n2節點)配置;
                                                         刪除已經不存在znode的配置;
                                                         current_data = /group/policy.dataversion (等于2)
                                                         current_zxid = /group/policy.zxid (等于5)
  情形二)
  3.2)create /group/policy/n2(mzxid=5,dataversion=0) 收到通知 current_dataversion+=1 (等于2)
  4.2)set /group/policy (mzxid=6,dataversion=2)  沒有收到通知  current_zxid(=4)不變。漏掉該消息是沒有關系的,再次收到該消息時,會更新current_zxid
  情形三)
  3.3)create /group/policy/n2(mzxid=5,dataversion=0) 沒收到通知 current_dataversion不變(等于1)
   4.3)set /group/policy (mzxid=6,dataversion=2)  沒有收到通知   current_zxid(=4)不變。
   5)create /group/policy/n3(mzxid=7,dataversion=0) 收到通知 current_dataversion+=1 (等于2)
   6)set /group/policy (mzxid=8,dataversion=3)   收到通知    current_data < /group/policy.dataversion 得知漏掉了通知
                                                              同步mzxid大于current_zxid(值為4)的節點(即n2,n3節點)配置;
                                                              刪除已經不存在znode的配置;
                                                              current_data = /group/policy.dataversion (等于3)
                                                              current_zxid = /group/policy.zxid (等于8)

通過這種方式,可以讓client端知道自己錯過了通知,至少在下次收到/group/policy節點更新通知時,能夠重新同步配置。因此可以保證client之間遲早會變得同步。

更進一步,可以額外再增加時鐘來觸發對/group/policy節點的檢查。這樣就可以保證一個時鐘間隔之后,client肯定是同步的。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

衡东县| 九江县| 乌拉特前旗| 武平县| 治县。| 丽水市| 明星| 达拉特旗| 赤水市| 庆元县| 锦屏县| 布尔津县| 阜康市| 邯郸县| 芜湖县| 南投市| 清苑县| 南皮县| 竹北市| 平远县| 新野县| 乌苏市| 夹江县| 肇东市| 延安市| 鄂尔多斯市| 葵青区| 肥西县| 沅江市| 二手房| 乃东县| 顺义区| 宜兰市| 固原市| 乌拉特后旗| 华宁县| 荔浦县| 曲麻莱县| 库车县| 焉耆| 维西|