對於乙個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庫。對於上游程式來說,他是乙個觀察者,套進設計模式就是觀察者模式,好萊塢有句名言. 「不要給我打**, 我會給你打**」.我們暫且叫這種策略為「被動實時感知下游變化」。
演算法小討論
舉例說 假設你們班級有30個人,假設按照成績高低已經把試卷排列好了,你想找出數學成績在75分的人。第一種辦法,就是簡單的順次查詢,找到就退出。複雜度o n 第二種辦法,把試卷分兩羅,大概在中間那張如果小於75分,就把上邊的再分兩羅再執行上邊步驟,按照這個辦法找到為止。每次輸入範圍是上次的一半,遞迴,...
HMaster的failover 流程 三
繼續hmaster的failover 流程 哪兒了。首先來看如何重現。1.master 傳送rpc請求去open region,此時zk上的節點時offline狀態。2.rs收到請求還沒有開始處理,即zk節點仍然是offline。3.master重啟 4.master開始failover 流程,rs...
Flink中task的failover機制
flink中的failover分為task的failover和master的failover。我們先來看task的failover,它有多種策略 1.restart all 重啟所有的task,從上次的checkpoint開始重新執行。只重啟出錯的task,只適用於task間無連線的情況,應用場景有...