跳至主要內容
跳到課程內容
課程目錄
技術與業務流程優化 效能調校與可擴展性設計
0%
18 / 25 進階 60 分鐘 00:00

考試領域 Analyzing and optimizing technical and business processes

效能調校與可擴展性設計

用 latency budget、快取、非同步處理與 backpressure 找出瓶頸,並以壓測驗證擴展能力

2026年3月13日 更新:2026年10月29日
本課目錄21 個段落

「系統很慢」還不是可調校的問題

先把抱怨翻成可量測的目標:哪一個 user journey、哪個 percentile、在哪個負載和地區,超過多少 latency?

例如:

台灣登入使用者在每秒 2,000 次結帳請求時,建立訂單 API 的 p99 server latency 應低於 800 ms,錯誤率低於 0.5%。

接著把 800 ms 拆成 latency budget:edge/load balancer、application、database、third-party 和 queue 各能用多少。用 trace 找 critical path、用 profiler 找 CPU hot path、用 metrics 看 saturation、用 logs 補事件 context。CPU 80% 不是通用故障門檻;某些 workload 在 90% 仍穩定,另一些在 40% 已因 single-thread 或 connection pool 卡住。

效能與擴展流程:端到端 request latency budget 分配到 CDN/cache、應用與資料庫;流量暴增時 backpressure 佇列限制下游進入速度,自動擴展再增加容量,最後以查詢、連線和監控資料定位真正瓶頸

圖解:先把 latency budget 分配到各段,再讓可共用內容走快取、動態工作走應用路徑;流量暴增時先用 backpressure 控制進入下游的速度,之後才談擴展與瓶頸調校。

先建立 baseline,再做單一變更

效能實驗至少記錄:

  • Traffic shape、request size、cache warm/cold、read/write ratio。
  • p50、p95、p99 latency 和 timeout/error rate。
  • CPU、memory、GC、thread、connection、queue depth、disk/network saturation。
  • Downstream quota、rate limit 與 third-party latency。
  • 每次實驗的版本、configuration 和成本。

一次只改一個主要變因,否則變快了也不知道原因。壓測還要有 soak、spike 和 failure test;短短五分鐘的平均 RPS 看不出 memory leak、autoscaling lag 和 retry storm。

Cloud CDN:快取前先定義資料是否能共用

Cloud CDN 能在 edge 回應 cacheable content,降低 user latency 和 origin load。三種主要 cache modes 是:

  • CACHE_ALL_STATIC:自動快取常見 static content,也尊重有效 origin cache directives。
  • USE_ORIGIN_HEADERS:只有 origin 提供有效 cache headers 才快取。
  • FORCE_CACHE_ALL:忽略 origin 的 private/no-store 等指令快取成功回應。

FORCE_CACHE_ALL 可能把個人化 HTML、API response 或 user-identifiable data 快取給其他人,不能只因 hit ratio 低就開啟。即使使用 signed URL,內容仍可能被 edge 快取;signed URL 控制存取時間,不代表內容不可共用。

Cache key 決定安全與命中率

Cache key 若包含所有 query、header 和 cookie,hit ratio 可能很低;排除太多,又可能把不同使用者的內容混在一起。設計前列出哪些 request attributes 真正改變 response,並測試:

  • Authenticated 與 anonymous response 是否分開。
  • Language、device、compression 和 experiment variant 是否影響內容。
  • Cache-Control、Vary、negative caching 和 serve-stale 行為。
  • TTL 到期與 invalidation 時,origin 能否承受 cache stampede。

Cache invalidation 是例外工具。常見做法是 versioned asset URL 搭配長 TTL,動態內容使用短 TTL 或 origin-controlled directives。

Memorystore:先選資料語意,再選 engine

Memorystore 目前包含 Valkey、Redis Cluster、Redis,以及已 deprecated 的 Memcached。新設計不應再把 Memcached 當預設候選。

選擇時看:

  • Client/command compatibility 和需要的 data structures。
  • 單一 instance 或 sharded cluster。
  • Replica、zone distribution、failover 和 SLA 要求。
  • Memory capacity、hot keys、eviction、persistence 與 recovery。
  • Private connectivity、region 和 maintenance behavior。

