保持系統簡單的六個經驗教訓

2024.12.12

在AWS re:Invent大會上,CTO Werner Vogels分享了亞馬遜在系統設計方面的一些基本經驗教訓。

譯自Werner Vogels' 6 Lessons for Keeping Systems Simple,作者 Joab Jackson。

“實體不應無故增多”——威廉·奧卡姆,奧卡姆剃刀

且不說亞馬遜網路服務 (Amazon Web Services),這家雲巨頭已經能夠在其系統和服務上擴展超過二十年,不斷推出新功能,同時保持用戶體驗易於管理。

在其慣例週四主題演講中,AWS 首席技術官Werner Vogels分享了他二十年來在雲巨頭工作的經驗中,關於保持簡單的一些經驗教訓。

複雜性總是潛入系統設計中,因此工程師必須勤勉地管理這種複雜性。

目標始終是“以安全的方式擴展我們的系統,使其隨著時間的推移變得更加複雜”,他說道。

從靈活到致命

目標不是消除複雜性,而是有效地管理它。

增強任何系統時的危險在於它帶來了不必要的複雜性,這難以維護,並剝奪了用戶的樂趣。

但正如 Larry Tesler所指出的,複雜性無法消除,只能轉移。

現在,存在良好的複雜性,這是為了幫助系統發展而添加的; 然後是那種在沒有架構監督的情況下發生的複雜性,它只會減慢使用者速度,並使系統更難以維護,他解釋道。

複雜性不僅取決於系統中元件的數量,還取決於這些元件的排列方式。

“你無法將給定任務的複雜性降低到某個點以下。 一旦達到這一點,你只能轉移負擔。 "——Larry Tesler

在這裡,Vogels 以自行車設計為例。

實際上,自行車最簡單的形式是獨輪車,它只有一個輪子。 獨輪車非常靈活(“它們可以原地轉彎”),但很難騎。

另一方面是三輪車,它們很容易騎,但笨重且難以操縱,任何騎過三輪車的人都知道。

最好的設計實際上是兩輪自行車,它兼具易用性和靈活性。

“自行車有更多元件,但從整體角度來看,它是最簡單的形式,”他說道。 自行車成為最流行的自行車形式並非偶然。

將複雜性放在需要的地方。

Amazon S3(簡單存儲服務)就是一個例子,它只提供最終一致性,而不是強一致性。 這意味著如果客戶購買了 Amazon S3 儲存桶,它最終會可用,但可能不會立即可用。

然而,客戶希望獲得強一致性,並已開始構建變通方案,以確保在其自身設計中基於 S3 實現強一致性,這導致了他們自身系統中不必要的複雜性。

AWS 最終重新設計了 S3 以實現強一致性,“將複雜性轉移到需要的地方”,即遠離客戶。

那麼,系統工程師如何管理他們自己系統中的複雜性呢?

Vogels 提供了六個技巧:

1. 構建能夠發展的系統

不向前發展的軟體系統會消亡。 即使是最穩定的軟體也會看到世界在沒有它的情況下前進。

此外,誰不想看到自己喜歡的應用程式擁有新功能或運行速度更快?

你的系統會隨著時間的推移而發展,你需要修改你的架構,Vogels 建議道。

“每當你改變數量級時,你都需要重新審視你的架構,”Vogels 說。 當 S3 推出時,設計工程師知道他們將改變架構。 隨著時間的推移,儘管其 API 的佔用空間很小,但它積累了驚人的功能範圍。

“你會看到,每年我們都會添加新功能,而不會對我們為客戶提供的功能產生任何影響,”他說。

網路服務也是如此,在使用者的請求下,網路服務得到了顯著的發展。

“我們知道,無論我們在 2006 年為您提供的網路功能是什麼,到 2010 年肯定會在 2020 年發生根本性的變化,”Vogels 說。

你需要制定一個策略來應對複雜性,這種複雜性會隨著時間的推移在你的系統中增長。

Vogels 說,可進化性是管理複雜性的前提條件。

2. 打破複雜性

複雜性可能會潛入你的應用程式,就像諺語中青蛙湯里的熱量一樣。

