1. 簡介 1.1. 在過去20年裡,軟體系統的規模、複雜性和容量都出現了前所未有的增長 1.2. 代碼是容器、資料庫、消息傳遞系統和其他組件的一部分,通過調用API和構建指令,構成你的應用程式 1.3. 可擴展(scalable)是軟體工程中用來描述軟體系統能夠適應增長的術語 1.3.1. 可擴展 ...
1. 簡介
1.1. 在過去20年裡,軟體系統的規模、複雜性和容量都出現了前所未有的增長
1.2. 代碼是容器、資料庫、消息傳遞系統和其他組件的一部分,通過調用API和構建指令,構成你的應用程式
1.3. 可擴展(scalable)是軟體工程中用來描述軟體系統能夠適應增長的術語
- 1.3.1. 可擴展性是一個非常簡單的概念
1.4. 快速且低成本地擴展應用程式的能力應該是當代面向互聯網的應用程式的軟體架構的決定性質量
2. 定義
2.1. 維基百科對它的定義是“可擴展性是通過添加更多資源來處理越來越多的工作的系統屬性”
2.2. 與物理系統不同,軟體系統在某種程度上是無定形的
-
2.2.1. 它們並非是通過外部觀察就能瞭解其內部行為的東西
-
2.2.2. 一個軟體系統就是一個數字工件(artifact)
2.3. 不同運營維度的例子
-
2.3.1. 系統可以同時處理的來自用戶或外部設備(例如感測器)的請求的數量
-
2.3.2. 系統可以有效處理和管理的數據量
-
2.3.3. 對系統存儲的數據進行預測分析而獲得的價值
-
2.3.4. 隨著請求量的增長,系統保持穩定、一致的響應時間的能力
2.4. 在開發和部署的早期階段,可擴展性並不是主要的質量要求
- 2.4.1. 在有明確的需求之前引入一些複雜的分散式技術可能對項目有害,額外的複雜性會導致開發過於保守
2.5. 成功擴展系統關係到許多現代互聯網應用程式的生存問題
- 2.5.1. 在系統的發展過程中,提高系統性能和可擴展性成為當務之急甚至影響系統存亡的現象比比皆是
2.6. 往往存在一個臨界點,在輕負載下有意義的設計和決策突然變成了技術債務
2.7. 通過增加資源來增加系統在某個維度上的容量稱為縱向擴展(scaling up)或橫向擴展(scaling out)
2.8. 與物理系統不同,能夠按比例縮小(scale down)系統容量以降低成本同樣重要
- 2.8.1. 一個非常典型的例子是Netflix,它需要處理來自不同區域的可預測的晝夜請求
2.9. 案例
-
2.9.1. Scribe是一種自定義緩存隊列解決方案,它可以以每秒幾TB的速率從伺服器傳輸日誌,並將它們傳送到下游分析和數據倉庫系統中
-
2.9.2. 互聯網站點提供的關於服務規模的真實且具體的數據仍然是商業機密
3. 軟體系統發展簡史
3.1. 1980~1989
-
3.1.1. 一個由分時主機和小型機主宰的時代
-
3.1.2. 個人電腦出現於20世紀80年代初期,但很少聯網
-
3.1.3. 萬維網在20世紀80年代誕生於歐洲核子研究中心(CERN),由Tim Berners-Lee首創
3.2. 1990~1995
-
3.2.1. 網路變得更加普遍,為基於HTTP/HTML的萬維網(WWW)技術的出現創造了成熟的環境
-
3.2.2. 1994年雅虎(Yahoo!)創立
-
3.2.3. 1995年亞馬遜和eBay誕生
3.3. 1996~2000
-
3.3.1. 網站數量從10000左右增長到1000萬
-
3.3.2. 亞馬遜、eBay、谷歌和雅虎等公司已經開創了許多設計原則和先進技術的早期版本
3.4. 2001~2006
-
3.4.1. 網站數量從約1000萬個增長到8000萬個
-
3.4.2. 2005年,YouTube推出
- 3.4.2.1. 第一次上傳視頻到YouTube發生在2005年
-
3.4.3. 2006年,Facebook向公眾開放
- 3.4.3.1. 亞馬遜網路服務(AWS)重新推出了S3和E C2服務
3.5. 2007至今
-
3.5.1. 大約擁有20億個網站
-
3.5.2. 大約有40億互聯網用戶
4. 可擴展性系統設計基本原則
4.1. 擴展系統的基本目標是在應用程式的某些特定維度上增加容量
4.2. 一個常見的維度是增加系統在給定時間段內可以處理的請求數量
- 4.2.1. 系統的吞吐量
4.3. 複製
-
4.3.1. 在軟體系統中增加容量的第一個策略
-
4.3.2. 我們基本上複製了軟體中處理請求的資源,以提供更多的請求處理能力,從而提高吞吐量
-
4.3.3. 在基於雲的軟體系統中,只需點擊滑鼠即可實現複製,我們可以有效地複製用來處理請求的資源,高達數千倍
4.4. 優化
-
4.4.1. 如果我們通過以下方法可以優化請求的處理,那麼可以在不增加資源的情況下提高系統能力
-
4.4.1.1. 使用更有效的演算法
-
4.4.1.2. 在資料庫中添加額外的索引以加快查詢速度
-
4.4.1.3. 用更快的編程語言重寫伺服器
4.4.1.3.1. Facebook創建的用於PHP的HipHop
4.4.1.3.2. HipHop將PHP代碼編譯為C++,將Facebook的網頁生成速度提高了6倍
-
5. 可擴展性與成本
5.1. 對於某些應用程式,需要承擔修改業務系統來滿足最終業務需求的成本
5.2. 不應該期望一個沒有採用可擴展架構、機制和技術的軟體系統快速發展以滿足更大的容量需求
5.3. 在成本線性增長的同時支持指數級擴展的軟體系統被稱為超大規模系統
6. 權衡
6.1. 可擴展性是非功能性需求,它只是眾多質量屬性之一
6.2. 經驗豐富的軟體架構師非常註意分寸,他們精心設計系統來滿足高優先順序的質量屬性,同時儘量減少對其他質量屬性的負面影響
7. 可用性
7.1. 可用性和可擴展性通常是高度相容的“合作伙伴”
-
7.1.1. 當我們複製資源來擴展自己的系統時,我們創建了多個服務實例,可用於處理來自任何用戶的請求
-
7.1.2. 如果一個實例出現故障,則其他實例仍然可用
-
7.1.3. 系統容量減少的原因只是應用程式出現故障或資源不可用
7.2. 可用性是指系統即使在對手的攻擊下也仍然保持可靠運行的能力
7.3. 來自對手的攻擊可能是試圖利用系統設計弱點使系統癱瘓
7.4. 另一種攻擊則是經典的分散式拒絕服務(DDoS),在這種攻擊中,對手獲得了對眾多系統和設備的控制權,並協同大量請求,使得受害系統不可用
8. 安全性
8.1. 安全系統的基本要素是身份驗證、授權和數據完整性
8.2. 安全性是所有面向互聯網的系統的必要質量屬性
8.3. 構建安全系統的成本是不可避免的
8.4. TLS使用非對稱加密提供加密、身份驗證和數據完整性能力
-
8.4.1. 由於雙方都需要生成和交換密鑰,所以會產生性能成本
-
8.4.2. 建立連接後,傳輸中的數據將使用對稱加密技術進行加密,由於現代CPU具有專用的加密硬體,因此這部分的性能損失可以忽略不計
-
8.4.3. 建立連接通常需要在客戶端和伺服器之間進行兩次消息交換,因此速度較慢
-
8.4.4. 儘可能重用連接可以最大限度地減少性能開銷
8.5. 保護靜態數據
-
8.5.1. SQL Server和Oracle等流行資料庫引擎具有透明數據加密(TDE)等功能,可提供高效的文件級加密
-
8.5.2. 靜態安全數據的開銷是實現安全性必須承擔的成本
- 8.5.2.1. 研究表明開銷在5%~10%的範圍內
8.6. 一般來說,安全性和可擴展性是對立的力量
-
8.6.1. 安全必然會導致性能下降
-
8.6.2. 系統包含的安全層越多,性能和可擴展性的負擔就越大
9. 可管理性
9.1. 用於描述這種複雜監控功能的術語是可觀測性
9.2. 指標對於洞察系統是非常寶貴的,它有助於確保持續運營,以及凸顯系統中可能需要優化或複製的部分
9.3. 擴展系統總是意味著添加新的系統組件——硬體和軟體
- 9.3.1. 它增加了系統操作的複雜性和監控成本,這需要開發更多的監控代碼來調整可觀測平臺,確保其監控了新的系統組件
9.4. 在擴展時,控製成本和可管理性的複雜性的唯一方法是自動化
9.5. DevOps自動執行系統的持續測試、部署、管理、升級和監控,縮短了新功能的開發生命周期
- 9.5.1. 它是所有成功的可擴展系統的組成部分