Cache 要被視為可遺失或可重建,除非你明確選擇並驗證它作為 primary data store 的 durability semantics。即使有 replica,failover 也可能中斷 connection 或遺失尚未複寫的最新 write,client 必須 timeout、retry 並重新連線。

Cache-aside 的兩個難題

  1. Stale data:database 更新後,cache 何時 invalidate/refresh?
  2. Stampede:熱門 key 到期時,大量 request 是否一起打到 database?

可以用 TTL jitter、request coalescing、single-flight、serve stale 或 background refresh 緩解。任何 cache optimization 都要同時量 hit ratio、staleness 和 origin load。

查看流程與節點文字

箭頭表示流程方向;方括號與引號內是節點名稱,可搭配下方圖解閱讀。

sequenceDiagram
  autonumber
  participant U as 使用者
  participant A as Application
  participant C as Cache
  participant D as Database
  U->>A: 讀取商品
  A->>C: GET product
  alt Cache hit
    C-->>A: 回傳 cached value
  else Cache miss
    C-->>A: miss
    A->>D: 查詢 authoritative data
    D-->>A: 回傳最新資料
    A->>C: SET value + TTL jitter
  end
  A-->>U: 回應商品
  U->>A: 更新商品
  A->>D: Transaction commit
  D-->>A: commit success
  A->>C: Delete/invalidate key
  Note over A,C: 下一次讀取重新填入 cache
讀取 miss 時才由資料庫補值;更新必須先確認 authoritative write 成功,再失效 cache,並用 TTL jitter 或 single-flight 降低同時回源。

Pub/Sub、Cloud Tasks、Scheduler 解的問題不同

Pub/Sub:發布事件給一個或多個 consumer

適合 producer 不需要知道所有 consumers 的 event distribution。Standard delivery 要假設 message 可能 redeliver,因此 consumer side effect 要 idempotent。

Exactly-once delivery 只支援 pull/StreamingPull subscriptions,並且 guarantee 受單一 cloud region 的 subscriber connection 條件限制。它能避免成功 ack 後重複 delivery,但 consumer crash、transaction boundary 和外部 side effect 仍需要自己的 idempotency/outbox 設計。

Ordering key 只保證相同 key 的順序,會降低可平行程度;dead-letter topic 也需要正確 IAM 與 retry 設定。不要為了「看起來更可靠」把所有訊息塞同一 ordering key。

Cloud Tasks:把一個 command 派送給指定 endpoint

Cloud Tasks 適合需要 queue-level dispatch rate、concurrency、schedule time 和精確 retry policy 的工作,例如控制第三方 API 或舊系統接收速度。Task ID 能在一定期間協助去重建立,但 execution 仍可能重試,handler 要 idempotent。

Cloud Scheduler:在時間點觸發

Scheduler 用 cron 呼叫 HTTP、Pub/Sub 或 App Engine target。Delivery 至少一次,因此「每日結算」不能假設只會執行一次;job 要用 business date/run ID 防重,並把長工作交給 job、workflow 或 queue。

簡單判斷方式:

  • 多個 subscriber 對「已發生事件」反應:Pub/Sub。
  • 要控制一個 endpoint 處理 command 的速度與重試:Cloud Tasks。
  • 要在某個時間啟動流程:Cloud Scheduler。
查看流程與節點文字

箭頭表示流程方向;方括號與引號內是節點名稱,可搭配下方圖解閱讀。

flowchart TD
  A["先描述工作如何被觸發"] --> B{"是依時間啟動?"}
  B -->|"是"| S["Cloud Scheduler<br/>觸發 HTTP、Pub/Sub 或 job"]
  B -->|"否"| C{"是一件已發生的事件<br/>要讓多個 consumer 反應?"}
  C -->|"是"| P["Pub/Sub<br/>fan-out 與獨立 subscription"]
  C -->|"否"| D{"要控制指定 endpoint 的<br/>dispatch rate、schedule 與 retry?"}
  D -->|"是"| T["Cloud Tasks<br/>派送 command"]
  D -->|"否"| R["重新確認需求:同步呼叫、<br/>Workflows 或 batch job"]
  S --> I["所有 handler 都要<br/>idempotent"]
  P --> I
  T --> I
