SRE方法论
确保长期关注研发
50% 以下的时间(google SRE 实际33%左右)用在运维,作为一个标准,保证开发,优化的精力。如果超出了,就要采取措施,比如临时转移运维压力回去给业务团队,增加资源等
- 放在我们团队来说,就是要保证一定配比以下的时间是用在做日常业务支撑的,以保证平台开发的时间。如果超出了,必须解决,如何解决,可以考虑比如工作移交给业务团队,增加人手,改进工具,停止承接业务,自动化等及时应对,而不是已100%业务压力做不了更多业务了来做为衡量标准(这个需要领导的支持)
- 比如实时计算团队,目前可以 50%的工作量做为业务开发的标准线?长期目标是20%以下
- 离线开发平台,控制在25%以下,长期目标是10%以下
- 后台开发团队,客户需求的,有强进度要求的开发工作量应该在25%以下,自主规划进度,把控方向的应该在75%以上
错误预算
不追求100%的可靠性,确定一个可靠性目标,在错误预算的范围内,用于新功能上线或产品创新等任何事情(这里的关键是,最大化新功能上线的速度,同时保证服务质量,一次事故不再是坏事,而是开发流程中不可避免的环节)
- 对我们来说,整体可靠性还差得远。。。我们是做得不够而不是太多,但是还是可以在特定项目和特定时期思考如何把握这个平衡,对不同的系统可以制订各自的目标。或者对于我们更重要作用意义,是可以更量化的设定我们在质保环节的标准,而不是凭感觉。
监控
监控系统不应该依赖人来分析警报信息,而是应该自动分析,仅当需要用户执行某种操作时,才通知用户
- 对于我们来说,比如开发平台的报警,要考虑如何更加智能的分析,比如失败重试这种的报警,不能简单触发,需要更智能的判断发送的时机,减少不必要的报警。
Google SRE将大部分工作重心放在了“运维手册”的维护上,同时通过演练不断实践和培训团队成员
- 对于我们来说,两方面: 1. 平台上业务任务故障的处理,应该给用户更明晰的排查指南,提供更易用的工具,确保排查手段流程的文档化。 2 对于平台自身的运维,标准化,文档化。
监控系统的4个黄金指标:延迟,流量,错误,饱和度(容量/负载)
- 这可以是个维度划分的指导原则,我们可以按这4个维度来分类整理组织监控数据?
注意长尾,监控指标的平均值可能无法有效反映/发现系统问题
- 对一些指标,应该采用比如中位值,99分位值,分组统计等方式来处理,避免掩盖问题
变更管理
自动化的完成: 1. 渐进式发布,2. 迅速准确的检测到问题, 3. 安全快速的回退
- 对于我们来说,1,是一个原则,需要强化这个思想 2 做得很不够,发布的变更,结果是否正确,没有快速判断的手段,需要针对性的建立 3. 需要加强回退预案的制订,做到更标准化是一个可行的手段。
所有的二进制文件,都支持用一个命令显示自身的构建时间,构建源代码版本,构建标识符等,很容易将二进制文件和构建过程对应起来
- 显然很有用的一个功能,但是,怎么做到100%覆盖的?! 能否在发布系统中支持自动添加这个功能? ;) 或者自己打patch做到? 我们做不到全部系统支持,那么重要的系统自己打patch做起来还是可以考虑的。和发布系统,发布流程的标准化是可以相互辅助的
基于版本分支发布,而不是基于主分支发布,bug等cherry picking到发布分支,这样可以明确每个发布版本的内容,便于维护和跟踪
- 基于固定的主分支来做发布流程,加上tag等机制估也能做到类似效果,不过,看起来还是上面的逻辑比较顺,不过这样的话,每个发布,分支可能都不一样,发布系统自动化的逻辑处理可能稍微麻烦一些
稳定性,可靠性相关
服务质量目标
全球Chubby服务计划内停机,服务质量大大高于SLO目标的时候,人为的进行可控的故障停机,进而敦促依赖于这个系统的其它系统更好的认知面对chubby的可能故障,而不是按自己的理解,假设chubby的可靠性。
- 挺有意思的做法,就我们的情况来说,首先,我们的服务质量可能还没有达到这个水平,但是,思想上其实是一致的
- 要和业务方达成服务质量目标认识的一致性
- 可以通过计划内的模拟演练,敦促业务方面对SLO目标以外的故障,对风险进行控制,做好预案,而不是一味要求底层服务的完全可靠性,或者依赖于特定的假设。比如集群可能存在主备节点切换,比如ZK可能列表上的第一个节点故障。这种场合,业务不应该出现严重问题。
- 反过来说也成立,底层系统,我们需要考虑模拟故障的情景,采取适当的容错措施
SLI(服务质量指标)与SLO(服务质量目标)实践
监控并度量SLI
比较SLI和SLO,以决定是否需要采取操作
如果需要,采取什么操作
执行这些操作
哪些适合用来做SLI,如何更好的定义好SLO?进一步说,故障等级,我们如何更好的更科学的制订(其实也就是,要关注哪些SLI,如果违反SLO,有什么明确后果?进而更好的敦促系统在这方面进行改进)
比如,调度系统或者集群的吞吐率,可能是一个需要监控的SLI,虽然他不一定和故障有直接联系,但是改进和关注它,对降低故障(往往是数据延迟)是一个非常有意义的手段。
failure injection : 通过日常化的向系统里注入可控的失败来监控系统的健壮性,主要是复杂的系统,变化频繁,牵连众多,需要一个机制来时刻检验它的稳定性。
- 这个我们目前整体上来说,也没到这个水平,但是,可以有计划的在现有的系统里通过这种方式来加强测试,基于失败流程来测试,而不是基于成功流程来测试,可以逐步构建这个机制,比如调度系统这样逻辑复杂的系统就有必要采取这种方式?
负载均衡
后端主动要求停止发送请求(跛脚鸭状态),是一种可靠识别后端负载情况的方法,也容易透明的处理后端节点维护问题
- 我们的调度系统的worker执行器,可以考虑添加这种主动流控机制
加权轮询,给后端一个服务能力值,用轮询的方式按权重分发,根据后端的表现:如资源使用,响应延迟等等情况周期性的调整权重
- 调度系统 worker负载流控可以考虑添加这种轮询策略
应对过载:将重要性这个参数信息,作为了RPC请求的一级属性!每个RPC请求都会标识重要性,这样在服务质量保证方面给后端服务提供了更多信息来更合理的区别处理
- 这个很理想的一种方案,可以考虑在我们的部分系统中添加,比如调度系统的作业调度请求
处理连锁故障
要尽可能保证缓存层只是用来提高服务性能,而不是服务能正常工作的强制依赖,如果变成了强依赖,那么就要考虑改变这种依赖关系,比如可以过量配备该服务。
- 比如权限系统就有类似的问题,我们其它偏底层,对可靠性要求高的系统也要考虑这个原则,不能让缓存成为风险
调用链永远向下,以避免循环依赖。
- 主要是防止在故障发生时,正反馈效应雪崩放大故障
重试:系统故障时,无节制的重试可能导致系统故障进一步放大
- 明确的错误返回码,将可重试错误和不可重试错误区分开来
- 限制重试次数
- 考虑全局重试预算,例如调度系统中,可以在master端限制重试频率?
- 采用随机的,指数递增的重试周期策略
上面的手段套到我们的实际系统中,想想看,哪些近期可以/应该 做到
请求延迟和截止时间:在RPC请求中,明确的传递服务截止时间机制
这个实现难度有些大,容易执行偏差,不过,在我们的一些大流量系统中,是要考虑这种方案来应对过载。
连锁故障的测试: 负载提高到测试到出现故障后,还要继续测试!!原因是:
- 继续测试已发现是否在过载的情况下,服务只是拒绝一部分请求,但是能继续存活下来,而不是崩溃
- 还要进行流量恢复的测试,以判断服务是否能恢复,负载需要降低到多少才能恢复等。
我们的压力测试,应该考虑这个原则,而不是仅仅压上限,更多的是更好的发现问题点。
考虑降级方案!考虑降级方案!
- 考虑避免过载是一方面,直面过载,寻求降级方案同样重要。核心系统流程都应该好好想一想
数据安全
备份数据,关键不是备份,关键是数据是否能够恢复,关注恢复,这才是重点,而不仅仅是备份!
- 复制和冗余不代表可恢复性。
数据丢失的场景,最常见的原因是用户误操作和软件bug,最难处理的场景是bug造成的数据丢失是渐进的,而不是突然的大规模的损坏
- 仔细回想一下,我们的情况也是如此,比如离线集群,所以,有必要专门针对性的采取措施。
第一层保护手段是软删除(或辅助“延迟删除”),第二道防线是备份及其相关的恢复方法, 第三层和最后一层是定期数据验证,及早发现问题!
- 软删除机制是防止开发者错误和户错误的有效手段
- 延迟删除机制是防止内部开发错误的主要防御措施
- 知道数据丢失的越早,恢复越容易和完全。-》我们尤其需要加强预防验证的机制
- 考虑定期带外数据校验
- 定期数据恢复演练
杂项
简化
最小API,不提供非必要的API
所有没用的代码,都应该删除,而不是注释,或者功能开关之类,无用代码会干扰后续开发,或者留下定时炸弹,而版本管理工具,让恢复代码变得很容易
- 我们有不少系统,同学图方便,采用了注释等拌饭,需要纠正这种观念,及时清理代码,普及代码版本管理的最佳实践
服务的容量管理
谷歌的服务通过BNS地址进行抽象,然后服务注册时会配置每个BNS的可用容量,用QPS为单位
- 这显然是一种预配置化的流控手段,我们也可以考虑在一些服务中采用这种思路? 比如调度系统的executor,按不同的机器配置容量?然后将不同的任务标准化为一定的容量使用负载?进而进行流控。
基础设施的风险和服务需求管理,在多个不同的竞争性需求的约束条件下,分割服务,提供不同的服务质量,比如bigtable用高冗余集群服务低延迟要求的服务,用冗余度较低的集群服务更关注吞吐率而非低延迟的服务
- 我们的服务也有类似的情况,比如HBase,比如调度集群,或者调度的worker的服务负载是否都可以用这个原则划分一下
- 比如按任务重要性分worker执行,KPI任务的执行,所在的worker负载流控阀值可以配得更低一些,所在的任务的JVM参数可以放得更宽一些,等等之类的手段来分割服务,提供不同服务质量。
事后总结
对需要写事后总结的场景制定标准
- 目的是形成风气和习惯
对事不对人的完成事后总结,
- 重点海是事后总结的风气要端正,才能发挥作用。
需要评审事后总结的完整程度
- 和方案评审一样,目的是保障这件事请做的质量,让总结不是走形式,而是能真正帮助改进和发挥作用
公开共享事后总结文档,便于大家学习和吸取经验
- 这个很重要,形成开放的态度,同时,对大家的质量意识也是一个敦促