分佈式緩存console重構

    剛剛畢業進入工做崗位第一個任務是重構分佈式緩存的console。不太重構是後面的事情,原由是對console的rebalance算法作簡化。若是你有興趣能夠翻看我第一篇blog,裏面解析了新rebalance算法。算法來自於豌豆莢的codis,爲了搞懂他的思想,我看了codis rebalance的源碼,並在github上跟向做者提問,終於徹底搞懂了。下面會記錄一下重構這個項目的過程。java

    首先說明一下緩存console的功能:git

  1. console監聽zk group節點的子節點數量,響應group數量的改變;
  2. 若是增長group,則計算出新的負載狀況,即group -> buckets的對應關係,以二維表的形式存在zk上,二維表的行是group,列(index)是桶號;若是group減小,則出現宕機狀況,更新二維表;
  3. 控制client能看到的二維表,下面會解釋的
  4. 控制migration的結果和client讀寫權限
  5. 響應zk state change,即zk Disconnected SyncConnected狀態,以及主備切換

    console主要功能是控制。二維表是console的核心數據結構,重構前他的結構是第0行爲緩存主機,第1行第一個備機,第二行是第二個備機,以此類推。縱向看index是桶號,0號桶的主備機,1號桶的主備機,以此類推。切換成組以後的不一樣是一個組包含了主機和備機,而對於緩存client來講他只能看到主機,因此,新的二維表只有一行,表中的內容從機器地址擴展爲group對象,增長了字段和功能。github

    上面羅列的console功能中屢次出現不一樣功能的二維表,在zk上有三張不一樣功能的二維表,他們共同爲client、console、引擎提供組信息。第一張是c表,是client看到的組的分佈狀況;第二張是m表,存放「舊」數據;第三張d表存放「最終結果」數據。算法

    新算法對增長組進行rebalance計算,如果宕機則須要人工介入,重啓宕掉的組。做爲組出現,即主備機同時宕掉的概率極低,若是主機宕掉,備機頂上來。新增組後,作rebalance,其算法思想很簡單明瞭,很好理解。根據上來組的內存大小按比例分配多少個桶(bucket or slot)「落在」哪一個組中。越大的組分配越多的桶。這個前提是認爲各個桶的分配是均衡的。算法詳情點擊這裏緩存

    思路很清楚,須要新增兩個zkChildListener,分別監控組和遷移結果的變化。經過對比二維表和zk上組路徑下子節點的數量和子節點的內容,就能夠判斷有哪些組是新增的、哪些組宕掉了。若是當掉了,三張表中對應位置組置爲0。client看到0會報錯,console同時也會在宕機邏輯中報錯,且還會有一個線程持續檢查是否有宕機狀況。組減小的處理狀況很簡單,不過也是最合理的。由於儘管宕機這種事情「必然」會發生,但頻率很低,用人工介入代替複雜的算法邏輯是合理的。不過增長組的邏輯就稍微麻煩一些。session

    最正常的狀況是新增組是三張表是相同的,沒有宕機和遷移這兩種狀況。那麼正常rebalance,將「最終結果」寫入d表,m表中就變成了「舊」數據,將c表中遷移的源組置爲只讀。例如(1 : 192.168.0.1:33661, 2 : 192.168.0.2:33661....) : m表111222,增長3,d表變爲113223,須要遷移的是二、5號桶、遷移的源和目的也能得出。數據結構

    若是正在遷移,新增組這種狀況不會發生,由於這裏有其餘模塊控制這種異常狀況,但確實是一種異常狀況。這種異常很複雜,須要處理不少複雜邏輯。架構

    若是是有宕機的狀況,新增組,這種異常的思路是「填回去,不計算」。既然有空位爲何不直接填回去,幹嗎還要rebalance,原先也必定是平衡狀態。宕機也分爲兩種,一種是舊組宕掉,一種是新組宕掉。其區別是對不一樣的二維表作操做,緣由是m、d表的數據不相同。分佈式

    遷移就更簡單明瞭,你也應該能感受到,對比m、d表計算出須要遷移,監控migration節點子節點變化,引擎完成一個桶的遷移,寫一條記錄,觸發一次計算。遷移結束更新三張表。測試

    不過以上這些結論都是通過幾回作錯、再重構後得出的,畢竟架構師不會把太多的時間放在我身上。。。

    關於第5點功能,我遇到了zk的bug,若是你也遇到過能夠交流一下。console的主備是依靠註冊到zk上的順序決定的。會在一個臨時節點中存master的值。但這個臨時節點在zk server停掉後沒有消失,隨即報錯。這個問題我還要測一下。。醉了,其餘的都蠻簡單的就略過了。。

----------------------------------------------------------------分割線--------------------------------------------------------------------

    這個並非zk的bug,測試時由於機器宕機,但在zk服務端,舊的session還沒過時,session的過時時間是30s,形成臨時節點沒有釋放。其實規避方法很明顯有兩種,一是重連間隔 > 30s,二是建立節點以前要判斷節點是否exists。

    因爲是公司的項目須要保密,只能說一下思想,源碼就不貼了,其實貼了也沒太大的意義,除非把,,哦,對了,這個分佈式緩存已經開源,但新console還沒開源,但願感興趣的同窗能在github上跟主創交流,開源代碼點擊這裏

相關文章
相關標籤/搜索