先分辨時間觸發、事件散佈與受控 command,再選服務;三者都有重送或重試情境,不能省略 idempotency。

Backpressure 比自動擴展更早救系統

上游能快速擴展,下游 database 通常不能無限增加 connection。系統需要 backpressure:

  • API 設 admission control、quota 和清楚的 overload response。
  • Queue 設 dispatch rate/subscriber flow control。
  • Retry 使用 exponential backoff、jitter 和上限,避免 synchronized retry storm。
  • Circuit breaker 在 downstream 故障時快速失敗或降級。
  • Autoscaler 除了 CPU,也可看 concurrency、queue depth 或業務指標。
  • Maximum instances/workers 保護 downstream capacity。

Queue 只會把尖峰延後,不會消除工作。Capacity planning 要比較 arrival rate 與 sustainable processing rate,估算 backlog 清空時間和 message retention。

Maximum instances/workers 也是容量護欄的一部分,不是嚴格的資料庫連線保證;要連同 pool、部署重疊及平台擴縮例外計算。若還不能從每個 instance 的量測結果算出下游預算,先做第九課的容量演練。

離線演練:佇列能等,使用者能等多久?

預留 20 分鐘,用紙筆即可完成。先備能力是分清楚每秒進件、每秒完成、同時執行數與累積工作量;若還混淆,先寫出每個數字的單位。完成後,你應能算出 backlog、持續進件下的清空時間,並說明重試為何會改變可交付容量。

這是虛構訂單處理的簡化模型,不是 Cloud Tasks 的派送保證:起始 queue 為空、FIFO、各時段進件和完成速率固定、worker 已就緒、沒有故障或工作過期。初始計算先忽略重試;後面再改變這個條件。實際的長尾處理時間、擴縮、冷 queue、burst、重送和資料庫競爭都需要另測,因此算出的是理想化估計。

時段/條件已受理的不重複新訂單可完成的不重複訂單
前 120 秒尖峰每秒 200 筆每秒 120 筆
尖峰結束後,仍持續進件每秒 80 筆每秒 120 筆
業務期限每筆受理後 60 秒內完成排隊時間也計入

表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。

先交出四項成果:

  1. 尖峰結束時,queue 裡還有多少筆?
  2. 尖峰結束後,還要多久才清空?為什麼不能只用 backlog 除以 120?
  3. 尖峰結束時,新受理的一筆工作前面有這些 backlog,它是否一定能在 60 秒內完成?
  4. 若不能增加資料庫容量,寫出至少兩項可驗證的處理方式,以及使用者會看見什麼狀態。
算完再展開:清空速度要扣掉持續到來的新工作
  • 尖峰每秒多進 200 − 120 = 80 筆,120 秒後累積 80 × 120 = 9,600 筆 backlog。
  • 尖峰後每秒仍有 80 筆進件,淨減少速率是 120 − 80 = 40 筆/秒,清空需要 9,600 ÷ 40 = 240 秒。9,600 ÷ 120 = 80 秒只適用於沒有新進件時的清空估算。
  • FIFO 下,尖峰結束時新進工作僅等待前方 backlog 就約需 9,600 ÷ 120 = 80 秒,還沒加自己的執行時間,已無法符合 60 秒期限。能保存 9,600 筆工作不等於能準時交付。
  • 可在 admission 限制可受理流量、延後活動或採預約時段;超出者應明確顯示未受理/稍後重試,不能顯示完成。也可以改善查詢與處理流程後重測完成速率,或在業務正式同意後改成較長期限的非同步訂單,向使用者顯示排隊、處理與最終結果。
  • 若限制受理,仍要把被拒絕的需求留在業務與可用性報表中;不能只計算已入隊的工作,就宣稱原本全部需求都達標。只延長 queue retention 或無限重試不會增加每秒完成量。

