最近在做系統(tǒng)升級,由于當(dāng)時設(shè)計的局限,導(dǎo)致系統(tǒng)不停服,保證服務(wù)的做法非常麻煩。當(dāng)時再定方案的時候,由于自己在這方面沒有經(jīng)驗,導(dǎo)致有些樂觀。到了實際做的時候,預(yù)期時間至少比預(yù)想的多了一周的時間,要知道,在互聯(lián)網(wǎng)公司,一周的時間是個非常長的時間。而這一周,還包括了OT。
在這里總結(jié)一下分布式系統(tǒng)設(shè)計的大忌,本來想試著分一下級,但是還是算了,一來標(biāo)準(zhǔn)太多,無法制定一個合適的規(guī)則來界定;二來自己的經(jīng)驗也在增長,低調(diào)一下是自己也沒詳細的研究過超過5個分布式系統(tǒng);三來做事情還是要嚴(yán)謹,不做沒有十足把握的事情。
1. 忽視服務(wù)接口的設(shè)計
雖然大家口口聲聲說對于一個集群來說,每臺機器都可能出故障。但是做方案設(shè)計的時候,某些資源卻向用戶直接暴漏了服務(wù)的實際地址。對于一個服務(wù)幾年的服務(wù)器來說,故障的可能性非常大,尤其是如果這個服務(wù)器的平時負載比較高的話。我不清楚一臺服務(wù)器的平均保修時間是多少,但是絕對不可能是幾個小時能搞定的,這個時間少則一天,多則半個月甚至更長。對于一些高級的用戶,它會使用本地的cache,或者其他的策略來屏蔽調(diào)用服務(wù)不可用帶來的影響,但是,幾天的停服對于用戶方的影響是無論如何不可能忽略的。
這種問題發(fā)現(xiàn)后,可能簡單的發(fā)布一個新版本的api,或者一個簡單的配置文件就可以糾正。但是對于線上用戶來說,他們運行的是一個一直都在 running狀態(tài)的服務(wù)。這個簡單的改正可能需要他們服務(wù)重啟,這對于一個大型的集群來說,帶來的成本非常高。如果是因為這個服務(wù)的不可用導(dǎo)致了線上事故,那么應(yīng)用方肯定會非常主動的去修正這個錯誤。但是如果使用架構(gòu)方發(fā)現(xiàn)了這個問題,而主動推動應(yīng)用方去修改,可能應(yīng)用方會因為各種原因而推脫。
因此,設(shè)計服務(wù)的接口一定要注意,這個接口一定要是穩(wěn)定的,而且后臺服務(wù)的故障,升級等操作絕對對于用戶要是透明的。不要將服務(wù)的實際地址暴漏給用戶方:這臺服務(wù)器終有一天會掛掉。尤其是對于C++等需要編譯的api來說,這個接口就更加重要了。畢竟api的修改對于應(yīng)用方來說意味著要重新編譯;重新編譯意味著要重新走一下發(fā)布流程:至少要提測吧。
2. 后臺升級對用戶不透明
這實際上是又是一句大家都知道的。但是設(shè)計時確實有時候會忽略。對于彈性計算系統(tǒng)來說,服務(wù)的伸縮是必須的,這個也是設(shè)計的目標(biāo)之一。但是對于一些小規(guī)模的計算集群來說,可能大家認為伸縮不是最重要的feature。最重要的feature就是能夠快速的完成系統(tǒng)設(shè)計和實現(xiàn),為用戶服務(wù)。但是實際上,這個通過一些簡單的修改,就可以完成:Worker上帶一個agent和master或者meta server通信,保持心跳。心跳超時的Worker會被下線,以后的服務(wù)都不會發(fā)送到這個Worker上來。而新加入的Worker則會加入集群接收計算任務(wù)。這個不單是應(yīng)對服務(wù)的伸縮,也是為了應(yīng)對機器的故障。因此不用太大的改動,就可以將一個系統(tǒng)從山寨提升到真正的可用。
一個系統(tǒng)的服務(wù)質(zhì)量,不是說在一般情況下的服務(wù)是可靠的,除了網(wǎng)絡(luò)丟包、網(wǎng)絡(luò)傳輸造成的問題外,服務(wù)質(zhì)量可以做到10000個請求至多有1個失敗就是說這個系統(tǒng)是可用的。評價服務(wù)質(zhì)量的另外一個重要指標(biāo)是全年可服務(wù)時間。這個要將機器故障,機房故障考慮在內(nèi)。如果依賴于運行環(huán)境沒有問題,才能達到 99.99,那么這個服務(wù)就有點山寨,對于重要的應(yīng)用方來說,這種服務(wù)不可接受。
3. 應(yīng)用方設(shè)計時未衡量后臺服務(wù)失敗的影響
如果服務(wù)的可靠性要求非常高,比如是直接面向互聯(lián)網(wǎng)用戶的,要求任何時間都能夠?qū)ヂ?lián)網(wǎng)用戶提供服務(wù),那么就需要在調(diào)用服務(wù)時做下服務(wù)不可用的預(yù)案。甚至做下超時機制:如果服務(wù)調(diào)用指定時間不返回,那么需要有其余的邏輯來替代。
當(dāng)然了本次還遇到很多其他的痛點,每個都是設(shè)計上得小瑕疵,當(dāng)時注意的話不會增加工作量,或者增加很少的工作量就可以做到可用?;ヂ?lián)網(wǎng)強調(diào)快,那么底線應(yīng)該是可用吧。易用可能是更要的要求。當(dāng)然了這個可能可以一種互聯(lián)網(wǎng)風(fēng)格,就是一個事情可以快速做完,快速上線。當(dāng)時上線時候也做了二期需要做的改進,但是后臺發(fā)現(xiàn)上線效果好,符合預(yù)期。又去做其它高優(yōu)先級的事情去了。導(dǎo)致原來設(shè)計的局限就永遠的停留在那里了,這就是為后來人埋下一個坑。。
本次升級的時候,由于信息的不一致導(dǎo)致一臺服務(wù)器停服,導(dǎo)致大面積的失敗。后來為了避免其它的集群出現(xiàn)類似的問題,因此所有的信息都重新確認了一遍。而這帶來了半天的枯燥工作。因此,自己做設(shè)計的時候,一定要注意,不求最好,但求可用,在機器故障,服務(wù)升級,對于用戶來說,服務(wù)都可用。
BTW,正在做一個架構(gòu)的設(shè)計,細節(jié)是魔鬼,正在和魔鬼做斗爭。