最近看到 Netflix 的混沌工程的介紹鳖宾,感觸頗深。在 TiDB 里面逆航,我們?yōu)榱吮WC系統(tǒng)的健壯性鼎文,也做了很多工作。在內(nèi)部我們開(kāi)始叫做 stability test因俐,后來(lái)進(jìn)化成 Schodinger 平臺(tái)拇惋。之前我一直苦于沒(méi)有沒(méi)法對(duì)我們做得工作進(jìn)行歸類周偎,畢竟它可能是一個(gè) test,但又比 test 做得多一點(diǎn)撑帖,現(xiàn)在知道蓉坎,原來(lái)我們一直做的其實(shí)算是一門工程實(shí)踐。
既然是工程胡嘿,那么就會(huì)有方法論蛉艾,也就能詳細(xì)的歸納總結(jié)出來(lái)實(shí)施的步驟,這樣后面的同學(xué)就能非吃钇剑快速的學(xué)習(xí)掌握伺通,而不會(huì)像我們之前那么漫無(wú)目的的探索了,但我們現(xiàn)在還做不到這一步逢享,而且相比 Netflix罐监,我們還有很多路要走。所以我打算深入研究下 Netflix 是如何做的瞒爬,在想想如何提升我們自己的工作弓柱。
介紹
首先,我們需要知道侧但,混沌工程到底是什么矢空。根據(jù) Netflix 的解釋,混沌工程師通過(guò)應(yīng)用一些經(jīng)驗(yàn)探索的原則禀横,來(lái)學(xué)習(xí)觀察系統(tǒng)是如何反應(yīng)的屁药。這就跟科學(xué)家做實(shí)驗(yàn)去學(xué)習(xí)物理定律一樣,混沌工程師通過(guò)做實(shí)驗(yàn)去了解系統(tǒng)柏锄。
上圖就是混沌工程的典型代表 - 猴子酿箭。拜 Netflix 所賜,現(xiàn)在大部分的混沌工程項(xiàng)目都叫做 Monkey趾娃,也就是一只討厭的猴子缭嫡,在你的系統(tǒng)里面上蹦下竄,不停搗亂抬闷,直到搞掛你的系統(tǒng)妇蛀。
然后,我們需要知道笤成,為什么需要混沌工程评架。應(yīng)用混沌工程能提升整個(gè)系統(tǒng)的彈性。通過(guò)設(shè)計(jì)并且進(jìn)行混沌實(shí)驗(yàn)炕泳,我們可以了解到系統(tǒng)脆弱的一面古程,在還沒(méi)出現(xiàn)對(duì)用戶造成傷害之前,我們就能主動(dòng)發(fā)現(xiàn)這些問(wèn)題喊崖。
混沌工程其實(shí)是很重要的挣磨,但我之前一直以為混沌工程就是測(cè)試雇逞,但它們還是有區(qū)別的。雖然混沌工程跟傳統(tǒng)測(cè)試通常都會(huì)共用很多測(cè)試工具的茁裙,譬如都會(huì)使用錯(cuò)誤注入工具塘砸,但混沌工程是通過(guò)實(shí)踐對(duì)系統(tǒng)有更新的認(rèn)知,而傳統(tǒng)測(cè)試則是使用特定方式對(duì)某一塊進(jìn)行特定測(cè)試晤锥。譬如在傳統(tǒng)測(cè)試?yán)锩娴羰撸覀兛梢詫懸粋€(gè)斷言,我們給定特定的條件矾瘾,產(chǎn)生一個(gè)特定的輸出女轿,如果不滿足斷言條件,測(cè)試就出錯(cuò)了壕翩,這個(gè)其實(shí)是具有很明確的特性蛉迹。但混沌工程是試驗(yàn),而試驗(yàn)會(huì)有怎樣的新信息生成放妈,我們是不確定的北救。譬如我們可以進(jìn)行下面的這些試驗(yàn):
- 模擬整個(gè) IDC 當(dāng)?shù)?/li>
- 選擇一部分網(wǎng)絡(luò)連連接注入特定時(shí)間的延遲
- 隨機(jī)讓一些函數(shù)拋出異常
- 強(qiáng)制 NTP 時(shí)間不同步
- 生成 IO 錯(cuò)誤
- 榨干 CPU
這些試驗(yàn)到底會(huì)有什么樣的結(jié)果,有些我們可以預(yù)料芜抒,但有些可能我們就不會(huì)預(yù)先知道珍策,只有發(fā)生了,才會(huì)恍然大悟宅倒,有一種『喔攘宙,這也會(huì)出現(xiàn)!』的感嘆拐迁。
原則
在開(kāi)始應(yīng)用混沌工程之前蹭劈,我們必須確保系統(tǒng)是彈性的,也就是當(dāng)出現(xiàn)了系統(tǒng)錯(cuò)誤我們的整個(gè)系統(tǒng)還能正常工作唠亚。如果不能確保链方,我們就需要先考慮提升整個(gè)系統(tǒng)的健壯性了持痰,因?yàn)榛煦绻こ讨饕怯脕?lái)發(fā)現(xiàn)系統(tǒng)未知的脆弱一面的灶搜,如果我們知道應(yīng)用混沌工程能導(dǎo)致顯而易見(jiàn)的問(wèn)題,那其實(shí)就沒(méi)必要應(yīng)用了工窍。
雖然 chaos 有混亂的意思割卖,但混沌工程并不是制造混亂。相反患雏,我們可以認(rèn)為混沌工程是用經(jīng)驗(yàn)的方法來(lái)定位問(wèn)題的一門實(shí)驗(yàn)學(xué)科鹏溯。譬如,我們可以思考:『如果我們?cè)谙到y(tǒng)里面注入混亂了淹仑,這個(gè)系統(tǒng)會(huì)怎樣丙挽?』肺孵,或者『我們系統(tǒng)離混亂的邊界還有多遠(yuǎn)?』颜阐。所以平窘,為了更好的進(jìn)行混沌試驗(yàn)腿椎,我們需要有一些原則來(lái)進(jìn)行指導(dǎo)窥摄。
假定穩(wěn)定狀態(tài)
在一個(gè)復(fù)雜系統(tǒng)里面,我們有特別多的組件僧须,有很多不同的輸入輸出肤舞,我們需要有一個(gè)通用的方式來(lái)區(qū)別系統(tǒng)哪些行為是可以接受的紫新,而哪一些則是不合適的。我們可以認(rèn)為當(dāng)系統(tǒng)處于正常操作時(shí)候的狀態(tài)就是穩(wěn)定狀態(tài)李剖。
通常我們可以通過(guò)自己測(cè)試芒率,來(lái)確定一個(gè)系統(tǒng)的穩(wěn)定狀態(tài),但這個(gè)方法當(dāng)然是比較低效的杖爽,另一種更常用的做法就是收集 metric 信息敲董,不光需要系統(tǒng)的 metric,也需要服務(wù)自身的 metric慰安,但收集 metric 需要注意實(shí)時(shí)性的問(wèn)題腋寨,你如果收集一個(gè)每月匯總的 metric 信息,其實(shí)沒(méi)啥用化焕,畢竟系統(tǒng)是實(shí)時(shí)變化的√汛埽現(xiàn)在市面上面有很多不錯(cuò)的開(kāi)源 metric 系統(tǒng),譬如我們就在用的 Prometheus撒桨。
當(dāng)我們能收集到信息之后查刻,就需要用這些信息去描述一個(gè)穩(wěn)定狀態(tài)。這個(gè)難度比較大凤类,因?yàn)椴煌臉I(yè)務(wù)是不一樣的穗泵,即使是同一個(gè)業(yè)務(wù),不同時(shí)間也可能變化很大谜疤。但也有一些方法佃延,譬如我們可以根據(jù)前面一段時(shí)間譬如上周的 metric 的曲線得到一個(gè)大概合理的穩(wěn)定狀態(tài),也可以自己做很多壓力測(cè)試夷磕,得到相關(guān)的數(shù)據(jù)履肃。
當(dāng)有了 metric 以及知道穩(wěn)定狀態(tài)對(duì)應(yīng)的 metric 是怎樣之后,我們就可以通過(guò)這些來(lái)考慮混沌實(shí)驗(yàn)了坐桩。思考當(dāng)我們注入不同的事件到系統(tǒng)中的時(shí)候尺棋,穩(wěn)定狀態(tài)會(huì)如何變化,然后我們就會(huì)開(kāi)始做實(shí)驗(yàn)來(lái)驗(yàn)證這個(gè)假設(shè)绵跷。
變更真實(shí)世界事件
在真實(shí)的世界中膘螟,我們可能遇到各種各樣的問(wèn)題成福,譬如:
- 硬件故障
- 網(wǎng)絡(luò)延遲和隔離
- 資源耗盡
- 拜占庭錯(cuò)誤
- 下游依賴故障
做混沌試驗(yàn)的時(shí)候需要模擬這些故障,來(lái)看系統(tǒng)的狀態(tài)荆残。但從成本上面考慮闷叉,我們并不需要模擬所有的故障,僅僅需要考慮那些會(huì)比較頻繁發(fā)生脊阴,而且模擬之后會(huì)很有效果的握侧。在 TiDB 里面,我們主要就是模擬的網(wǎng)絡(luò)嘿期,文件系統(tǒng)的故障品擎,但現(xiàn)在看起來(lái)還是不夠,后面會(huì)逐漸的添加更多备徐。
在生產(chǎn)中進(jìn)行試驗(yàn)
要看混沌試驗(yàn)有沒(méi)有效果萄传,在真實(shí)生產(chǎn)環(huán)境中進(jìn)行驗(yàn)證是最好的方法。但我相信大部分的廠商還沒(méi)這么大的魄力蜜猾,這方面 Netflix 就做的很猛秀菱,他們竟然能夠直接停掉 Amazon 上面的一個(gè) Zone。
如果不能再生產(chǎn)環(huán)境中試驗(yàn)蹭睡,一個(gè)可選的方法就是做 shadow衍菱,也就是通常的錄制生產(chǎn)環(huán)境的流量,然后在測(cè)試中重放肩豁〖勾或者模擬生產(chǎn)環(huán)境,自己造數(shù)據(jù)測(cè)試清钥。
自動(dòng)化持續(xù)執(zhí)行
最開(kāi)始執(zhí)行混沌試驗(yàn)琼锋,我們可能就是人工進(jìn)行,試驗(yàn)進(jìn)行的過(guò)程中祟昭,看 metric缕坎,試驗(yàn)結(jié)束之后,通過(guò)收集的 metric 在對(duì)比篡悟,看系統(tǒng)的狀態(tài)谜叹。這個(gè)過(guò)程后面完全可以做成自動(dòng)化的,也就是定期執(zhí)行恰力,或者系統(tǒng)發(fā)布的時(shí)候執(zhí)行等叉谜。
如果能做到自動(dòng)化執(zhí)行試驗(yàn)旗吁,已經(jīng)很不錯(cuò)了踩萎,但我們可以做的更多,甚至有可能根據(jù)系統(tǒng)的狀態(tài)自動(dòng)化的生成相關(guān)的試驗(yàn)很钓,這個(gè) Netflix 已經(jīng)做了很多研究香府,但我們這邊還處于初級(jí)階段董栽,沒(méi)考慮過(guò)自動(dòng)化生成的問(wèn)題。
最小化影響范圍
在進(jìn)行混沌試驗(yàn)的時(shí)候企孩,一定要注意影響的范圍锭碳,如果沒(méi)預(yù)估好,把整個(gè)服務(wù)搞掛了勿璃,導(dǎo)致所有的用戶都沒(méi)法使用擒抛,這個(gè)問(wèn)題還是很嚴(yán)重的。
通常都會(huì)使用一種 Canary 的方法补疑,也就是類似 A/B 測(cè)試歧沪,或者灰度發(fā)布這種的,在 Canary 集群這邊做很多試驗(yàn)莲组。也就是說(shuō)诊胞,如果真的搞壞了,那也只是一小部分用戶被搞壞了锹杈,損失會(huì)小很多撵孤。
在 Canary 里面還有一個(gè)好處,因?yàn)槲覀冎勒麄€(gè)系統(tǒng)的穩(wěn)定狀態(tài)竭望,即使不做混沌測(cè)試邪码,也可以觀察 Canary 里面的狀態(tài)是不是跟之前的穩(wěn)定狀態(tài)一致的,如果不一致咬清,那也可能有問(wèn)題霞扬。
實(shí)踐
上面我們說(shuō)了相關(guān)的原則,那么如何開(kāi)始進(jìn)行一次混沌試驗(yàn)?zāi)胤阏瘢科鋵?shí)很簡(jiǎn)單喻圃,只要做到如下步驟就可以:
- 選擇一個(gè)假設(shè)
- 選擇試驗(yàn)的范圍
- 明確需要觀察的 metric 指標(biāo)
- 通知相關(guān)的團(tuán)隊(duì)
- 執(zhí)行試驗(yàn)
- 分析結(jié)果
- 增大試驗(yàn)的范圍
- 自動(dòng)化
譬如對(duì)于 TiDB 來(lái)說(shuō),譬如我們可以選擇驗(yàn)證網(wǎng)絡(luò)隔離對(duì)系統(tǒng)的影響粪滤,我們會(huì):
- 假設(shè)一臺(tái)機(jī)器的網(wǎng)絡(luò)隔離對(duì)整個(gè)系統(tǒng)不會(huì)造成影響
- 將一個(gè)用戶一臺(tái) TiKV 進(jìn)行網(wǎng)絡(luò)隔離
- 觀察 QPS斧拍,latency,等指標(biāo)
- 通知負(fù)責(zé)這個(gè)用戶的 OPS 同學(xué)
- 斷網(wǎng)
- 一段時(shí)間之后分析 metric
- 在多個(gè)集群測(cè)試
- 將這個(gè)流程自動(dòng)化
上面只是一個(gè)簡(jiǎn)單的例子杖小,實(shí)際還會(huì)復(fù)雜很多肆汹,但通過(guò)這種方式做了操作了很多次之后,大家都會(huì)更加熟悉自己的系統(tǒng)予权。
混沌成熟度模型
這里在簡(jiǎn)單說(shuō)說(shuō)混沌成熟度模型昂勉,Netflix 總結(jié)了兩個(gè)維度,一個(gè)是復(fù)雜度扫腺,一個(gè)就是接受度岗照。前者表示的是混沌工程能有多復(fù)雜,而后者則表示的是混沌工程被團(tuán)隊(duì)的接受程度。
復(fù)雜度分為幾個(gè)階段:
-
初級(jí)
- 試驗(yàn)沒(méi)有在生產(chǎn)中進(jìn)行
- 進(jìn)程被收工管理
- 結(jié)果只反映系統(tǒng) metric攒至,沒(méi)有業(yè)務(wù)的
- 只有簡(jiǎn)單的事件進(jìn)行試驗(yàn)
-
簡(jiǎn)單
- 試驗(yàn)可以在類生產(chǎn)環(huán)境中進(jìn)行
- 能自動(dòng)啟動(dòng)執(zhí)行厚者,但需要人工監(jiān)控和終止
- 結(jié)果能反應(yīng)一些聚合的業(yè)務(wù) metric
- 一些擴(kuò)展的事件譬如網(wǎng)絡(luò)延遲可以進(jìn)行試驗(yàn)
- 結(jié)果可以手工匯總和聚合
- 試驗(yàn)是預(yù)先定義好的
- 有一些工具能進(jìn)行歷史對(duì)照
-
復(fù)雜
- 試驗(yàn)直接在生產(chǎn)環(huán)境中進(jìn)行
- 啟動(dòng),執(zhí)行迫吐,結(jié)果分析库菲,終止都是自動(dòng)完成
- 試驗(yàn)框架集成在持續(xù)發(fā)布
- 業(yè)務(wù) metrics 會(huì)在實(shí)驗(yàn)組和控制組進(jìn)行比較
- 一些組合錯(cuò)誤或者服務(wù)級(jí)別影響的事件可以進(jìn)行試驗(yàn)
- 結(jié)果一直可以追蹤
- 有工具可以更好的交互式的對(duì)比試驗(yàn)和控制組
-
高級(jí)
- 試驗(yàn)在每個(gè)開(kāi)發(fā)步驟和任意環(huán)境都進(jìn)行
- 設(shè)計(jì),執(zhí)行和提前終止這些全部都是自動(dòng)化的
- 框架跟 A/B 或者其他試驗(yàn)系統(tǒng)整合
- 一個(gè)事件譬如更改使用模式和返回值或者狀態(tài)變更開(kāi)始進(jìn)行試驗(yàn)
- 試驗(yàn)包括動(dòng)態(tài)作用域和影響志膀,可以找到突變點(diǎn)
- 通過(guò)試驗(yàn)結(jié)果能保護(hù)資產(chǎn)流失
- 容量預(yù)測(cè)可以通過(guò)試驗(yàn)分析提前得出
- 試驗(yàn)結(jié)果可以區(qū)分不同服務(wù)的臨界狀態(tài)
而接受度也有幾個(gè)階段:
-
在暗處
- 相關(guān)項(xiàng)目不被批準(zhǔn)
- 很少系統(tǒng)被覆蓋
- 很少或者沒(méi)有團(tuán)隊(duì)有意識(shí)
- 早期接受者不定期的進(jìn)行試驗(yàn)
-
有投入
- 試驗(yàn)被被官方批準(zhǔn)
- 部分資源被用于實(shí)踐
- 多個(gè)團(tuán)隊(duì)有興趣并投入
- 少部分關(guān)鍵服務(wù)不定期進(jìn)行試驗(yàn)
-
接受
- 有專門的 team 進(jìn)行混沌工程
- 應(yīng)急響應(yīng)被集成到框架熙宇,從而可以創(chuàng)建回歸試驗(yàn)
- 多數(shù)關(guān)鍵系統(tǒng)定期進(jìn)行混沌試驗(yàn)
- 一些試驗(yàn)驗(yàn)證會(huì)在應(yīng)急響應(yīng)或者游戲時(shí)間被臨時(shí)執(zhí)行
-
文化
- 所有關(guān)鍵服務(wù)都有頻繁的混沌試驗(yàn)
- 大多數(shù)非關(guān)鍵服務(wù)定期進(jìn)行
- 混沌試驗(yàn)已經(jīng)是工程師的日常工作
- 默認(rèn)所有系統(tǒng)組件都必須參與,如果不想進(jìn)行溉浙,需要有正當(dāng)?shù)睦碛?/li>
如果按照這上面兩個(gè)維度來(lái)看奇颠,我們其實(shí)做的并不好,所以還有很大的提升空間放航。
總結(jié)
上面就是對(duì)混沌工程的簡(jiǎn)單介紹烈拒,后面我會(huì)考慮依照混沌工程的原則,開(kāi)始工程化的實(shí)踐广鳍。雖然之前我們做過(guò)很多工作荆几,如果能用理論開(kāi)始指導(dǎo),就能更進(jìn)一步了赊时。