改變條件:重試吃掉多少容量?

現在重新量測:worker 每秒總共只能處理 120 次 attempt,其中 30 次是重送、重複執行或尚未成功的重試;其餘 90 次各完成一筆新的不重複訂單。這裡直接給定 attempt 組成,不是假設「四分之一訂單重試一次」。

若尖峰已留下 9,600 筆、之後仍每秒新進 80 筆,清空要多久?若改成每秒新進 95 筆,又會發生什麼事?

參考答案:派送量不能當作成功交付量

可交付速率只剩 120 − 30 = 90 筆/秒。每秒進 80 筆時,淨減少 90 − 80 = 10 筆,清空需 9,600 ÷ 10 = 960 秒,即 16 分鐘。若新進 95 筆,queue 每秒增加 5 筆,這個固定條件下不會清空。

Idempotency 可避免重送造成重複扣款,但重複請求仍可能消耗網路、驗證、查詢與 worker 時間,不能在容量試算中視為零成本。先降低造成重試的瓶頸、限制 retry amplification 並重測;不能一看到 queue 長就把 worker 加到超過資料庫預算。

完整答案應包含 9,600 筆、240 秒、80 秒等待已超期限,以及改變重試條件後的 960 秒與持續增長。算對數字後,還要能說出受理、排隊與最終成功三種狀態的差別。

把模型變成可驗收設定

Cloud Tasks 的 max_dispatches_per_second 計入首次派送與重試,而且使用 token bucket,短時間可能 burst;max_concurrent_dispatches 則限制同時進行的工作數。兩者都不保證每秒有相同數量的業務成功,請對照官方 rate 與 retry 說明。冷 queue 的升速行為也要另查scaling risks。

本次驗收紀錄至少要一起保存 arrival、attempt、unique completion、oldest queue age、期限內完成比例,以及 downstream connections。先用實際量測估計 sustainable rate,再設定 dispatch、concurrency 與 admission;不要把上述理想化算式當成 p99 或平台 SLA。最後將重試與未完成量帶入第十七課的成功單位成本,避免把排隊造成的成本延後誤認為節省。

查看流程與節點文字

箭頭表示流程方向;方括號與引號內是節點名稱,可搭配下方圖解閱讀。

flowchart TB
  U["流量尖峰"] --> A["Admission control<br/>quota/overload response"]
  A --> Q["受限速的 queue<br/>保留可接受工作"]
  Q --> W["Workers<br/>有上限的 autoscaling"]
  W --> D["Database/第三方服務<br/>sustainable capacity"]
  D -->|"latency、error、connection"| M["Telemetry"]
  Q -->|"queue age/depth"| M
  M --> C["調整 dispatch、concurrency<br/>與 maximum instances"]
  C -. "形成保護邊界" .-> A
  C -. "形成保護邊界" .-> Q
  C -. "形成保護邊界" .-> W
Autoscaler 只負責增加 worker;admission、queue dispatch 與最大實例數共同限制進入下游的速度,才能避免 connection exhaustion 和 retry storm。

Database:先修 query 和 connection

  • 用 Query Insights/execution plan 找 slow query、lock 和 full scan。
  • 建 index、partition/cluster,並確認 write amplification 和 maintenance cost。
  • 控制 connection pool 大小;每個 autoscaled instance 都開一個大 pool,會很快耗盡 database connections。
  • Cloud SQL Auth Proxy/connector 提供安全連線與 IAM integration,不負責 connection pooling。Pooling 要在 application、sidecar 或合適 pooler 處理。
  • Read replica 能分擔允許 replica lag 的 read,不能拿來處理 read-after-write 或所有 transaction。

BigQuery 則要看 bytes scanned、partition pruning、shuffle、slot contention 和 concurrency。Reservation/edition 提供 capacity 管理,但 query design 仍然重要。

Gemini Cloud Assist:拿來縮小調查範圍

