Google SRE 工作手册详细总结:写给从未接触过 SRE 的人
- 约 33 分钟读完 - 全文 12972 字Google SRE 工作手册详细总结:写给从未接触过 SRE 的人
参考书籍:Google SRE 团队《The Site Reliability Workbook》(《SRE 工作手册》,2018) 目标读者:第一次听说 “SRE” 这个词,想知道它到底是什么、解决什么问题、能不能用在自己团队的人。
〇、这本书是什么?
Google 在 2016 年出版了《Site Reliability Engineering》(第一本 SRE 书),讲的是 SRE 的原理——Google 是怎么想的。2018 年这本《Workbook》(工作手册)是它的姊妹篇,讲的是 怎么落地——两本书的章节基本一一对应(比如第一本书第 4 章"服务级别目标"对应本书第 2 章"实施 SLO")。
这本书最有价值的一点是:它故意收录了大量 Google 之外的公司 的落地案例——Evernote、Home Depot(家得宝)、《纽约时报》、Spotify、Waze、PagerDuty——就是为了破除"SRE 只在 Google 那种规模和文化下才玩得转"的误解。全书由 100 多人贡献完成。
用前言里 Mark Burgess 的话说,整本书可以浓缩成三句话:
- 承诺:明确地设定服务的目标、期望和水平;
- 评估:根据指标和预算约束持续评估这些承诺;
- 反应:快速做出反应以兑现承诺。
一、SRE 到底是什么?和 DevOps 什么关系?
SRE = Site Reliability Engineering,网站可靠性工程。这个词由 Google 工程副总裁 Ben Treynor Sloss 创造。一句话概括:
SRE 就是让软件工程师去做运维团队的工作——“运维是一个软件问题”。
传统模式里,开发团队(追求快速出新功能)和运维团队(追求稳定别出事)天然对立:开发想"快发",运维想"别动"。SRE 用一套量化的工程方法消解这个矛盾,而不是靠开会吵架。
那它和 DevOps 是什么关系?第 1 章的标题本身就是一行代码,堪称全书最著名的梗:
class SRE implements DevOpsDevOps 是一套文化和哲学,SRE 是它的一种具体实现——就像极限编程(XP)是敏捷(Agile)的一种具体实现。Puppet 前 VP Andrew Clay Shafer 在前言里甚至说:如果第一本 SRE 书早几年出版,社区会团结在"消除琐事"的旗帜下,“DevOps"这个词可能根本不会存在。
DevOps 的五个关键思想与 SRE 的对应实现:
| DevOps 思想 | SRE 的具体做法 |
|---|---|
| 不再有孤岛 | SRE 与开发共享所有权、用相同的工具 |
| 事故是正常的,指责无用 | 对事不对人的事后总结(blameless postmortem) |
| 变更应该小步快跑 | 金丝雀发布、CI/CD、降低失败成本(MTTR) |
| 工具和文化相互关联 | 统一的工具链本身就是文化载体 |
| 度量至关重要 | SLI / SLO / 错误预算 |
SRE 的七条核心原则:
- 运维是一个软件问题——用写代码的方式消灭重复劳动;
- 按 SLO 管理——不追求 100% 可用性(为什么,下面细讲);
- 努力减少琐事(toil);
- 自动化今年的工作——Google 硬性规定 SRE 花在琐事上的时间不超过 50%,而且要把它当成"保证"而不是"上限”;
- 通过降低失败成本来加快开发速度——恢复快(MTTR 低)比不出事更重要;
- 与开发者共享所有权;
- 无论头衔如何,都使用相同的工具。
这里有一个值得记住的反面案例:2017 年 5 月英国航空大停运,被书中引为"把运维当成本中心拼命压缩"的失败典型——一场大事故抵消了低成本运营省下的所有钱。
二、全书的地基:SLI、SLO、SLA 和错误预算
第 2 章被作者称为"本书最重要的章节",金句是:“没有 SLO,就不需要 SRE”。这一节是全书的地基,务必看懂。
2.1 三个容易混淆的概念
用一个"外卖小哥"的比喻:
- SLI(Service Level Indicator,服务级别指标):你实际测出来的数字。比如"过去 30 天,99.2% 的外卖在 40 分钟内送达"。
- SLO(Service Level Objective,服务级别目标):你给自己定的目标。比如"我们承诺 99% 的订单 40 分钟内送达"。
- SLA(Service Level Agreement,服务级别协议):和客户签的、违约要赔钱的商业合同。通常比 SLO 宽松,SLO 是内部"提前预警线",SLA 是"最后底线"。
工程上的标准写法:
SLI = 好事件数 / 总事件数 (0% ~ 100% 之间)
错误预算 = 100% − SLO
错误预算(Error Budget) 是全书最重要的发明。它的逻辑是:既然 100% 不可靠也不必要,那么"允许出错的额度"就是一种可以花掉的预算——你可以用它来快速发布新功能、做架构实验;预算花光了,就冻结发布,全员回头修可靠性。开发和运维的矛盾,从"立场之争"变成了"看数据说话"。
2.2 为什么不追求 100% 可用性?
书中给了四个理由:
- 组件同时故障的概率永远不为零,100% 在数学上就做不到;
- 用户访问你的服务要经过很长的链路(手机 → 运营商 → 公网 → 机房),你把可用性从 99.9% 提到 99.99%,用户的实际体验提升微乎其微——边际效用递减;
- 100% 意味着你不能做任何变更,而变更是功能迭代的前提;
- 100% 的 SLO 只是"运维团队的 SLO",不是一种工程文化。
还有一个很直观的乘法效应:如果你的服务依赖 9 个可用性 99.99% 的关键上游,你的总可用性 ≈ 0.9999¹⁰ ≈ 99.9%——4 个 9 直接掉到 3 个 9。第 19 章还有一个更扎心的数字:客户在 99.999% 的平台上自己只做到 99%,最终用户感受到的是 99% × 99.999% = 98.99901%。
2.3 一个完整的例子:手机游戏后端
第 2 章用一个手机游戏案例贯穿始终,非常适合入门者理解。架构如下:
graph LR
A["📱 手机 App"] --> B["HTTP API 服务"]
B --> C[("永久存储<br/>游戏状态/排行榜")]
A --> D[("用户数据存储<br/>头像等")]
C --> E["⏰ 定时管道<br/>生成今日/本周/历史排行榜"]
E --> F[("排行榜数据存储")]
G["🌐 网站"] --> F
先量现状:过去 4 周 API 总请求 3,663,253 次,成功 3,557,865 次(可用性 97.123%),P90 延迟 432ms,P99 延迟 891ms。据此定出入门级 SLO:
- 可用性:97% 请求成功
- 延迟:90% 请求 < 450ms,99% 请求 < 900ms
对应的错误预算:每四周允许失败约 109,897 个请求。
然后看两个真实事故的"预算消耗"对比,这是全书最有说服力的算账方式:
| 事故 | 错误数 | 消耗预算 |
|---|---|---|
| 一次坏发布,NullPointerException 持续 4 小时 | 14,066 | 13% |
| 唯一的状态数据库故障,从备份恢复花了 20 小时 | ~72,000 | 65% |
结论很反直觉:五年只发生一次的数据库故障,远没有每年 2~3 次的坏发布值得投入——改进发布流程的优先级应该高于调查服务器故障。这就是错误预算的意义:它把"该把工程资源投到哪"从拍脑袋变成了算术题。
2.4 落地 SLO 的完整流程
flowchart TD
A["绘制服务架构图"] --> B["组件分类:<br/>请求驱动 / 管道 / 存储"]
B --> C["为每类组件选 SLI 规范<br/>(不超过 5 种)"]
C --> D["选择 SLI 实现方式<br/>(日志 → 探针 → 客户端插桩,精度递增)"]
D --> E["基于历史数据定初始 SLO"]
E --> F{"三方达成一致?<br/>产品:对用户够用<br/>开发:预算耗尽愿意行动<br/>SRE:不靠英雄主义守得住"}
F -- 否 --> E
F -- 是 --> G["白纸黑字写错误预算政策<br/>(预算耗尽怎么办)"]
G --> H["监控 + 告警上线"]
H --> I["定期审查迭代 SLO"]
三类组件各自推荐的 SLI:
- 请求驱动型(API 服务):可用性、延迟、品质;
- 管道/流水线型(数据处理):新鲜度、正确性、覆盖范围;
- 存储型:耐用性(数据丢不丢)。
错误预算政策里要事先写清楚"预算耗尽怎么办":可靠性 bug 最优先、冻结生产变更(P0 问题和安全补丁除外),极端时宣布"紧急状态",直到服务回到 SLO 以内。附录 B 还有一个值得抄的细节:单个事件消耗超过四周预算的 20% → 必须做事后调查,且至少包含一个 P0 行动项;对错误预算计算有分歧 → 上报 CTO 裁决。
三、非 Google 公司怎么落地?两个完整案例
3.1 Evernote:和云厂商"打破 SLO 的墙"
背景:全球 2.2 亿用户、存储 120 亿条信息、750+ 个 MySQL 实例,从自建数据中心迁往 GCP。传统"开发 vs 运维"两种模式(“you build it, you run it” 和 “you build it, we run it”)都试过了,都不满意,于是在 Google CRE(客户可靠性工程)团队帮助下落地 SLO。
- 首版 SLO:按月窗口、99.95% 正常运行时间;用第三方探针 Pingdom 每分钟轮询,需两个地理独立的探针连续失败才算"停机";维护窗口也算停机(用户不知情就是不可用);
- 治理节奏:每月与 Google 团队审查一次 SLO,每 6 个月修订一次,9 个月迭代了 3 版;指导原则是"完美是良好的敌人"——先有再优;
- 一个漂亮的故事:2017 年讨论是否压缩发布窗口时,双方用 SLO 计算把发布窗口从 5 个减到 2 个,量化了客户影响,消除了主观争论;
- 最创新的一点:与 Google 共享实时 SLO 仪表板。于是 Google 的告警从泛泛的"GCP 负载均衡今天有点慢"变成"该问题影响 Evernote SLO 的 5%",重大事件双方作为联合 P1 故障单处理。
3.2 Home Depot(家得宝):传统企业的规模化推广
背景:北美 2,200+ 门店、近 40 万员工、每年 15 亿+ 交易——证明 SRE 不是互联网公司专利。
他们发明了 VALET 框架(呼应 Google 的四大黄金信号,连批处理系统都能套用):
- Volume 容量(流量/处理记录数)
- Availability 可用性
- Latency 延迟
- Errors 错误
- Tickets 故障单(人工介入次数)
推广靠四板斧:
flowchart LR
subgraph 推广四支柱
A["通用语言<br/>VALET 缩写,人人会说"]
B["布道<br/>内部博客/路演/T恤贴纸<br/>FiRE 学院培训"]
C["自动化<br/>TPS Report 自动采集指标<br/>VALET 仪表板 + 聊天机器人"]
D["激励<br/>SLO 纳入开发经理年度目标"]
end
A & B & C & D --> E["一年从 0 到 800 个服务<br/>每月新增约 50 个"]
给产品经理的简化分级表也很实用:99.5% = MVP/内部工具;99.9% = 大多数非销售系统;99.95% = 销售系统;99.99% = 共享基础设施。他们的原话值得引用:“我们是一家传统企业;如果我们能成功引入这么大的变化,您也可以。”
四、监控与告警:在预算烧光之前叫醒你
4.1 监控的基本盘
监控的五大用途:告警、诊断、可视化、长期趋势/容量规划、变更前后对比。指标和日志要分工:指标近实时但粒度低(告警、仪表板用它),日志有延迟但精确(根因分析用它)。数据新鲜度很关键——超过 4~5 分钟的失效数据会严重影响事件响应。
现代监控栈是松散耦合的:Prometheus(采集/规则)→ InfluxDB(长期存储)→ Alertmanager(告警聚合)→ Grafana(仪表板)。
4.2 告警的正确姿势:盯着错误预算的"消耗率"
新手最常见的告警写法是"错误率超过 X% 就报警",书第 5 章用一整章论证这有多糟糕,并给出了演进路径:
flowchart TD
M1["方法1:错误率≥SLO 就告警<br/>❌ 太敏感:10 分钟 0.1% 错误率就告警<br/>实际只消耗月预算 0.02%,每天可收 144 条"]
M2["方法2:加大告警窗口<br/>❌ 检测太慢,大事故发现太晚"]
M3["方法3:加持续时间参数 for:1h<br/>❌ 每 10 分钟一次 5 分钟的 100% 错误尖峰<br/>累计烧掉 35% 预算却永不触发"]
M4["方法4:按消耗率 burn rate 告警<br/>⚠️ 进步明显,但重置时间长"]
M5["方法5:多消耗率分档<br/>⚠️ 快烧/慢烧分开告警"]
M6["方法6:多窗口多消耗率 ✅<br/>长窗保证精确度,短窗保证灵敏度"]
M1 --> M2 --> M3 --> M4 --> M5 --> M6
消耗率(burn rate) = 当前错误率相对 SLO 允许错误率的倍数。对照表(99.9% SLO,30 天窗口):
| 消耗率 | 错误率 | 耗尽预算需时 |
|---|---|---|
| 1 | 0.1% | 30 天 |
| 10 | 1% | 3 天 |
| 1000 | 100% | 43 分钟 |
最终推荐的"多窗口多消耗率"参数(针对 99.9% SLO,可直接抄):
- 呼叫值班(紧急):1 小时长窗 + 5 分钟短窗,消耗率 14.4(约 2% 预算/小时)
- 呼叫值班(次紧急):6 小时 + 30 分钟,消耗率 6
- 工单(不紧急):3 天 + 6 小时,消耗率 1
短窗口取长窗口的 1/12。两个极端情况的提醒:低流量服务(每小时 10 个请求时,1 个失败就是 10% 错误率)要合并请求或拉长时间窗;99.999% 的服务 100% 中断 26 秒就耗尽预算——比大多数监控采集间隔还短,只能靠自愈。
五、消除琐事(Toil):SRE 的时间去哪了
琐事(toil) 的六大特征:手动、重复、可自动化、被动应对、无持久价值、随服务规模线性增长。Google 规定 SRE 花在琐事上的时间不超过 50%,保证至少一半时间做"让明天比今天更好"的工程。
书中几个精彩案例:
- John Looney 修内核:2005 年他入职 Google 时的活儿是修坏机器——任何时候都有超过 20,000 台坏机器。发现大量机器是日志把根分区填满,他本想写个脚本"截断大日志 + 重启 syslog"了事,被队友拦下要求修根因。最终他向 Linux 内核提交补丁,并用"这个问题导致 Google 每小时损失约 1000 美元"的成本分析说服了内核团队。修症状是琐事,修根因才是工程。
- “不完美的自动化就够了”:Google 数据中心网络维修自动化(Saturn/Jupiter 项目)中,内存错误诊断被过度分析了三年(收集了 650+ 个离散问题数据),后来发现多数错误是暂时性的,重启重装即可恢复——完美的自动化不值得,“足够好"的自动化先跑起来。
- “买下那个侏儒”:早年 Froogle 搜索"跑鞋"会返回一个穿跑鞋的花园侏儒(eBay 商品),修不掉这个 bug,团队干脆在 eBay 上把侏儒买了下来。引申义:有时改变现实去适应代码,比反过来便宜。
遗留系统的四阶段处理路径:避免 → 封装/增强(高息技术债转低息)→ 替换/重构 → 退役/监护。
与琐事相关的第 7 章"简单化"还有两个名案例:
- Borg vs Omega:Omega 本想做成"更干净的 Borg"重写版,但 Borg 持续演进让 Omega 永远追不上移动的目标,迁移成本高到不可行。结局:Omega 的想法回流 Borg,概念最终催生了开源的 Kubernetes。教训:重写前先算一算"同样的精力投入改进现有系统会怎样”。
- pDNS 循环依赖:客户端查服务 IP 依赖 Svelte,Svelte 依赖 pDNS,pDNS 的负载均衡器又依赖 Svelte——“我们就像洞穴居民,只能用上一次篝火点燃的火炬点火”(系统冷启动成为不可能)。解法:低级组件本地缓存关键 IP 列表,打破环路。
六、值班与事件响应:像消防队一样打仗
6.1 可持续的值班体系
关键数字:轮班不超过 12 小时;每 12 小时班次最多 2 个事件(再多就处理不过来了);多站点 24/7 值班每站点至少 5 人;保证 ≥50% 的时间留给项目工作。警惕"温水煮青蛙"式的运维过载——值班负载用 21 天移动平均来看趋势。
Evernote 的事件分级很清爽:P1 立即处理(呼叫值班、影响 SLO)、P2 下一工作日(邮件通知)、P3 仅供参考(只看仪表板)。
6.2 事件指挥体系(ICS/IMAG)
大规模事件的打法直接借用了消防系统:1968 年消防员为应对野火创建的事件指挥系统(ICS),Google 内部叫 IMAG。核心思想:混乱中最大的敌人不是故障本身,而是"谁说了算都不知道"。
graph TD
IC["🎖️ 事件指挥官 IC<br/>总负责,做决策,默认承担未委派的角色"]
CL["📢 沟通主管 CL<br/>对用户/领导/媒体发通告"]
OL["🔧 运维主管 OL<br/>带领团队执行技术操作"]
IC --> CL
IC --> OL
事件管理围绕"三个 C":Coordinate(协调)、Communicate(沟通)、Control(控制)。四条基本原则:保持命令清晰、明确角色、实时记录、尽早且频繁地宣布事件。行动顺序永远是"缓解优先":评估影响 → 缓解影响 → 根因分析 → 修复与事后报告。
三个真实案例,一正一反一个惊险:
- 反例:Google Home/Assistant 事件(2017):一个 bug 让文件获取频率比预期高 50 倍,5 月 22 日就发现 QPS 异常,但误判了根因,而且在周六把灰度推到了 100%(违反"首次上线仅在工作日"的铁律),用户丢了一半请求,靠开发者周末"英雄主义"硬扛。教训:没有尽早宣布事件、缓解后没定根因就继续推送。
- 惊险:GKE CreateCluster 中断:欧洲集群创建失败率超 60%,根因竟是从 DockerHub 拉取的一个镜像损坏(美国正常)。伦敦 SRE 6:41 被呼叫,9:10 才正式建立 IMAG 结构(太晚了),最后发现用现成的 GCR 镜像站点(
--registry-mirror=https://mirror.gcr.io)就能缓解——镜像其实早就就位了。总中断 6 小时 40 分钟,41 人参与,事后报告列出 28 个行动项。最大教训:发现大致位置后就该先用"通用缓解"(回滚到已知良好状态),而不是继续深挖根因。 - 正面:比利时数据中心雷击(2015):两分钟内 4 次雷击,UPS 电池在第 3、4 次雷击间隔太近时未能切换,磁盘托盘断电。事件指挥得当:IC 定了三个明确目标,沟通主管对四类受众(公司领导、依赖团队、外部客户、工单客户)分别通报。最终数据丢失仅 0.000001%——管理良好的事件,损失可以极小。
七、事后总结文化:从失败中学习
SRE 文化的灵魂是对事不对人的事后总结(blameless postmortem)。第 10 章用同一个真实事故的"坏版本"和"好版本"两版报告做对比,极其有教育意义。
事故本身(2014-08-11,Google 卫星擦除事故):Google 在托管机房部署的代理/缓存机架叫"卫星"。一次机架退役流程中,自动化中途失败,工程师手动重跑——重跑时 GetMachines() 返回了空列表,而 API 有个 bug:空列表被当作"无过滤条件",而不是"不操作任何机器"。于是全球所有卫星机器在几分钟内被磁盘擦除。
flowchart TD
A["机架退役自动化失败"] --> B["工程师手动重跑流程"]
B --> C["GetMachines() 返回空列表"]
C --> D["API bug:空列表 = 无过滤条件<br/>(而不是不操作任何机器)"]
D --> E["全球所有卫星进入退役流程"]
E --> F["磁盘被全部擦除 💥"]
F --> G["边缘流量切到核心集群<br/>用户延迟上升约两天"]
G -.->|"容量规划良好,<br/>用户几乎无感知"| H["几天后恢复"]
两版事后报告的对比:
| 坏版本 | 好版本 | |
|---|---|---|
| 发布时间 | 拖了 4 个月 | 4 天内(8/11 出事,8/15 发布) |
| 根本原因 | “dylanfour@ 粗心大意忽略自动化” | 深入分析 API 语义缺陷与流程漏洞 |
| 行动项 | 全是 P2,措辞含糊(“使自动化更好”) | 每项有唯一所有者、优先级、bug 号,含 P0 级"大红色按钮"(紧急停止开关) |
| 分享范围 | 团队小范围 | 全公司工程师 |
后续更有说服力:三年后类似事件重演,但第一次事后总结落实的行动项大幅缩小了爆炸半径。Google 运维副总裁 Ben Treynor Sloss 的原话:
“没有后续行动的事后总结等于没写事后总结。所有影响用户的停机事后总结必须至少关联一个 P0/P1 bug,例外由我亲自审批,例外极少。”
事后总结文化崩塌的信号也要警惕:工程师回避参与、高管说指责性语言、没时间写、同类事故重复发生。
八、管理负载:Pokémon GO 的惊险一课
Google 管理流量的三层工具:负载均衡 + 自动扩缩容 + 减载(load shedding)。核心警告是:必须把它们当作一个整体系统设计,否则工具之间会形成灾难性的反馈回路。
8.1 案例:Pokémon GO(2016,真实)
上线前按最乐观估计的 5 倍做了负载测试,实际流量是估计的近 50 倍。随后发生的级联故障堪称教科书:
flowchart TD
A["真实流量超预期 50 倍"] --> B["Niantic 前端代理跟不上入站连接"]
B --> C["后端变慢但不拒绝请求"]
C --> D["负载均衡层自动重试 GET"]
D --> E["GFE 的 SSL 客户端代码被打到极限"]
E --> F["GCLB 全球容量实际下降 50% ⚠️"]
C --> G["客户端立即重试 + 固定退避<br/>错误时所有客户端同步重试(雷群)"]
G --> H["同步峰值达此前全球 RPS 峰值的 20 倍"]
F & H --> I["Google SRE 三步止血:<br/>①隔离 Pokémon GO 专用池 ②扩容 ③限流"]
事后双方各自改进:Niantic 给客户端加了抖动(jitter)+ 截断指数退避;Google 学会把 GFE 后端当潜在负载源、建立准入负载测试。共同教训:尽可能靠近客户端测量负载。
8.2 案例:Dressy 减载反馈回路(虚构但典型)
三区域部署,A 区流量上涨先触发减载(CPU 超阈值直接拒绝请求)→ 被拒请求几乎不耗 CPU → 负载均衡器一看"A 区每个请求成本只有 B/C 的 1/10,效率最高!"→ 把更多流量发给 A → A 区 503 爆炸。恶性循环的根源:配减载的和配负载均衡的是两拨人,没人把它们当统一的负载管理系统检查。修法很巧妙:让被拒绝的请求按 120% CPU 计入利用率,A 区立刻"显得"过载,流量自然流向 B/C。
九、NALSD:把白板上的架构图翻译成数字
NALSD(Non-Abstract Large System Design,非抽象大型系统设计) 是 Google 要求的系统设计方法:从问题出发迭代设计,每一步都必须把架构图翻译成具体的资源估算(多少台机器、多少字节、多少 IOPS),并回答四个问题——“可能吗?能做得更好吗?可行吗(钱和硬件)?有弹性吗(故障怎么办)?”
书中用 AdWords 点击率统计系统做了五轮完整迭代:每秒 50 万次搜索查询、1 万次广告点击,为数百万广告主出实时仪表板(SLO:99.9% 的查询 1 秒内完成,数据延迟不超过 5 分钟)。
flowchart LR
I1["迭代1 单机方案<br/>100TB/天日志<br/>需 2500 块 HDD 或 1563 台机器<br/>❌ 单点故障一串"] --> I2["迭代2 MapReduce 批处理<br/>❌ 做不到 5 分钟内可见"]
I2 --> I3["迭代3 LogJoiner<br/>流式 join 查询日志与点击日志<br/>⚠️ IOPS 单机扛不住"]
I3 --> I4["迭代4 分片 + 副本<br/>hash(query_id) mod N<br/>⚠️ 单数据中心仍是单点"]
I4 --> I5["迭代5 多数据中心 + Paxos ✅<br/>每 DC 约 4TB RAM、64 台机器<br/>网络带宽只用 25%"]
给面试和日常设计的启发:每轮迭代不是"画个更复杂的图",而是算一笔账——日数据量 = QPS × 86400 × 条目大小;磁盘数 = QPS ÷ 单盘 IOPS;Paxos 顺序吞吐 = 1000ms ÷ 跨机房 RTT。假设不必完美,有价值的是把多个不完美但合理的估算组合起来做决策。
十、数据处理管道、配置与金丝雀发布
10.1 把管道当服务运营(Spotify 案例)
数据管道也要定 SLO:新鲜度(“99% 的数据 30 分钟内处理完”)、正确性、完整性。Spotify 的事件传递系统每天收集数千亿条事件(听歌、点广告……),用于向艺术家支付版税——可靠性是财务级要求。
flowchart LR
A["Spotify 客户端事件"] --> B["Cloud Pub/Sub 主题<br/>(按事件类型完全隔离)"]
B --> C["消费微服务"]
C --> D["分区微服务<br/>分配到小时桶"]
D --> E["Dataproc 批作业去重"]
E --> F[("GCS 小时桶<br/>与下游的唯一接口")]
三个值得抄的设计决策:时间戳用服务器接收时间而非客户端时间(用户可以离线缓冲 30 天、可以改设备时间);只给"财务相关"事件承诺偏度/完整性 SLO,刻意不提供数据质量 SLO——“我们是邮政服务:负责按时完整送达,包裹里的内容质量归寄件人”;容量规划留安全边际,高峰 CPU 不超 50%。
10.2 配置:最好的人机界面是"没有配置"
配置三要素哲学:理想配置是完全没有配置(系统自动识别正确值);以用户为中心(用户说"我要热的绿茶",而不是指定水量/温度/浸泡时间);动态默认值(线程数默认 = CPU 核数)。任何配置变更必须满足安全三属性:逐步部署、可回滚、失控时自动回滚(想想多少人用防火墙规则把自己锁在服务器外面过)。
10.3 金丝雀发布:用小部分错误预算买安全感
术语来自煤矿里的金丝雀。核心是一笔账:一个缺陷导致 20% 请求出错,直接全量发布就是 20% 总错误率;先部署到 5% 的金丝雀集群,总错误率只有 5% × 20% = 1%。
flowchart TD
A["新版本部署到 5% 金丝雀集群"] --> B["细分指标对比:<br/>金丝雀组 vs 对照组"]
B --> C{"错误率/延迟显著偏离?"}
C -- 是 --> D["暂停发布 + 回滚<br/>通知人工介入"]
C -- 否 --> E["逐步扩大:1%→10%→50%→100%"]
E --> F["全量发布 ✅"]
D -.->|"修复后重来"| A
两个容易踩的坑:监控指标的聚合间隔必须小于等于金丝雀时长(30 分钟的金丝雀用"每小时错误数"评估,噪声会淹没信号);金丝雀指标首选 SLI,且总数不要超过 12 个。
十一、人的部分:过载恢复、团队建设与组织变革
第三部分"流程"处理的是书中最"软"也最难的部分。
11.1 识别过载并恢复(第 17 章)
过载分两种:真实过载(任务量客观超支)和感知过载(沟通不足导致的主观感受)——书中强调,感知过载的实际危害和真实过载一样大,而且会传染。恶性循环是这样的:
flowchart LR
A["运维过载"] --> B["心理压力"]
B --> C["犯错增多"]
C --> D["可靠性下降"]
D --> E["更多运维工作"]
E --> A
B --> F["心理安全下降<br/>协作与信息共享停滞"]
F --> G["效率更低"]
G --> E
真实案例:Google 一个支撑 Gmail/Drive 后端的存储 SRE 团队,2016 年三分之二的成员短期相继转岗。恢复方法朴素得出奇:全队进一个房间把所有职责写上白板分类,两天时间(一天分类、一天写文档/做自动化)清理了几个月的积压;之后每两周分类一次,每人最多 10 张打开的工单,超了就有五种干预动作。另一个感知过载团队(悉尼/苏黎世两地)的恢复路线是分三档:短期先减压(圆桌吐槽会、删掉垃圾警报、“慷慨地静音”)、中期减负(把一项服务交还开发团队、补员)、长期治本(SLO 对齐、服务统一化)。约一年后匿名调查显示团队重回"高效且安全"。
11.2 SRE 怎么参与一个服务(第 18 章)
SRE 永远是稀缺资源(Google 把 SRE:开发比例控制在 1:10 左右),所以要主动选择参与模式。服务的生命周期:
flowchart LR
A["架构与设计"] --> B["积极开发<br/>(生产化)"] --> C["有限可用 Beta<br/>GA 前必须定 SLO"] --> D["一般可用 GA<br/>通过 PRR 生产准备审查"] --> E["弃用<br/>SRE 同时运维新旧两套"] --> F["放弃<br/>运维交还开发团队"] --> G["不支持"]
两个一正一反的收场案例:Ares 团队(好聚)——反滥用团队 CAT 内部建立了具备生产知识的 Ares 小组,SRE 通过"交流计划"转移知识后体面退出,CAT 开发速度反而提升;数据分析管道(好散)——合作十年后关系恶化(旧系统到极限、沟通破裂),最终解散 SRE 团队、平稳移交,教训是"如果关系健康,本可以暂时交还再取回"。
11.3 SRE 团队生命周期(第 20 章)
从 0 到 1 的路径,三条原则贯穿:①SRE 需要有结果的 SLO;②SRE 必须有时间让明天比今天更好;③SRE 团队必须能调节自身工作量。
flowchart TD
A["没有 SRE?<br/>先用 SLO:承认不要 100% → 定 SLO → 写错误预算政策 → 测量并执行"] --> B["招第一个 SRE<br/>考察:运维/软件工程/监控/自动化/架构"]
B --> C["组建 SRE 团队<br/>Tuckman 模型:组建 → 震荡 → 规范 → 表现"]
C --> D["多团队:按产品域或技术栈拆分<br/>⚠️ 警惕无人认领的组件"]
D --> E["地理分布式<br/>时区间隔 6-8 小时最佳,避开凌晨值班"]
警告:不要在还没实践 SRE 原则之前,把"运维团队"改名成"SRE 团队"——品牌一旦失败,组织会彻底否定 SRE 这个概念。
11.4 组织变革管理:Waze 的逆袭(第 21 章)
Waze(2013 年被 Google 收购)的消息队列是全公司组件的通信命脉。吞吐量暴增后可靠性崩溃,最糟时整个 SRE 团队连续两周 24/7 救火,每小时手动重启部分组件才能维持数千万用户的服务。
变革路径(完美对应 Kotter 八步模型):2 名 SRE + 1 名高级工程师组成"指导联盟";评估现成产品后决定自研;招募志愿军先给占 30% 以上流量的单个组件建专用队列,挤出两个月的原型窗口;重写客户端库实现新旧系统流量切换;先迁低流量高重要性的消息流,双写提供备份路径。最终新系统承载旧系统 1000 倍以上的负载,且几乎无需人工干预。第二轮变革是部署流程:引入 Spinnaker 持续交付,如今 Waze 超过 95% 的服务持续部署,几乎无人工干预。
书里还有一条推广通用工具的朴素经验:迁移成本必须接近零(“重新编译就能用上”),收益必须明确(“现在你已经不受某某漏洞影响”),衡量推广成功的第一指标是采用率。
十二、结语:把这本书带走的五句话
- 没有 SLO,就不需要 SRE——先量化"什么叫足够可靠",再谈可靠性工程。
- 错误预算是开发速度与稳定性的通用货币——预算充足就大胆发布,花光就冻结变更,不用吵架。
- 琐事不超过 50%,修根因不修症状——每小时损失多少钱,把账算给决策的人听。
- 缓解优先于根因,对事不对人——先把用户救回来,再写一份有 P0 行动项的事后总结。
- SRE 不是 Google 专利——Home Depot 一年从 0 到 800 个服务,“如果我们能做到,您也可以。”
最后用全书结尾的祝福语收个尾:
愿你的查询流畅,愿你的传呼机保持沉默。 (May your queries flow and your pagers stay silent.)