非功能需求 (Nonfunctional Requirements)

★★★★Draft

FromDDIASystem Design Interview

📚 From the Books

非功能需求 (Nonfunctional Requirements)ConceptFundamentals

功能需求講「系統要做什麼」,非功能需求講「系統要做得多好」——夠不夠可靠、能不能撐住成長、好不好維護。這三個詞業界天天講,卻常缺精確定義。把它們拆清楚,才有辦法在設計時談取捨、在面試時給訊號。

🧠 Core Ideas

TIP

三大支柱:Reliability(可靠性) =出問題還能正確運作;Scalability(可擴展性) =負載長大時有辦法應對;Maintainability(可維護性) =工程與營運團隊能持續高效地維護演進。三者都沒有銀彈,但都有反覆出現的模式。

⚖️ Reliability:容錯而非防錯

Fault 與 Failure 不同
  • Fault=某個元件偏離規格;Failure=整個系統停止對外服務。容錯的目標就是阻止 fault 演變成 failure
  • 多數情況偏好容忍故障而非預防——甚至刻意注入故障來驗證容錯,Netflix 的 Chaos Monkey 隨機終止生產程序就是代表。
  • 例外:安全性問題預防遠重於容忍,因為一旦敏感資料外洩就無法逆轉。
三類故障來源
  • 硬體故障:硬碟 MTTF 約 10–50 年,一萬顆硬碟的叢集平均每天壞一顆。傳統靠冗餘(RAID、雙電源),雲時代轉向軟體層容錯,順帶換來滾動升級不停機。
  • 軟體錯誤:系統性、會跨節點關聯(如 2012 閏秒觸發 Linux 核心 bug)、級聯故障。沒有銀彈,靠測試、隔離、監控。
  • 人為錯誤:最不可靠的元件。研究顯示大型網路服務停機主因是配置錯誤,硬體只佔 10–25%。對策:設計不易出錯的介面、沙箱、自動化測試、快速回滾、完善監控。

⚖️ Scalability:先量化負載,再談效能

用負載參數描述負載
  • 負載參數(load parameters) 依架構而定:每秒請求數、讀寫比、同時活躍使用者數、快取命中率。
  • Twitter 案例:發推 4,600 次/秒、讀主頁時間線 30 萬次/秒。挑戰在 fan-out——寫入時展開投遞給每個追蹤者(讀取快),但名人有 3,000 萬追蹤者、一則推觸發 3,000 萬次寫入,最終走混合式(一般人寫入展開、名人讀取合併)。關鍵負載參數是每人的追蹤者數分布
用百分位數描述效能
  • Latency ≠ Response time:response time 是客戶端觀察到的完整時間(含處理 + 網路 + 排隊);latency 特指請求等待被處理的潛伏時間。
  • 別用平均值描述典型回應時間——用百分位數:p50(中位數)、p95、p99、p999。
  • 高百分位=尾端延遲(tail latency),直接影響體驗。Amazon 用 p999 定義內部服務要求,因為最慢的客戶往往是資料最多、最有價值的客戶;其研究顯示回應時間多 100ms,銷售掉 1%。
  • 微服務的尾端延遲放大:一個請求扇出到多個後端,遇到至少一個慢呼叫的機率大增。
  • 百分位數用來定義 SLO(服務層級目標)SLA(服務層級協議):如中位數 < 200ms、p99 < 1s、可用率 ≥ 99.9%。
  • 陷阱:百分位數不能取平均——多台機器的 p99 不能平均成整體 p99,要合併直方圖再算。
可用性:以「幾個 9」衡量
  • 高可用以百分比計,多數服務落在 99%–100%;Amazon / Google / Microsoft 等雲端 SLA 多設在 99.9% 或更高
  • 9 越多、停機越少:99% 一年約停機 3.65 天;99.99% 約 52.6 分鐘;99.999% 約 5.26 分鐘。
  • 詳細的量級估算見 Back-of-the-envelope 估算
應對負載:垂直 vs 水平
  • 垂直擴展(scale up)=換更強的機器;水平擴展(scale out)=把負載分散到多台小機器,即 shared-nothing。好的架構通常是務實混合。
  • 彈性(elastic) 系統偵測負載自動擴;手動擴展更簡單、意外更少。
  • 無狀態服務好分散,有狀態資料系統分散化代價高——過去常做法是盡量讓 DB 留單節點,直到成本或高可用逼你分散。詳見從零到百萬用戶

⚖️ Maintainability:讓維護不痛

三個設計原則

軟體成本大半在持續維護而非初次開發。三原則:

  • Operability(可操作性):讓營運團隊好過——良好監控、標準工具整合、避免依賴單機、清晰文件與運維模型、合理預設。
  • Simplicity(簡單性):移除偶發複雜度(實作引入、非問題本身固有的);最強工具是抽象——把實作細節藏在乾淨介面後(高階語言之於機器碼、SQL 之於磁碟結構)。
  • Evolvability(可演化性):讓變更容易。與簡單性、抽象品質高度相關——例如把 Twitter 時間線架構從「讀取合併」重構成「寫入展開」這種資料系統層級的敏捷。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading