《SRE google 运维解密》读书笔记 (一)
新财年换了领导,管理风格也有一些区别。在团队内增加了一个 SRE 的职位。这一财年我将会承担一部分 SRE 的工作。
之前作为开发者,总的来说从开发的角度来思考系统的稳定性。现在需要从更高更全面的角度来思考和理解站点的稳定性。上网研究了一番,SRE 是 google 的一个职位同时 SRE 也是一套 google 总结出来的站点稳定性的方法论。所以找来了 《SRE google 运维解密》。这本书成书比较早,里面有些章节介绍的技术栈可能过时。具体我也不了解 google 内部是否还在使用。但是方法论还是很合理、科学的。
一直以来我工作过的团队对于风险的态度都是,预防和杜绝。但是在这本书里面,google 对于风险的态度就变成了管理,合理使用,甚至利用风险来保证项目的迭代。
介绍
SER 是指 Site Reliability Engineer(站点可靠性工程师)。SRE 在 google 中有一套比较成熟的方法论包括如下:
- 可用性改造
- 延迟优化
- 性能优化
- 效率优化
- 变更管理
- 监控
- 紧急事务处理
- 容量规划与管理
SRE 方法论:
确保长期关注研发
SRE 只有 50% 的时间投入运维工作,如果超过就需要将任务分配至研发团队,形成良性循环,激励研发团队设计构建出不需要人工干预,自主运行的系统。
出现事故需要推动事后总结。
保证服务在 SLO 的前提下最大化迭代
- 正确认识“错误预算”,系统不能 100% 可用,也不应该追求 100 %可用。
- 业务系统可用利用错误预算,上新功能,黑度,AB test 等。
- SRE 目标并不是 0 事故,而是与业务团队一起管理好“错误预算”
监控系统
- 监控是 SRE 了解系统的重要手段
- 监控只有三类输出
- 紧急报警:收到报警的用户必须立即采取某些操作,解决问题或者避免即将发生的问题
- 工单:收到报警的用户可以采取某些操作非立即,只需要在时效内完成。系统不会受到影响
- 日志:平时无需关注日志,日志作为调试或者事后分析使用
应急事件处理
- 可靠性是 MTTF(平均失败时间) 和 MTTR (平均回复时间)的函数
- 人工操作的事情会延长回复时间
- 运维手册
- 事故演练
可以缩短恢复时间
变更的管理
- 采用渐进式的发布
- 迅速检测出问题的机制
- 出现问题可以快速回滚
需求的预测和容量规划
- 有明确的自然增加的预测
- 规划中还要考虑非自然增涨的需求来源的统计
- 定期压测,了解系统
资源部署
资源是变更和规划的产物
- 快速正确的部署资源是基本的要求
效率和性能
改善利用率,降低成本。
从三个因素推动效率提升
- 用户需求
- 可用容量
- 资源利用率
Google 的生产环境
成书较早,参考价值不大(略)
拥抱风险
管理风险
可靠性的提升,投入并不是线性的
冗余
- 设备的冗余
- 计算的冗余,增加一些空间进行奇偶校验
机会成本
- 如果工程师投入到可靠性建设,就不能从事为用户开发的工作中了
所以,可靠性的管理是通过风险的管理进行的。提升系统可靠性和服务故障的耐受水平同等重要。努力提升服务可靠性,但是不超过服务需要的可靠性。否则将会付出更多的成本。
度量服务的风险
按时间:
可用性= 正常时间/(正常时间+ 不可用时间)
四个九 一年宕机 52 分钟
合计次数
可用性 = 成功次数/总调用次数
对于分布式系统按时间是不合理的,总有部分系统在线,所以 google 倾向使用按次统计
服务的风险容忍度
- 客户对服务失败的容忍度
- toB 要比 toC 低很多
- 付费要比免费低
- 关系到收入的要低
- 故障的类型
- 成本
- 其他服务指标
基础设施容忍度
- 可用性目标水平
- 高可用性很贵
- 要看人下菜碟,合理保障
- 故障类型
- 成本
错误预算使用的目的
错误预算的构建:
- 产品管理层定义一个 SLO,确定服务的预计正常运行时间
- 通过监控来度量
- 而知差值就是不可靠预算
- 如果预算为正就能够进行发布和变更。
好处
创新和可靠性的平衡点。
使用这个控制回路来调节发布的速度,有预算就快速迭代,如果频繁违反 SLO 或者错误预算被耗尽,就需要暂停发布,在测试和开发环节投入更多资源,提升系统可用性。
如果客观的故障发生比如光缆被挖断,影响了 SLO 需要扣减错误预算么?需要的,每个人都有义务保障服务正常运行。
利用错误预算机制,还能够找到定的过高的可用性指标。如果预算耗尽,团队无法发布,就可以考虑降低 SLO 来提升创新速度。
注:SLO 并非越高越好,稳定和创新通常是矛盾的。使用错误预算机制,闭环平衡稳定和创新的关系。
服务质量目标
术语:
- SLI (indicator) 服务的某一个量化指标。比如
- 延迟(rt)
- 错误(error)
- 吞吐量(qps)
- 可用性
- SLO (Objective) 可用性目标,通常指:
范围下限 <= SLI <= 范围上限
- SLA (Agreement) 服务质量协议,指达到或者没有达到某个 SLO 的后果。
SLI 的实践中的应用
关心什么指标
- 用户可见的系统:
- 可用性
- 延迟
- 吞吐
- 存储系统:
- 延迟
- 可用性
- 持久性
- 大数据系统:
- 吞吐
- 延迟
- 时间
- 所有系统都有关注延迟
收集
汇总
标准化
SLO 在实践中的应用
目标的定义
- 指出如何被度量
- 有效的条件
目标的选择
- 不要仅以目前的状态为基础选择(要用发展的眼光)
- 保持简单
- 避免绝对值
- SLO 越少越好
- 不要追求完美
控制手段
- 监控并度量 SLI
- 是否需要人工干预
- 如果需要干预,决定怎么干预
- 执行具体干预措施
SLO 建立用户预期
- 留有余量
- 实际 SLO 不要过高
SLA 的使用
减少琐事
琐事的定义
- 手动性
- 重复性
- 可被自动化的
- 战术性的(突然出现的,非策略驱动和主动安排的)
- 没有持久价值的
- 与服务同步线性增长的(良好的设计至少是有数量级增长的)
SRE 工作内容
50% 琐事,50% 工程项目
工程工作
工程工作,是新颖的,本质上需要主观判断的工作。战略性的。有创新性和创造性的。通过设计来解决问题,越通用越好。
琐事的危害
- 职业停滞
- 士气低落
- 造成误解
- 进展缓慢
- 开创先例(如果愿意接受琐事,那就会有更多的琐事)
- 产生摩擦
- 违反承诺
分布式系统的监控
术语定义
- 监控
- 白盒监控
- 对系统暴露的性能指标进行监控
- 黑盒监控
- 通过测试某种外部用户可见的系统进行监控
- dashboard
- 警报
- 根源问题
- 某个缺陷被修复,就可以保证这种缺陷不再发生以同样的方式发生。
- 节点或者机器
- 推送
为什么要监控
- 分析长期趋势
- 跨世纪范围的比较,或者实验组和对照组之间的区别
- 报警
- 构建监控 dashboard
- 临时性问题的回溯分析
监控可以在系统发生故障或者将要发生故障的时候通知我们。
处理报警会占用员工的时间,报警太频繁会造成“狼来了”效应
对监控系统设置合理预期
Google 倾向于使用简单和快速的监控,配合高效的工具进行分析。避免使用“魔方”系统-试图自动学习或者自动检查故障的系统。
监控系统的规则越简单约好。
监控系统信噪比应该很高,发出报警的组件应该简单可靠。
黑盒和白盒监控
白盒监控应该要作为监控的主要手段。
黑盒监控是面向现象的-现在发生的,而非即将发生的。
白盒监控大量依赖对系统内部信息的检测。白盒监控可以检测到即将发生的问题和重试严掩盖问题。白盒系统既可以面向原因也可以面向现象。
4 个黄金指标
- 延迟(rt)
- 流量
- 错误
- 饱和度
- 通常是系统中最为受限的某个具体指标的度量。
- 复杂系统里面,可以配合其他搞层次的负载度量使用。使用一个简介的指标。
长尾
只使用平均值是不足以描述系统的。需要区分平均值的慢,或者长尾值的慢。可以对数据进行分组统计。
简化直到不能再简化
- 最能反应正式故障的规则越简单越好
- 不常见的报警就要删除(定时删除没有用到的报警)
- 没有被报警规则使用的信息,就应该
报警的深层次理论
- 每当收到报警,需要立即进行某种操作,每天次数有限,过多会有“狼来了”效应
- 每个紧急报警都应该是可以具体操作的
- 报警的回复都应该是需要某种智力过程的,如果只需要固定的机械操作,那就不应该是紧急报警
- 每个紧急报警都应该是正交的,不应该彼此重叠
监控系统的长期维护
系统不断演变,软件经常重构,负载和性能目标也经常变化。所以监控系统的的设计和决策充分考虑长期目标。每一个报警都会占用优化系统的时间。花时间投入监控,换取未来系统的稳定是值得的。
短期和长期的可用性经常冲突。通过一些“暴力”因素,可以使一个摇摇欲坠系统保持一定的高可用性,这种方案不能长久,且依赖个人英雄主义。
短期接受稳定性的降级获得长期的可用性提升。
Google 自动化演进
自动化的价值
- 一致性
- 平台性
- 自动化的系统可以提供一个可以扩展的、广泛适用的。
- 同时会将错误集中化、意味着修复的缺陷是一劳永逸的。
- 修复速度更快
- 行动速度快
- 节约时间
发布工程
哲学
- 自服务模型
- 追求速度
- 密闭性
- 构建工具必须确保一致性和可重复性
- 强调策略和流程
持续构建和部署
- 构建
- 分支
- 所有代码默认提交到主分支上。
- 构建一个发布分支
- 发布分支不会并入主分支
- 代码从主分支 cherry pick 到发布分支
- 测试
- 单测
- 打包
- 部署
- 部署
配置管理
一开始就进行发布工程
不要做时候诸葛亮
简单化
软件系统是本质上是动态和不稳定的
系统的稳定性和灵活性
- 为了灵活性牺牲稳定性是有意义的。
乏味是一种美德
定期删除无用代码
“负代码行”作为指标
- 臃肿的软件置管术是不可取的
- 添加代码可能引入新的缺陷
- 小的代码容易理解,也容易测试,缺陷就越少
最小 API
- 书写一个明确的,最小的 API 是软件系统简单的必要部分
- 方法越少,参数越少也容易理解
模块化
发布简单化
软件的简单是可靠性的前提。