天天看點

failover機制的小讨論

  對于一個7*24小時無間斷的線上服務來說,在服役時間内難免會遇到一些fail,例如db斷開連接配接且短暫連接配接不上了, 下遊的某個節點忽然挂了,運維部署上依賴的某一個東西不存在了等等場景。本文主要來讨論一下這些場景使用怎樣的政策會比較好。

  最簡單的方法,While(true) + sleep(固定時間)  不斷的重試,直到成功為止。這個方法的優點就是簡單,可依賴。缺點就是對于感覺延遲要求比較嚴格的程式,會消耗大量的CPU,甚至因為一些不合理的邏輯導緻CPU滿載等等情況發生.這種簡單粗暴的方法應用廣泛,并且能解決實際問題,在很多場合還是非常可取. 我們暫且叫這種政策為”粗暴法”.

  我曾經在一個實時檔案抓取程式中(類似于scribe這樣的實時日志傳輸方案),使用了這樣的政策,當fstat源檔案發現檔案不存在的時候,我會重試1000次,每次間隔sleep 10ms, 其間程式會輸出很多warnning資訊來支援一些報警等,重試完1000次之後(10s之後),将sleep間隔設定為固定時間,例如1s,在降低程式對CPU的消耗的同時,保證了一定的實時性,源檔案無論什麼時候出現都能夠確定在1s内cover進來,而且這樣的政策對于日志切分場景也非常實用,普通的日志切分(如切分nginx為每小時一個檔案,crontab每小時mv access.log access.log.$date再 kill -USR1等)程式能夠立馬感覺到并作出相應的政策調整。我們暫且叫這種政策為”重試N次後,将間隔時間調整為最大的可接受值”.

  再看看另外一種方法,最近看了下facebook scribe的源碼(感興趣的自己google,大家可以姑且的認為是一個多下遊的日志轉發工具),他在下遊死掉了之後選擇對sleep時間循序漸進的政策,每次将retryInterval *1.414; (sqrt(2)),再加上一個範圍随機數(如1-100ms),同時來設定了一個最大值的方式來相對動态的判斷下遊狀态. 為什麼一定要設定最大值呢?因為這個政策在異常時間久了之後,滞後性會非常大,當一場恢複時,可能不能及時感覺,是以需要一個最大值做保證。我們暫且叫這種政策為“重試時間循序漸進, 且確定不大于最大可接受值“.

  近兩年來使用zookeeper(以下簡稱zk)的公司越來越多,很多公司都用zk來做大型分布式系統的協調,他的模式類似于:下遊通過在zk上注冊一個臨時節點,告訴大家,我活着呢, 上遊通過watch這個節點的變化來感覺下遊的變化。模式很簡單,但是大家都是用zk是因為他提供了很多額外的東西,例如下遊注冊的臨時節點在下遊當機,或者網絡不可達(反正就是挂了)等等情況下會自動清除,并且通過回調函數實時讓上遊程式感覺,作出相應變化,當下遊活了之後,又注冊一個臨時節點宣稱自己活了,上遊程式也能通過回調函數實時感覺。上遊程式依賴zookeeper的一個Lib庫。對于上遊程式來說,他是一個觀察者,套進設計模式就是觀察者模式,好萊塢有句名言. “不要給我打電話, 我會給你打電話”.我們暫且叫這種政策為“被動實時感覺下遊變化”。

  先寫到這裡(也隻想到了這些),後續有所想法再補充吧,也歡迎各位看官留言,過去的博文都長篇大論,以後盡量做到簡約不簡單吧。畢竟時間精力有限。

部落格位址:Zealot Yin

歡迎轉載,轉載請注明出處[http://creator.cnblogs.com/]

繼續閱讀