@@ -20,7 +20,7 @@ breadcrumbs: false
2020* 如何定義和衡量系統的 ** 效能** (參見 [ "描述效能"] ( /tw/ch2#sec_introduction_percentiles ) );
2121* 服務 ** 可靠** 意味著什麼——即即使出現問題也能繼續正確工作(參見 [ "可靠性與容錯"] ( /tw/ch2#sec_introduction_reliability ) );
2222* 透過在系統負載增長時新增計算能力的有效方法,使系統具有 ** 可伸縮性** (參見 [ "可伸縮性"] ( /tw/ch2#sec_introduction_scalability ) );以及
23- * 使系統長期更 ** 易於維護** (參見 [ "可運維性 "] ( /tw/ch2#sec_introduction_maintainability ) )。
23+ * 使系統長期更 ** 易於維護** (參見 [ "可維護性 "] ( /tw/ch2#sec_introduction_maintainability ) )。
2424
2525本章介紹的術語在後續章節中也很有用,當我們深入研究資料密集型系統的實現細節時。然而,抽象定義可能相當枯燥;為了使這些想法更具體,我們將從一個案例研究開始本章,研究社交網路服務可能如何工作,這將提供效能和可伸縮性的實際案例。
2626
@@ -68,7 +68,7 @@ SELECT posts.*, users.* FROM posts
6868
6969如果由於某些特殊事件導致帖子速率激增,我們不必立即進行時間線交付——我們可以將它們排隊,並接受帖子在粉絲的時間線中顯示會暫時花費更長時間。即使在這種負載峰值期間,時間線仍然可以快速載入,因為我們只是從快取中提供它們。
7070
71- 這種預先計算和更新查詢結果的過程稱為 * 物化* ,時間線快取是 * 物化檢視* 的一個例子(我們將在 [ 後續章節 ] 中進一步討論這個概念)。物化檢視加速了讀取,但作為回報,我們必須在寫入時做更多的工作。對於大多數使用者來說,寫入成本是適度的,但社交網路還必須考慮一些極端情況:
71+ 這種預先計算和更新查詢結果的過程稱為 * 物化* ,時間線快取是 * 物化檢視* 的一個例子(我們將在 [ 待補充連結 ] 中進一步討論這個概念)。物化檢視加速了讀取,但作為回報,我們必須在寫入時做更多的工作。對於大多數使用者來說,寫入成本是適度的,但社交網路還必須考慮一些極端情況:
7272
7373* 如果使用者關注非常多的賬戶,並且這些賬戶釋出很多內容,該使用者的物化時間線將有很高的寫入率。然而,在這種情況下,使用者實際上不太可能閱讀其時間線中的所有帖子,因此可以簡單地丟棄其時間線的一些寫入,只向用戶顯示他們關注的賬戶的帖子樣本 [ ^ 5 ] 。
7474* 當擁有大量粉絲的名人賬戶釋出帖子時,我們必須做大量工作將該帖子插入到他們數百萬粉絲的每個首頁時間線中。在這種情況下,丟棄一些寫入是不可接受的。解決這個問題的一種方法是將名人帖子與其他人的帖子分開處理:我們可以透過將名人帖子單獨儲存並在讀取時與物化時間線合併,來節省將它們新增到數百萬時間線的工作。儘管有這些最佳化,在社交網路上處理名人仍然需要大量基礎設施 [ ^ 6 ] 。
@@ -93,7 +93,7 @@ SELECT posts.*, users.* FROM posts
9393
9494> [ !TIP] 當過載系統無法恢復時
9595
96- 如果系統接近過載,吞吐量被推到極限附近,它有時會進入惡性迴圈,變得效率更低,從而更加過載。例如,如果有很長的請求佇列等待處理,響應時間可能會增加到客戶端超時並重新發送請求的程度。這導致請求率進一步增加,使問題變得更糟——* 重試風暴* 。即使負載再次降低,這樣的系統也可能保持過載狀態,直到重新啟動或以其他方式重置。這種現象稱為 * 亞穩態故障* ,它可能導致生產系統的嚴重中斷 [ ^ 7 ] [ ^ 8 ] 。
96+ 如果系統接近過載,吞吐量被推到極限附近,它有時會進入惡性迴圈,變得效率更低,從而更加過載。例如,如果有很長的請求佇列等待處理,響應時間可能會增加到客戶端超時並重新發送請求的程度。這導致請求率進一步增加,使問題變得更糟——* 重試風暴* 。即使負載再次降低,這樣的系統也可能保持過載狀態,直到重新啟動或以其他方式重置。這種現象稱為 * 亞穩態故障(Metastable Failure) * ,它可能導致生產系統的嚴重中斷 [ ^ 7 ] [ ^ 8 ] 。
9797
9898為了避免重試使服務過載,你可以在客戶端增加並隨機化連續重試之間的時間(* 指數退避* [ ^ 9 ] [ ^ 10 ] ),並暫時停止向最近返回錯誤或超時的服務傳送請求(使用 * 熔斷器* [ ^ 11 ] [ ^ 12 ] 或 * 令牌桶* 演算法 [ ^ 13 ] )。伺服器還可以檢測何時接近過載並開始主動拒絕請求(* 負載卸除* [ ^ 14 ] ),併發送響應要求客戶端減速(* 背壓* [ ^ 1 ] [ ^ 15 ] )。排隊和負載均衡演算法的選擇也可能產生影響 [ ^ 16 ] 。
9999
@@ -193,7 +193,7 @@ Akamai 最近的一項研究 [^24] 聲稱響應時間增加 100 毫秒將電子
193193
194194如果系統在發生某些故障時仍繼續向用戶提供所需的服務,我們稱系統為 * 容錯的* 。如果系統不能容忍某個部分變得有故障,我們稱該部分為 * 單點故障* (SPOF),因為該部分的故障會升級導致整個系統的失效。
195195
196- 例如,在社交網路案例研究中,可能發生的故障是在扇出過程中,參與更新物化時間線的機器崩潰或變得不可用。為了使這個過程容錯,我們需要確保另一臺機器可以接管這項任務,而不會錯過任何應該交付的帖子,也不會複製任何帖子。(這個想法被稱為 * 精確一次語義* ,我們將在 [ 後續章節 ] 中詳細研究它。)
196+ 例如,在社交網路案例研究中,可能發生的故障是在扇出過程中,參與更新物化時間線的機器崩潰或變得不可用。為了使這個過程容錯,我們需要確保另一臺機器可以接管這項任務,而不會錯過任何應該交付的帖子,也不會複製任何帖子。(這個想法被稱為 * 精確一次語義* ,我們將在 [ 待補充連結 ] 中詳細研究它。)
197197
198198容錯總是限於某些型別的某些數量的故障。例如,系統可能能夠容忍最多兩個硬碟驅動器同時故障,或最多三個節點中的一個崩潰。如果所有節點都崩潰,沒有什麼可以做的,這沒有意義容忍任何數量的故障。如果整個地球(及其上的所有伺服器)被黑洞吞噬,容忍該故障將需要在太空中進行網路託管——祝你獲得批准該預算專案的好運。
199199
@@ -319,11 +319,11 @@ Akamai 最近的一項研究 [^24] 聲稱響應時間增加 100 毫秒將電子
319319
320320此外,適合一個負載級別的架構不太可能應對 10 倍的負載。如果你正在開發快速增長的服務,因此很可能你需要在每個數量級的負載增加時重新考慮你的架構。由於應用程式的需求可能會演變,通常不值得提前規劃超過一個數量級的未來伸縮需求。
321321
322- 可伸縮性的一個良好通用原則是將系統分解為可以在很大程度上相互獨立執行的較小元件。這是微服務背後的基本原則(參見 [ "微服務與無伺服器"] ( /tw/ch1#sec_introduction_microservices ) )、分片([ 第 7 章] ( /tw/ch7 ) )、流處理([ 後續章節 ] )和無共享架構。然而,挑戰在於知道在哪裡劃分應該在一起的事物和應該分開的事物之間的界限。微服務的設計指南可以在其他書籍中找到 [ ^ 84 ] ,我們在 [ 第 7 章] ( /tw/ch7 ) 中討論無共享系統的分片。
322+ 可伸縮性的一個良好通用原則是將系統分解為可以在很大程度上相互獨立執行的較小元件。這是微服務背後的基本原則(參見 [ "微服務與無伺服器"] ( /tw/ch1#sec_introduction_microservices ) )、分片([ 第 7 章] ( /tw/ch7 ) )、流處理([ 待補充連結 ] )和無共享架構。然而,挑戰在於知道在哪裡劃分應該在一起的事物和應該分開的事物之間的界限。微服務的設計指南可以在其他書籍中找到 [ ^ 84 ] ,我們在 [ 第 7 章] ( /tw/ch7 ) 中討論無共享系統的分片。
323323
324324另一個好原則是不要讓事情變得比必要的更複雜。如果單機資料庫可以完成工作,它可能比複雜的分散式設定更可取。自動伸縮系統(根據需求自動新增或刪除資源)很酷,但如果你的負載相當可預測,手動伸縮的系統可能會有更少的操作意外(參見 [ "操作:自動或手動再平衡"] ( /tw/ch7#sec_sharding_operations ) )。具有五個服務的系統比具有五十個服務的系統更簡單。良好的架構通常涉及方法的務實混合。
325325
326- ## 可運維性 {#sec_introduction_maintainability}
326+ ## 可維護性 {#sec_introduction_maintainability}
327327
328328軟體不會磨損或遭受材料疲勞,因此它不會像機械物體那樣以同樣的方式損壞。但應用程式的要求經常變化,軟體執行的環境發生變化(例如其依賴項和底層平臺),並且它有需要修復的錯誤。
329329
0 commit comments