對《GitHub服務中斷24小時11分鐘事故分析報告》的分析

對《GitHub服務中斷24小時11分鐘事故分析報告》的分析

聲明

本文是根據公衆號“高效開發運維”翻譯整理的GitHub服務中斷分析報告的信息進行分析。可能存在某些觀點有誤,如果有歡迎指出。

原文地址:[GitHub服務中斷24小時11分鐘事故分析報告
](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協議),激活了西海岸的數據中心。而東海岸數據中心的數據庫有幾秒的數據還沒完全同步到西海岸。激活西海岸的數據庫(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這種數據庫架構方案在未來在覈心業務裏一定會逐步替換掉傳統數據庫基於主備同步思路的方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章