Gemini Cloud Assist 可以依支援功能協助理解 resource、log、metric 和建議。它適合快速整理可能原因或查詢入口,但不能取代 baseline、權限 review 和實驗。生成的 query、configuration 或調校建議都要由工程師驗證,尤其不要讓自然語言建議直接修改 production。

在架構上,應先確認它能看哪些 project data、誰能使用,以及互動如何留存和稽核。AI 助手能降低查資料時間,但最終證據仍是 telemetry 和可重現實驗。

情境練習:限時搶購

假設流量會在一分鐘內上升數十倍。

活動開始前,先列出三件事:你會先驗證什麼、過載時在哪一層擋、庫存以哪裡的數字為準。列完再展開對照。

列完再展開:參考設計
  1. 用 production-like load 重播登入、瀏覽、下單比例,找第一個 saturation point。
  2. Static assets 經 CDN,以 versioned URL 和正確 cache headers 減少 origin load;不快取購物車和個人化回應。
  3. Admission layer 依帳號/商品 rate limit,過載時回傳可重試但有 jitter 的 response。
  4. 下單 request 先產生 idempotency key;database transaction 或受控 reservation service 才是庫存 truth,不用單一 Redis decrement 當最終訂單依據。
  5. 若允許排隊,Cloud Tasks 依 database sustainable rate dispatch;使用者收到「排隊中」而不是假裝已下單成功。
  6. Notification 以 Pub/Sub event 解耦,email consumer 重試不影響訂單 commit。
  7. Autoscaling 設 minimum/maximum 和 downstream connection budget;活動前預熱並做 failover test。
  8. Dashboard 同時看 p99、error、queue age、inventory conflict、DB connection 和 CDN hit ratio。

課後檢查

往下看重點之前,先試著回答這幾題;答不出來,括號裡是該回去重讀的那一節。

  • Cache key 包含太多或排除太多,各會出什麼問題?(回〈Cache key 決定安全與命中率〉)
  • 上游已經能 autoscale,為什麼還需要 backpressure?(回〈Backpressure 比自動擴展更早救系統〉)
  • 有持續新進件時,如何算清空時間?為什麼派送 120 次不一定完成 120 筆?(回〈離線演練:佇列能等,使用者能等多久?〉)
  • Cloud SQL Auth Proxy 會不會幫你做 connection pooling?(回〈Database:先修 query 和 connection〉)

本課重點

  • 先把效能需求寫成 user journey、percentile、load 和 region,再拆 latency budget。
  • CPU 百分比不是通用答案;用 trace、profile 和 saturation 找真正 bottleneck。
  • CDN cache key/mode 錯誤可能洩漏個人化內容,安全和 hit ratio 要一起測。
  • Memorystore engine 要按 compatibility、sharding、HA、eviction 和 recovery 選。
  • Pub/Sub、Cloud Tasks、Scheduler 都可能重試,consumer/handler 必須 idempotent。
  • Exactly-once 有 subscription type 與 region 條件,不等於外部 side effect 自動 exactly once。
  • Autoscaling 前先做 backpressure 和 downstream capacity budget。
  • Cloud SQL Auth Proxy 不做 connection pooling;database scaling 先從 query 與 connection 著手。

延伸閱讀

下一步

下一課會談 API 與部署管理,從 consumer contract、auth、quota、版本相容性和 rollout verification 建立完整策略。

恭喜完成課程!

你已完成所有課程內容,做得太棒了!

25 課完成
22 小時 25 分鐘 預估課程時數
— 天連續學習

鍵盤快捷鍵

先關閉此說明再使用快捷鍵;輸入筆記時不會觸發。

導覽
← / j 上一課
→ / k 下一課
操作
c 標記完成 / 取消完成
n 展開 / 收合筆記
b 收藏 / 取消收藏
f 專注模式
其他
? 快捷鍵說明
Esc 關閉彈窗

課程目錄

徽章解鎖!
Nimbus

學習教練 Nimbus

你的雲端學習夥伴

依已保存的資源進度與學習目標提供練習建議。完成度不代表掌握程度或應考能力。

0
連續天數
0
確認讀完
0
收藏
0%
資源完成度
練習建議
    推薦下一步
    開始