2009 - DevOps 與持續部署:每天十次部署的膽量#
案件摘要#
2009 年 6 月,Flickr 的 John Allspaw 與 Paul Hammond 在 Velocity 大會發表演講 「10+ Deploys Per Day: Dev and Ops Cooperation at Flickr」,展示開發與維運協作讓部署頻率達到每天十次以上。 同年,比利時獨立顧問 Patrick Debois 受演講啟發創辦 DevOpsDays,"DevOps" 一詞自此誕生。 這個案子偵破的兇手是開發與維運之間的那道牆——以及牆兩邊互相矛盾的獎勵制度。
前因 -- 為什麼會有這個案子#
- 「能用的丟過牆」:傳統組織裡開發部負責「寫出新功能」,維運部負責「別讓系統掛掉」;開發把部署包丟過牆給維運,維運拖上數週才排程上線——部署變成恐懼儀式,每次上線像開刀。
- 獎勵制度互相矛盾:開發的 KPI 是變更吞吐量(改得越多越好),維運的 KPI 是穩定性(變更越少越好);兩邊都在理性地追求自己的目標,合起來卻是災難——這是組織設計的數學錯誤。
- 部署批次的惡性循環:部署風險高 → 攒一大批一起上 → 單批風險更高 → 出事更難查 → 部署更恐懼 → 攒更大一批。
- CI 已備好凶器:Martin Fowler 定義的持續整合(2006,其實踐可溯至 XP 的 continuous integration, 1999)已證明「小批量 + 自動化測試」可行,只差把同樣的推理推向部署與維運。
- 關鍵推理:Allspaw 在演講中的核心論斷——部署不該是罕見的大事件,而是日常的小動作:
\[ \text{單批風險} \propto \text{批次大小},\qquad \text{MTTR} \propto \text{批次大小},\qquad \text{部署頻率} \uparrow \;\Longrightarrow\; \text{單次風險} \downarrow \]
2009 年 10 月 DevOpsDays(Ghent)後,"DevOps" 從一場演講變成一個運動。
線索與推理 -- 數學式、程式、理論#
1. 案件現場:那道牆的解剖圖#
\[ \text{Dev} \xrightarrow{\text{throw over the wall}} \text{QA} \xrightarrow{\text{throw over the wall}} \text{Ops} \xrightarrow{\text{部署等待數週}} \text{Production} \]
- 開發視角:「功能寫完就是我的工作結束」;生產環境是別人的責任領域。
- 維運視角:「每個變更都是風險」;維護穩定的最佳策略是延遲與拒絕變更。
- Flickr 的解方:讓開發與維運共擔責任——開發參與部署、維運參與設計;部署自動化到「按一個鈕」,風險用監控與回滾兜底。
2. 批次大小與風險的數學#
設一次部署包含 \(k\) 個變更,每個變更獨立出錯的機率為 \(p\) :
\[ P(\text{批次出錯}) = 1 - (1-p)^k \approx k\,p \quad (kp \ll 1) \]
- 大批量( \(k=100\) ):出錯機率趨近 1,且出錯時要從 100 個變更裡找兇手,隔離成本 \(O(k)\) 。
- 小批量( \(k=1\) ):出錯機率只有 \(p\) ,且兇手就是「剛剛那次部署」,MTTR 從數小時降到數分鐘。
- 反直覺之處:部署頻率上升 10 倍,總變更量不變,但年失敗次數反而下降——因為小批量下每次驗證的變更面積小,自動化測試與回滾的覆蓋率實質提高。
3. CI → CD:持續的階梯#
\[ \text{CI(持續整合)} \xrightarrow{\text{每次 commit 都跑測試}} \text{CD(持續交付)} \xrightarrow{\text{按鈕部署}} \text{CD(持續部署)} \]
- CI:每次 commit 觸發自動建置與測試,整合問題在數分鐘內暴露(Fowler, "Continuous Integration", 2006)。
- 持續交付:每個通過測試的版本都是可部署的,部署是按鈕而非專案(Humble & Farley, Continuous Delivery, 2010)。
- 持續部署:通過測試即自動上線,人類不參與部署決策——Flickr 的 10+ deploys per day 是這一階的先聲。
4. 基礎設施即程式碼(IaC)#
把伺服器設定從「維運手冊+手工操作」變成版本控制的程式碼:
\[ \text{環境} = f(\text{code}),\qquad \text{code} \in \text{Git} \;\Longrightarrow\; \text{環境可重現、可審查、可回滾} \]
CFEngine(1993)、Puppet(2005)、Chef(2009)、Ansible(2012)都是這條線的作案工具;環境建置從 \(O(\text{數天的人工作業})\) 降為 \(O(\text{數分鐘的自動執行})\) ,且與應用程式碼共用同一套 review 流程。
5. DORA 指標:把 DevOps 變成可測量的科學#
2014 年起 DORA(DevOps Research and Assessment,Forsgren、Humble、Kim)以每年 State of DevOps Report 量測四個關鍵指標:
| 指標 | 定義 | 高績效團隊(2019) |
|---|---|---|
| 部署頻率 | 多久部署一次 | 每天多次(on-demand) |
| 前置時間 | commit 到上線 | 少於一小時 |
| MTTR | 出事到恢復 | 少於一小時 |
| 變更失敗率 | 部署後需要修補的比例 | 0–15% |
DORA 的資料證明:部署頻率與穩定性不是取捨,而是正相關——這正是 Allspaw 2009 年演講的實證確認,也打破了維運部門存在的最後藉口。
6. Python 實作:大批量 vs 小批量的部署風險模擬#
import random
def deploy_risk(k_changes, p=0.02, detect_hours_small=0.5, detect_hours_large=6.0, seed=42):
"""模擬一批 k 個變更的部署:回傳(失敗次數, 總恢復時間)。"""
rng = random.Random(seed)
failures, mttr_total = 0, 0.0
for _ in range(k_changes):
if rng.random() < p: # 這個變更出錯了
failures += 1
# 小批量:兇手就是這一次部署,30 分鐘內回滾
# 大批量:要從一堆變更裡找兇手,平均 6 小時
mttr = detect_hours_small if k_changes <= 5 else detect_hours_large
mttr_total += mttr * rng.uniform(0.7, 1.3)
return failures, mttr_total
def simulate_year(total_changes=240, seed=42):
"""一年 240 個變更:比較分 240 批(每天一次)vs 分 12 批(每月一次)。"""
print(f"{'策略':<12}{'批次大小':>6}{'部署次數':>7}{'失敗次數':>7}{'年恢復時間':>10}")
for name, batch in (("小批量", 1), ("中批量", 10), ("大批量", 20)):
n_deploys = total_changes // batch
fails, mttr = 0, 0.0
for _ in range(n_deploys):
f, m = deploy_risk(batch, seed=seed)
fails += f; mttr += m
print(f"{name:<10}{batch:>6}{n_deploys:>8}{fails:>9}{mttr:>9.1f}h")
simulate_year()
# 策略 批次大小 部署次數 失敗次數 年恢復時間
# 小批量 1 240 5 5.3h
# 中批量 10 24 5 71.6h
# 大批量 20 12 9 537.4h
# 結論:小批量的年失敗次數最少、恢復時間最短;
# 大批量不僅出錯率高,隔離兇手的 MTTR 更讓年恢復時間暴增兩個數量級。
def doratime(deploys_per_day, mttr_hours, days=365):
"""DORA 指標換算:部署頻率 × MTTR = 年度停機風險敞口。"""
annual_deploys = deploys_per_day * days
print(f"每天 {deploys_per_day} 次部署 × MTTR {mttr_hours}h → 年部署 {annual_deploys} 次")
doratime(deploys_per_day=10, mttr_hours=0.5)
# 每天 10 次部署 × MTTR 0.5h → 年部署 3650 次
結案 -- 後果與影響#
- DevOps 成為產業標準:DevOpsDays 從一場會議長成全球運動;到 2010 年代末,DevOps 工程師成為獨立職缺,Dev/Ops 的牆在多數新創公司已不存在。
- CI/CD 工具鏈成形:Jenkins(2011,前身 Hudson)、Travis CI(2011)、CircleCI、GitHub Actions(2019)——「每次 commit 都跑測試並自動部署」成為預設管線。
- SRE:Google 的平行解:Google 的 Site Reliability Engineering(2016 出書)以錯誤預算(error budget)量化「可靠 vs 變更」的取捨,與 DevOps 共擔責任的精神同源。
- 部署頻率的量級躍遷:從月(瀑布時代)→ 週(敏捷時代)→ 日(Flickr)→ 時(Amazon、Google:每天數千次)——變更小而頻繁成為高績效的定義。
- 理論延續:The Phoenix Project(2013,小說體)與 The DevOps Handbook(2016)把 DevOps 推向管理層;GitOps、平台工程(Platform Engineering, 2020s)是這條線的最新延伸。
關鍵人物與文獻#
- John Allspaw、Paul Hammond:Flickr 工程師,"10+ Deploys Per Day: Dev and Ops Cooperation at Flickr", Velocity Conference, 2009(YouTube 可查)。
- Patrick Debois:「DevOps 之父」,2009 年創辦 DevOpsDays,讓一詞成為運動。
- Jez Humble、David Farley:Continuous Delivery, Addison-Wesley, 2010。
- Nicole Forsgren、Jez Humble、Gene Kim:Accelerate, 2018(DORA 指標的學術版);Kim、Behr、Spafford, The Phoenix Project, IT Revolution, 2013。
- Martin Fowler:"Continuous Integration", martinfowler.com, 2006。
- Google:Site Reliability Engineering, O'Reilly, 2016(sre.google 免費全文)。