“小的變化起初似乎很容易管理、很容易吸收,但如果你忽略了警告信號,系統就會變得越來越複雜,越來越難以管理和理解,”他說。 答案是將系統分解成多個更易於管理的元件。

Amazon CloudWatch最初是一個簡單的監控服務。 隨著更多功能的添加,每個功能都載入登錄頁面上,直到頁面變得非常繁忙,AWS 才重新設計了它,使其只保留核心功能。 其他功能被遷移到它們自己的環境中。

服務應該有多大? 它應該能夠容納在一個工程師的腦子裡。

“如果你無法記住它,你的服務通常就太大了,”Vogels 說。

3. 將架構與業務需求對齊

Vogels 說,通過完善的 API 構建具有「智慧端點」和「細粒度介面」的業務重點元件。 將它們分散,以便它們「獨立發展」。

企業技術並非為了自身而構建。 它是為客戶而構建的。 因此,系統架構師需要與他們服務的營業單位緊密合作。

協作至關重要。 營業單位可能會說它需要 100% 的正常運行時間。 這是可行的,但代價高昂。 因此,系統設計師可能需要指出 100% 的可靠性將有多昂貴。

“然後你們就可以進行對話了,”他說。

Vogels 曾說過,一切都會一直失敗。 所以訣竅是計劃失敗。

4. 將工作組織成單元

隨著應用程式的流行和功能的增加,它在操作方式上也會產生複雜性。 考慮使用基於單元的架構來保持這種日益增長的複雜性的簡單性。

“構建系統的時間通常比運行系統的時間要少得多。 因此,提前投資可管理性至關重要,“Vogels 說。

管理這些操作也必須分解成更小的構建塊。 這是為了減少影響範圍,這對於最大限度地減少停機時間至關重要。

“單元在複雜系統中創造秩序,”他說。 “它們將問題隔離到特定單元,而不會影響其他單元。”

需要一個路由器和控制平面將請求路由到各個單元。 路由標籤可以基於區域ID、主機ID、客戶ID。

“隨著時間的推移,分解成單元將有助於您維護客戶的可靠性和安全性,”他說。

5. 設計可預測的系統

不確定性難以處理。 因此,提前設計您的系統以減少不確定性。

AWS 為其面向客戶的負載均衡器運行一個超平面,以處理數百萬客戶用來更改配置的所有更改。

令人驚訝的是,AWS 沒有使用事件驅動架構來設置此服務,這與普遍的看法相反,對於此任務來說是一種糟糕的方法,因為來自使用者的負載請求速率將是不可預測的。

相反,AWS 將更改寫入 S3 檔,負載均衡器以定期輪詢間隔提取這些檔。

“簡單需要紀律”——AWS 首席技術官 Werner Vogels

“這是一種我們稱之為持續工作的模式,”Vogels 說。 這種方法避免了峰值、積壓和瓶頸,並且還使系統能夠自我修復,因為“S3 是不可滲透的。 ”

AWS 的Route 53功能變數名稱服務在其運行狀況檢查器上採用相同的原理:輪詢而不是排隊。

6. 自動化所有事務

要管理複雜性,就自動化複雜性。

AWS 使用自動化來完成許多任務,甚至包括構建新的區域,這是完全自動化的。

問題不在於自動化什麼,而在於什麼不自動化。 只有那些真正需要人工參與的決策才應該有人工干預。 其他一切事情都應該自動化。

“自動化應該是標準,例外情況是我們需要人工參與,”Vogels 說。 “手動輸入只應在真正需要人工判斷的領域中需要。”

安全是 AWS 的一個高度自動化的流程,其中包括自動化威脅情報等流程。 AWS 每天收到「數萬億」個 DNS 更改請求,每天至少識別 100,000 個惡意功能變數名稱,這通過一個自動化流程完成——這是一個手工無法完成的流程。

支援票證是另一個適合自動化的領域通過代理。 代理最適合非常狹窄的用例,在這些用例中,它們被賦予了一系列工具,可以通過稱為“無伺服器提示鏈”的流程來解決問題。

如果代理無法解決問題,只需將其提請人工注意。

“自動化所有不需要高度判斷力的事情,”Vogels 說。