什麼是可擴展性?先認識三個絆腳石
不是「跑得更快」,而是「工作量變大時,還撐得住」——而且撐得起錢
當使用者突然變成十倍
想像你寫了一個小網站,平常一天只有一百個人來逛。某天它上了熱門版,一小時內湧進十萬人——網頁開始轉圈、有人按不動、有人乾脆看到錯誤畫面。這時你要問的問題就是:這個系統「可擴展」嗎?
所謂 可擴展性(scalability),講的不是「平常跑多快」,而是「當工作量往上加,系統還能不能穩住效能」。它是一種面對成長時的體質,而不是一次性的性能數字。
可擴展性像一間麵店的擴張能力。中午突然來了三倍客人,好擴展的店可以再開一口爐、多請一個人手、把座位往外擺,出餐速度幾乎不掉;不好擴展的店只有一個老闆一口鍋,客人再多也只能排隊乾等。差別不在「這口鍋現在煮多快」,而在「人變多時,能不能順順地加鍋、加人」。
ByteByteGo 怎麼定義:原文對照
可擴展性有兩種看法:一種只看「效能撐不撐得住」,另一種還要看「用的策略划不划算」。直接讀原文最精準——注意第二段特別把成本拉了進來:
可擴展性,是一個系統在工作量增加時仍能維持效能不掉的能力。
不過,我們也可以換個角度,從「擴展策略」來看它。
也就是說:可擴展性是系統靠反覆施行一套「成本可行」的策略,去消化增加工作量的能力。
這意味著——如果擴展策略在財務上不可行,那麼過了某個點之後,系統就很難再擴下去了。
技術上能擴,不代表就擴得起。原文特別點出:如果每加一倍流量就得砸一大筆錢、而且無法重複套用同一招,那過了某個點就擴不動了。真正的可擴展,是找到一套能一再重複、又付得起的做法。
擋在擴展路上的三大瓶頸
為什麼系統會擴不動?原文點名三個常見的 瓶頸。它們就像麵店裡「只有一口鍋」「湯要熬三小時」「所有工序卡在同一個人身上」——每一個都會讓你想加人加鍋卻加不上去。
整個系統擠在單一元件上運作。原文直言:這會變成一個 單點故障(single point of failure)——它一倒,全系統跟著倒。就像整間店只有一口鍋,鍋一壞就全停。
原文的說法是:這些元件會執行耗時的操作(time-consuming operations)。一個慢動作的環節就能拖垮整條流水線,後面全部排隊等它,像那鍋要熬三小時的湯。
元件之間綁得太死、彼此高度依賴。原文說:這會讓元件難以擴展——你想單獨放大其中一塊,卻被綁在一起的其他部分拖住,動一髮牽全身。
三大瓶頸・原文逐字對照
這三條在原文裡是編號列點,字很省,但每一句都有重點,值得逐字看一次:
可擴展性的三大瓶頸是:
1. 集中式元件:它可能變成一個單點故障——壞了就全垮。
2. 高延遲元件:這些是會執行耗時操作的元件,慢的那個拖垮全部。
3. 緊密耦合:讓元件彼此難以擴展,想單獨放大一塊卻被綁死。
認得了三個絆腳石,接下來就要學怎麼繞過它們——先看三大設計原則,再看四招業界最常用的擴展技巧,最後親手把技巧拖去解決對應的瓶頸。往下捲。
三大原則、四招技巧,動手對症下藥
先立好設計原則,再學四招最常用的擴展技巧,最後把技巧拖去解決對的瓶頸
可擴展系統該遵守的三大原則
知道了三個瓶頸,原文接著給出對策的總方針。它說:要打造可擴展的系統,就該遵循三大原則——這三條剛好一一對上前面的三個瓶頸。
無狀態指伺服器不把使用者狀態記在自己身上。這樣任何一台機器都能接任何請求,可以隨意加機器分攤——直接化解「集中在單一元件」的風險。
鬆散耦合是「緊密耦合」的反面:讓元件之間別綁得太死,各自能獨立變更、獨立放大。動一塊不必牽動全身。
非同步處理指耗時的工作丟去背景慢慢做,呼叫方不必卡在原地枯等——直接對付「高延遲元件」拖垮全線的問題。
因此,要打造可擴展的系統,我們應該遵循三大原則:無狀態、鬆散耦合,以及非同步處理。
四招最常用的擴展技巧
原則是方向,技巧是招式。原文列出四個提升可擴展性的常見技巧,每一招都在拆解前面某一個瓶頸。先逐字看原文:
一些提升可擴展性的常見技巧如下:
負載平衡(Load Balancing):把請求分散到多台伺服器,避免單一台變成瓶頸。
快取(Caching):把最常被請求的資訊存在記憶體裡。
事件驅動處理(Event-Driven Processing):用非同步的方式處理長時間運行的任務。
分片(Sharding):把一個大資料集切成較小的子集(稱為 shard),以做到水平擴展。
把大量請求分散到多台伺服器,讓沒有任何一台被壓垮。原文的原話:避免單一伺服器變成瓶頸——正對「集中式元件」而來。
把最常被要的資料先存進記憶體,下次直接從記憶體拿,不必每次都去跑那個慢吞吞的來源——正對「高延遲元件」而來。
用非同步的方式處理長時間任務:發出事件、丟去背景,各元件靠事件溝通而不直接互相等待——鬆開了「緊密耦合」。
把一個大資料集切成一小塊一小塊(shard)分散存放,達成 水平擴展(horizontal scalability)——不再把所有資料擠在同一個集中處。
動手配對:這招最直接在拆什麼?
把下面四個擴展技巧,各自拖到它最直接對應的那個痛點下面。線索都藏在原文對每招的描述裡:注意原文形容 Load Balancing 針對「單一伺服器」、Sharding 針對「單一大資料集」——兩者角度不同,各有各的格子。拖完按「對答案」。
原文並沒有把四招技巧一一對應到瓶頸——這裡的配對是依「原文對每招的描述」推出的最直接對應,方便你建立直覺。現實裡一招常常同時解好幾個瓶頸:快取也能減輕後端負載、負載平衡也牽涉無狀態設計、分片同時分散了資料與請求。這個練習還特別把 Load Balancing(分散請求、對付單一伺服器)和 Sharding(分散資料、對付單一大資料集)拆成兩格,因為原文形容它們的角度不同——但兩者骨子裡都是同一句話:別把東西集中在一處。抓主軸就好,別鑽牛角尖。
收束:小試身手
把整章串起來——原則對瓶頸、技巧對原則。來三題確認你都接上了:
可擴展性=工作量變大時效能不掉,而且要靠一套成本可行、能反覆施行的策略。三大瓶頸:集中式元件(單點故障)、高延遲元件、緊密耦合。三大原則:無狀態、鬆散耦合、非同步處理。四招技巧:Load Balancing、Caching、Event-Driven Processing、Sharding。原文最後留給你一個問題——「換你了:你都怎麼提升系統的可擴展性?」