每日最新頭條.有趣資訊

GitHub網絡鏈路中斷43秒,導致癱瘓了24 個小時

作者:JasonWarner是GitHub的技術負責人

上周,GitHub經歷了一次故障事件,導致服務品質下降了24小時又11分鐘。雖然我們平台的某些部分不受此事件影響,但多個內部系統還是受到了影響,導致我們顯示過時且不一致的資訊。最終,用戶數據沒有丟失;然而,數據庫寫入操作還是出現了幾秒鐘的手動協調。就事件過程中的大多數時間而言,GitHub也無法處理Web鉤子(webhook)事件,也無法構建和發布GitHub Pages網站。

我們GitHub的所有人都為這次事件給您們每個人帶來的影響深表歉意。我們深智您們對GitHub寄予的信任,並為構建的彈性系統讓我們平台能夠保持高可用性而引以為豪。但在這次事件中,我們讓您們失望了,對此深感抱歉。雖然我們消除不了GitHub平台長時間無法使用所帶來的問題,但我們可以解釋導致此事件發生的事件、吸取的教訓以及我們公司采取的步驟,以便更好地確保不再發生這種情況。

背景情況

面向用戶的GitHub服務大多數在我們自己的數據中心設施中運行。數據中心拓撲結構旨在提供一個強大且可擴展的邊緣網絡,該網絡在幾個區域數據中心的前端運行,為處理我們的計算和存儲工作負載提供支持。儘管該設計中的物理和邏輯部件已內置了多層冗余機制,但站點仍然有可能有一段時間無法彼此聯繫。

10月21日22:52UTC,由於100G光設備出故障,更換該設備的日常維護工作導致我們的美國東海岸網絡中心與我們主要的美國東海岸數據中心之間的連接斷開。這兩個地方之間的連接在43秒後恢復正常,但正是這次短暫的故障引發了一系列事件,導致服務品質下降了24小時又11分鐘。

GitHub網絡架構的大體描述,包括兩個物理數據中心、3個接入點(POP,又譯入網點)以及通過對等互聯(peering)的多個區域中的雲容量。

在過去,我們已討論了我們如何使用MySQL來存儲GitHub元數據以及為確保MySQL高可用性採用的方法。GitHub運行多個MySQL集群,集群大小從幾百GB到約5TB不等,每個集群最多有幾十個讀取副本來存儲非Git元數據,因此我們的應用程式可以提供合並請求(pull request)和問題單(issue)、管理身份驗證、協調後台處理,並且提供原始Git對象存儲之外的其他功能。應用程式不同部分的不同數據通過功能分區(sharding)存儲在各個集群上。

為了大規模提高性能,我們的應用程式將寫入引到每個集群的相關主系統,但在絕大多數情況下,將讀取請求委派給一小部分的副本伺服器。我們使用Orchestrator來管理我們的MySQL集群拓撲結構,並處理自動故障切換。Orchestrator在此過程中考慮了諸多變化因素,並建立在Raft之上以確保共識。Orchestrator可以實現應用程式無法支持的拓撲結構,因此必須小心謹慎,讓Orchestrator的配置與應用程式級別的期望保持一致。

事件時間線

10月21日22:52 UTC:

美國東海岸數據中心的數據庫伺服器含有無法複製到西海岸數據中心的短暫寫入內容。由於兩個數據中心中的數據庫集群現在含有另一個數據中心中沒有的寫入內容,我們在故障後無法將主數據庫安全地切換到東海岸數據中心。

10月21日22:54 UTC

內部監控系統開始發出警報,表明系統遇到眾多故障。工程師查明,眾多數據庫集群的拓撲結構處於意外的狀態。查詢Orchestrator API後顯示,數據庫複製拓撲結構隻包括來自西海岸數據中心的伺服器。

10月21日23:07 UTC

響應團隊決定手動鎖住內部部署工具,以防出現任何另外的變化。響應團隊將網站置於黃色警報狀態。情形自動更新為活躍事件,並向事件協調員發出警報。事件協調員加入進來,2分鐘後決定換成紅色警報狀態。

10月21日23:13 UTC

