節點、邊、方向
請求作為圖的行走
請求觸及的每個組件都是一個 節點 :客戶、DNS解析器、CDN邊緣、反向代理、後端副本、資料庫、快取。
兩個節點之間的每個連接都是一個 有向邊 :請求向前流動、響應向後流動。向前邊表示一個開啟的TCP連接加上上面的協議。
單個請求是一個 路徑 通過這個圖。系統為回答請求所做的總工作等於在每個節點上的工作之和加上每條邊的延遲。
為什麼關心? 一旦畫出圖,屬於程式碼中不可見的特性就會跳出:
- 跳數 :路徑中的邊數。每個跳增加延遲(網絡回合加節點處理)。少一些跳數就意味著延遲的下限更低。
- 入度 :指向一個節點的邊數。高入度意味著節點從多個來源接收請求並必須擴展或保護自己。
- 出度 :指向一個節點的邊數。高出度意味著節點依賴於多個下游並有多種失效方式。
- 切點節點 :一個單點節點,若其移除將使圖斷開。沒有同伴的反向代理是一個切點節點;移除它將移除對其源的所有訪問。
流量集中地點
Fan-In = Concentration
In-degree of a node = number of edges pointing into it. In a request graph, in-degree = number of upstream sources that send requests.
Fan-in pattern: many clients -> one CDN; many CDN edges -> few origin proxies; many proxies -> fewer backend replicas; many backends -> single database.
Concentration matters because the highest in-degree node sees the most aggregate load. The DB at the end of the chain may see queries from every active request in the entire system, even if no single user generates much.
Fan-Out = Dependency
Out-degree of a node = number of edges pointing out of it. High out-degree means many downstream dependencies.
A backend that calls a database, two caches, three external APIs, & a queue has out-degree 7. Its success probability is roughly the product of each downstream's success probability (if all are required for a successful response).
0.999 ^ 7 ≈ 0.993: a backend with 7 downstreams each at 99.9% reliability can only achieve ~99.3% reliability itself, even with no bugs of its own.
Reduce out-degree by: caching downstream results, making non-critical downstreams optional (graceful degradation), parallelizing what can be parallel.
The Asymmetry
Fan-in concentrates load; fan-out multiplies risk. A well-shaped graph minimizes both at the highest-impact nodes.
The database (highest fan-in): cache aggressively to reduce load. Read replicas to spread fan-in across multiple nodes.
The orchestrator service (highest fan-out): circuit breakers per dependency, graceful degradation, bulkheads.
插入節點購買靈活性
Indirection = Adding an Intermediate Node
Without a proxy, the graph is: client -> backend。The client must know about the backend's address。Moving the backend requires updating the client (via DNS or configuration)。This is a tight binding。
With a proxy, the graph becomes: client -> proxy -> backend。The client knows only about the proxy。Moving the backend requires updating the proxy's upstream configuration, not the client。
The graph operation: insert a node along an existing edge。The new edge client -> proxy is stable; the new edge proxy -> backend is now the team's to manage。
Geometric reading: indirection adds a layer that decouples upstream change from downstream change。Each layer's edges can rewire independently。
Cost of Indirection
Each layer adds:
- One hop of latency (the edge from client to proxy)
- One more cut vertex on the path (the proxy itself)
- One more place where misconfiguration can happen
The benefits (rewire, scale, shield, terminate TLS, distribute load) usually outweigh the costs for any non-trivial system。But there is a limit: every indirection layer adds another hop & another SPOF candidate。
The folklore rule: any problem can be solved by adding a layer of indirection (except the problem of too many layers of indirection)。
Read an Architecture as a Graph
Synthesis
You can now read a system architecture as a graph: count hops, identify cut vertices, measure fan-in concentration, compute availability ceilings from fan-out, & evaluate indirection trade-offs。
Apply all four。
這個架構的新服務:客戶端 -> CDN -> 反向代理(2個副本) -> 後端層(8個副本) -> { 主DB,缓存集群(3个节点),外部API }。
陪伴笔记
陪伴笔记
这个几何-lesson 将 Proxies & Origins 的主要lesson 转化为一个有向图分析。
接下来的陪伴在这个课程中,geometry_of_stateless_horizontal_scaling,将从主要的扩展lesson 中提取副本-数学,推导队列曲线,Little's Law,以及80%利用率弯的几何。
很好做。