對《GitHub服務中斷24小時11分鐘事故分析報告》的分析
對《GitHub服務中斷24小時11分鐘事故分析報告》的分析
宣告
本文是根據公眾號“高效開發運維”翻譯整理的GitHub服務中斷分析報告的資訊進行分析。可能存在某些觀點有誤,如果有歡迎指出。
原文地址:[GitHub服務中斷24小時11分鐘事故分析報告
](ofollow,noindex" target="_blank">https://mp.weixin.qq.com/s/fFv1ASElHsVNEPPkP53qAQ)
官方報告英文地址:[October 21 post-incident analysis
](https://blog.github.com/2018-10-30-oct21-post-incident-analysis/)
背景
UTC 時間 10 月 21 日 22:52,為了更換髮生故障的 100G 光纖裝置,美國東海岸網路中心與美國東海岸資料中心之間的連線被斷開。連線在 43 秒後恢復,但這次短暫的中斷引發了一系列事故,導致 24 小時 11 分鐘的服務降級。
簡單分析
根據報告裡資訊描述,大致意思是要做一個計劃中的變更,替換東海岸網路中心和資料中心之間的光纖,網路中斷了43秒。在43秒內一個全域性的容災高可用機制(Orchestrator)檢測到網路中斷(發生分割槽事件Partition),就自動做了高可用切換(使用raft協議),激活了西海岸的資料中心。而東海岸資料中心的資料庫有幾秒的資料還沒完全同步到西海岸。啟用西海岸的資料庫(SQL/">MySQL)後,雖然後面東海岸的網路恢復了,但是西部到東部的複製鏈路卻是因為資料不一致中斷了。報告裡沒有提這個複製機制是什麼。從其他公眾號文章(GitHub 的 MySQL 高可用性實踐分享 資訊推測這個複製就是MySQL的半同步。半同步在網路中斷的時候超過500ms(github設定的)降級為非同步了,在東海岸寫入了幾秒資料沒有同步到西海岸,導致兩邊不一致,從而導致西海岸的資料沒辦法同步回東海岸(因為mysql slave replication中斷了)。後面運維選擇了一個從備份中還原然後重跑某些任務來在東海岸構建一個一致的例項,從而恢復同步鏈路的方法,這個用了大概24小時。
暴露的問題
這裡只是從技術角度分析報告中反映的問題。由於Github對外的報告不一定把所有緣由都講清楚了,這裡的分析可能存在一些不對的地方。
MySQL的問題
MySQL的主從同步是邏輯同步,在原理上無法絕對保證主備一致。半同步只是儘可能的保證讓主庫的事務日誌傳送備庫。由於事務日誌可以不落盤,以及半同步在網路超時或中斷時還可以降級為非同步同步,所以Mysql的這個主從同步不是絕對可靠的。雖然平時都說網路中斷是小概率事件,但是一旦它發生,這個資料不一致就很高概率發生了。Github運維在構建這個體系的時候應該早就判斷出一旦發生中斷切換時資料就存在不一致,然而並沒有作出充分準備,最後還是成為整個事件的背鍋俠。
高可用
Github的高可用使用的是orchestrator。這個在判斷不可用事件的時候使用的是raft協議,跟阿里電商mysql高可用基於zookeeper去判斷道理一樣,可以避免腦裂,可以正確識別出異常事件,並且延伸出自動切換機制。 mysql的主備自動切換就要面臨資料不一致問題,做自動切換就是把可用性放在資料一致性要求上面。然後報告裡卻又說把使用者資料一致性放在第一位,這是有點矛盾的。
資料質量體系問題
少數資料不一致導致主備切換就中斷了,還不敢強制切換,影響了所有使用者。這個是很划不來的。報告裡沒有解釋為什麼不去修復這部分mysql不一致的資料。靠人肉比對肯定不行。如果平時就搭建了主從資料校驗和訂正平臺,7*24小時去校驗資料的差異並提供自動訂正的手段,那也就不用在出現故障的時候不能訂正資料了。 當然可能背後還有其他原因導致沒有去訂正。也許因為mysql裡只是一些業務元資料,github主要業務資料(如程式碼等)可能不是放在mysql吧(這點是猜測)。
業務架構設計問題
一小部分的資料不一致導致不敢做主備強制切換,結果影響到全部使用者,mysql成了背鍋俠,這個我覺得也有點冤。如果業務上能做一些拆分設計,比如說按專案維度或者按使用者維度做拆分。當有資料不一致的時候識別出是哪些專案或者使用者相關的,可以在qia
強制切換的時候遮蔽掉這部分專案或者這部分使用者的寫操作,對這部分受影響的只提供純讀服務(有延時);對於其他無關的專案和使用者提供讀寫服務,那麼這個事件的影響就非常小,就不會搞得人人皆知了。
供參考的解決方案
Github面臨的這個問題在異地容災或者多活架構裡是個繞不過去的問題,在阿里和螞蟻早就碰到過且充分考慮過。這裡列舉一下阿里和螞蟻的解決方案供參考。
架構設計
架構上首先要儘可能的將業務按模組,按某個維度做垂直和水平拆分。基於mysql做這個異地資料不一致難以避免,但是可以利用拆分技術把影響控制在很小的範圍內。
按業務特點做單元化。如買家業務,可以按買家使用者id拆分,在多地同時提供讀寫服務,然後地區之間進行雙向同步。如果是三地,選擇一箇中心節點做同步中繼。有些業務不能多地同時寫,如賣家業務,庫存必須在同一個地方修改,併為其他地方提供讀服務,則按賣家使用者拆分,中心讀寫,異地單元只提供讀服務(業務可以接受讀延時)。
在切換的時候,應用層設計了 “禁止更新”和“禁止插入”規則,可以保證源端某使用者正在修改的資料在沒有同步到目的地之前,目的庫的該部分資料是不能寫的,避免髒資料產生。然後有後臺任務以及資料庫的資料校驗和訂正程式一起設法將這部分不一致資料同步到目的端。等一致之後就清除這個規則。而對不受影響的使用者資料在切換後是完全不受影響。
簡單來說是臨時容忍了少量的不一致,保障了可用性,最終一致。這就是BASE的思想。
實際做起來總會有些想不到的問題和困難,總會找到解決辦法。方案准備的越充足,發生故障時要人做的就越少,恢復實際就越快。
資料同步
MySQL自身的同步效能並不好,在延時60ms的情況下半同步會限制主庫的效能。在阿里已經放棄用mysql同步做異地同步。內部用DTS產品同步。dts也是邏輯同步,理論上也不能保障資料強一致,所以需要配套的有資料校驗和訂正產品。要做到實時校驗,會有短暫的不一致。
高可用
阿里異地機房的資料庫切換沒有做自動切換。每個地方是一個獨立的mysql master-master同步結構,異地之間用dts同步,所以資料庫的切換是需要判斷dts同步延時的。前面那種機制只是保證在切換後將影響儘可能的減少。是否要切換還是要有個判斷。 這個機制說好也好,說不好也對,這是選擇問題。這是mysql 主備架構的問題。
當然隨著paxos協議和三副本同步技術的發展,alisql發展出 xdb,螞蟻這邊的oceanbase 已經徹底解決了這個資料同步和高可用問題,都是自動保障的,不給運維人員糾結的機會。
異地容災和多活
異地容災和多活的層次
做異地多活,個人認為可以做到幾個層次,從簡單到複雜如下:
- 1.應用雙機房部署且多活,資料庫主備架構雙機房部署,讀寫集中在其中一個機房(主庫)。這就是異地容災。
- 2.應用雙機房部署且多活,資料庫主備架構雙機房部署,讀寫集中在其中一個機房(主庫),另外一個機房提供部分讀業務(業務能接受延時),這是讀寫分離。
- 3.應用雙機房部署且多活,資料庫也雙機房部署,主備交錯雙向同步。同一個應用只讀寫一個機房資料庫,不同應用讀寫不同機房資料庫。這是應用混部給人的多活感覺,實際不同應用讀寫不同的庫。
- 4.應用多機房部署且多活,資料庫多機房部署且都提供讀寫服務。同一個應用在不同機房都可以讀寫本地資料庫。這個是資料庫提供了多地同時讀寫的能力,實際讀寫的是不同的物理表,但是藉助拆分設計可以是讀相同的業務邏輯表。即對應用而言,它也是寫同一個表,程式碼同一份。
- 5.應用多機房部署且多活,資料庫多機房部署且都提供讀寫服務。同一個應用在不同機房都可以讀寫本地資料庫,並且讀寫是相同的物理表。這裡也會藉助拆分設計將業務表拆分為多個物理分表。
傳統的IOE架構的資料庫由於是主備架構,所以在異地容災多活建設上只能做到1和2。有很多資料複製產品,無論是資料庫層面的複製還是儲存層面的複製,其思路也是一樣,雖然宣稱自己做到多活,通常也是到1和2,少數做到3(給人異地多活的假象)。 如果應用使用了拆分設計(分庫分表),倒是有可能做到5.不過分散式資料庫中介軟體也是最近5年才出來的技術,只在網際網路行業裡大量使用,傳統行業估計不會使用。掌控成本相對高,且風險不敢承擔(找不到承擔責任的廠商)。
螞蟻的OceanBase,使用paxos同步協議,沒有主備概念,多地節點可以同時讀寫。可以不依賴外部產品僅憑資料庫自身就做到1、2和3. 如果要做4和5,則需要業務做拆分設計(分庫分表),從應用的接入層就設計流量拆分規則,跟資料庫拆分規則保持一致。然後OceanBase就可以做到4。由於三副本的leader只允許一個寫入點,所以OceanBase單叢集是做不到5.
淘寶的MySQL,使用主備架構,異地同步用外部產品dts。多地的mysql叢集彼此獨立,可以同時讀寫相同的表。在應用做拆分設計(分庫分表)後,在接入層設計流量拆分規則,跟資料庫拆分規則保持y
一致。基於MySQL的分散式資料庫叢集是可以做到5,實現三地同時讀寫相同的表。 不過問題也是存在的。如前面說的mysql切換的強一致問題、高可用自動切換問題。所以螞蟻並沒有選擇這個方案。
OceanBase在異地容災和多活的特別能力
OceanBase是很方便做異地容災和多活建設的,不管是三機房還是五機房,都可以作為一個OceanBase叢集。其內部自動維護各個機房之間的資料同步 ,並保證這種同步在叢集層面是強一致 的和可靠的(對業務而言,資料絕對不會丟)。在正常執行期間這種保障就一直在。此外,單個或少數機房故障時,OceanBase內部會自動切換 ,並且切換後資料是不丟的。
OceanBase這種資料庫架構方案在未來在核心業務裡一定會逐步替換掉傳統資料庫基於主備同步思路的方案。