這時我們知道這個問題影響了多個數據庫集群。GitHub數據庫工程團隊的工程師開始調查現狀,以便搞清楚需要采取什麽措施,才能手動配置東海岸的數據庫作為每個集群的主數據庫,並重新構建複製拓撲結構。東海岸集群中的幾秒寫入數據沒有複製到西海岸,因而新寫入數據無法複製回到東海岸。

對於絕大多數數據庫調用而言,在東海岸運行、依賴將資訊寫入到西海岸MySQL集群的應用程式目前無法處理橫越全國的往回帶來的額外延遲。因此導致許多用戶無法使用我們的服務。但為了確保用戶數據的一致性,我們認為延長服務降級的時間是必要的。

10月21日23:19 UTC

查詢數據庫集群的狀態後,我們顯然需要停止運行中的任務,這些任務在寫入關於推送等操作的元數據。我們明確決定,暫停Web鉤子傳送和GitHub Pages構建,局部降低網站可用性,而不是危及我們已經從用戶處收到的數據。換句話說,數據完整性比網站可用性和恢復時間來得更重要。

10月22日00:05 UTC

事件響應團隊的工程師開始制定計劃以解決數據不一致性,並為MySQL落實故障切換程式。我們更新了狀態,告知用戶我們將對內部數據存儲系統執行有節製的故障切換。

雖然MySQL數據每隔4小時備份一次、保留多年,但備份內容存儲在異地的公共雲存儲服務中。恢復數TB備份數據花了幾小時,時間主要花在了傳輸來自遠程備份服務的數據上。解壓縮、校驗和、準備以及將龐大備份檔案裝入到剛配置好的MySQL伺服器上用去了大部分的時間。

10月22日00:41 UTC

開始對所有受影響的MySQL集群進行備份。同時,多個工程師團隊設法縮短傳輸和恢復時間,又不進一步降低網站可用性或導致數據損壞。

10月22日06:51 UTC

在東海岸數據中心,幾個集群完成了靠備份恢復的工作,開始複製來自西海岸的新數據。這導致對於在跨越全國的鏈路上執行寫入操作的頁面而言,網站加載時間緩慢,但如果讀取請求出現在剛恢復的副本上,從那些數據庫集群讀取數據的頁面會返回最新結果。其他較龐大的數據庫集群仍在恢復中。

10月22日11:12 UTC

所有主數據庫在東海岸再次建立。由於寫入內容現在被引到與我們的應用層在同一物理數據中心的數據庫伺服器,這導致網站響應極其緩慢。仍有眾多數據庫讀取副本比主數據庫延遲幾小時,因而導致用戶看到不一致的數據。我們將讀取負載分攤到龐大的讀取副本池上,針對我們服務的每個請求就很有可能“命中”延遲幾小時的讀取副本。

10月22日13:15 UTC

這時GitHub.com上的流量負載接近峰值。複製延遲在增加,而不是逐步降低。我們開始在東海岸公共雲配置更多的MySQL讀取副本。

10月22日16:24 UTC

副本同步後,我們切換到原始拓撲結構,以解決延遲/可用性問題。我們開始處理積壓的數據時,讓服務繼續處於紅色警報狀態。

10月22日16:45 UTC

我們不得不均衡分攤數據積壓帶來的更大負載,讓服務盡快回到100%的可用性。排入隊列的有500多萬個鉤子事件和8000多個Pages構建。

我們在重新處理這些數據時,處理了約200000個因超出內部TTL而丟棄的Web鉤子載荷。一發現這個問題,我們暫停了處理工作,暫時調高了該TTL。

為了避免進一步影響狀態更新的可靠性,我們仍處於性能降級狀態,直到處理完全部積壓的數據,並確保服務明顯回到正常的性能級別。

10月22日23:03 UTC

所有待處理的Web鉤子和Pages構建已處理完畢,所有系統的完整性和正常操作運行已得到了核實。網站狀態更新到綠色,以示正常。

結束語

我們知道您們的項目和公司多麽依賴GitHub。我們服務的可用性和您們數據的正確性備受關注。我們將繼續分析這次事件,以便有機會為您們提供更好的服務,並不負寄予我們的信任。

獲得更多的PTT最新消息
按讚加入粉絲團