武安闯,2016年加入B站,深度参与B站微服务拆分、云原生改造、高可用建设、SRE转型和稳定性体系落地等项目。当前主要关注B站在线业务的SRE稳定性体系建设和推广,对SRE的实践有深入的探索与思考。
B站 SRE 发展的 5 年
2020年 SRE 稳定性体系初步完善,20年B站做了很多活动(S10、跨晚、最美的夜等)。有了故障前的应急响应及故障后的复盘,开始探索故障前混沌工程和故障演练;质量之后是容量,B站是容器化部署(探索 PaaS 容量管理体系),在一系列落地之后,2020年稳定性体系初步完善。2021年至今SRE继续转型,从 Oncall 制度逐渐转向 BP 制度,更加关注稳定性和降本增效。之前做了多活、服务分级、SLO都会在今年重新做优化建设。全员现在在做 SRE 转型。
稳定性保障
下面介绍一下转型过程中具体的解析。首先是稳定性保障(高可用、多活、容量管理、活动保障)。
高可用
中间件主要是 MQ,数据同步 Canal、DTS,消息通知 Notify、缓存;
存储层面是关系型数据库、 KV、对象存储、ES等等;
再往下是可观测与效率体系;
底层是稳定性体系,包括服务分级&SLO、混沌工程/故障演练、多活容灾/预案管理、问题管理/事件分析、容量/降本及活动保障。
接入层
这是接入层架构,用户通过 DNS 或降级 HTTP DNS 访问 CDN,CDN 通过机房边缘 POP 点汇聚流量到机房,机房有不同可用区(逻辑概念),每个可用区主要是 SLB 和 API GW。
常见的故障有几种:
网络故障:边缘节点回机房(运营商公网故障); 机房故障:一般比较少遇到(主要看概率); 组件故障:比如 SLB 节点发生故障等; 服务故障:SLB/API GW 所代理的服务等;
接入层的高可用方案,比如 DNS 降级 HTTP DNS、多 CDN 节点动态选路、APP边缘节点网络层故障降级第三方CDN重试;多 POP 点做流量汇聚,多线路做源站互备。
如果单可用区 SLB 故障,支持 CDN 从其他可用区跨专线回源。
对于后端服务故障,SLB可发现服务区的所有节点;单可用区服务故障节点可以自动降级。SLB 也支持常见的降级、容灾与限流。
最后是 7.13 故障,SLB重建花了一个小时,故障后对 SLB 初始化重建做了很多优化,现在可以5分钟重建一套SLB。API Gateway 的高可用与 SLB 类似,这里不再重复。
服务层
服务调用有 P2C 算法,服务A调用服务B,服务B会返回自己节点的 CPU 使用率情况,服务A基于这次响应的 RT(包括服务B每个节点 CPU 使用率/成功率来选择一个最优的节点),虽然服务B不同节点 CPU 算力不一,但最终 CPU 使用率是一样的;
熔断,服务B故障时,服务A做一个熔断;
降级的场景有两种:
一是可用区的降级,当服务B在某可用区故障,服务A调用B可以通过服务发现组件降级到其他可用区;另外是做多活的时候,服务在本可用区没有做部署的情况下降级到其他可用区;
内容质量降级,服务B故障服务A可以访问本地缓存/降级服务。在我们场景里,如果播放地址失败会降级到灾备播放地址。B站首页APP推荐可能是动态的,推荐系统故障也会降级给用户热门视频。
限流有两种,一种是微服务框架侧全局限流,它在框架层面的拦截器,B站内部主要是 Golang,使用 Kratos框架,基于框架做了分布式限流。第二部分是动态限流,不需要预先配置,基于 Google 的 TCP BBR 算法来实现的,会自动分析每个容器节点 CPU 使用率/成功 QPS 等来自适应做一个保护。
中间件
当发生 cluster 风暴,再遇到短连接就会出现雪崩,根本没办法恢复。想恢复只能重建缓存或做一个冷重启。后来我们对缓存做了统一的 proxy 代理(sidecar 模式,或者通过 proxyless sdk),也是为了降本增效,把单容器改成 sdk 模式进行部署访问。
消息队列主要做临时持久化,异步写DB。集中式代理,不用 sidecar 模式部署,我们内部支持 redis 和 gRPC 两种协议。2020年B站做了很多扩圈活动,kafka topic数量急剧增加,当时代理是 kafka 的 Sarama SDK,这个 SDK 也是各种炸,不停出现故障。
数据库层面,内部提供数据库 proxy,用 sidecar 模式部署。对业务做读写分离,对业务透明。对异常SQL做拦截,比如慢SQL。为了降本增效,现在也提供了SDK模式。
那有了高可用能力,B站就不炸了吗?2021.7.13故障,B站/微博/知乎全网热搜,我们做一下复盘。
2021.7.13 故障
同时也看到,多活是机房级故障时容灾止损最快方案!
高可用 - 多活
对机房进行梳理,当时上海有很多机房(都在一个地域内,机房定位比较混乱)。梳理后将上海的4个机房划成两个逻辑可用区,同城双活(Gzone 类型服务)部署在上海;把江苏可用区作为 Rzone 单元化服务部署模拟异地;我们又规划华北/华南的可用区,来做单元化、Czone 服务部署(30ms-40ms网络延迟)。
高可用 - 同城双活
GZS:Invoker
实际多活编排和切量流程是,编排先选择业务(评论/弹幕/播放)、选择业务类型(同城双活/单元化)、编排接入层规则。
数据库层编排是 KV、DB,要把多活各个维度资源编排出来,业务就可以发起切量。
业务和业务域。业务域(直播/电商/社区),业务域下会有业务(社区有评论/弹幕/点赞等),切量编排是对流量编排或存储编排。
切量完成之后触发审批。审批之后是巡检,巡检主要为三部分:
容量管理
容量管理之前,SRE 要想一个问题,要管什么容量?
在整个系统架构中有接入层(核心是带宽);
应用层面核心就是计算资源;
DB 和存储,那是存储资源。
对 SRE 来讲,容量管理的核心应该是应用。
容量管理做出之后谁关注?
不同角色关注是不一样的,比如研发/SRE/平台/预算团队等等。
目标收益是做之前要想清楚的。这里是每个角色对容量管理的预期:
研发核心是有资源扩容、自动扩容、发布/回滚不被资源限制。
SRE既要关注服务资源使用率,还要关注弹性扩缩,部门资源水位、降本增效。
部门维度,关注部门资源水位、使用率、部门成本、部门 TopN 服务报表。
平台维度,容器平台关注 Buffer、平台超卖、资源混部、资源利润率、降本增效。
成本团队就是资源用量、账单这些事情。
底层是 K8s 平台,上层是基于 K8s 应用基础数据搜集(集群容量/资源池容量/Node容量/应用容量/应用基本画像); 再往上是VPA/HPA/合池/配额管理。VPA 是面向 SRE平台(对研发不可见),VPA 的好处是动态调整服务 Request 指标,提升 K8s 可调度资源数量; HPA,横向弹性伸缩,面向研发,解决服务扩容的问题; 合池,Buffer 复用,增加弹性资源能力。要解决机器维度的差异或者 Node 节点的差异; 配额管理,没有合池每个部门只能看到独立资源的物理资源,合池之后看不到物理资源(只能看逻辑资源,LIKE云平台),Limit 作指标。
最上面就是容量可视化和报表运营,底层的元数据和容量保障之上给业务提供统一可视化平台/运营平台,查询部门资源容量/排序,某个组织/业务的容量和数据。
容量管理 - VPA
遇到一些痛点,当 Request 分配完,Used 特别低时,资源池没有资源可调度,SRE找研发按应用维度调整超卖率,对研发来讲想抢占资源,这个服务是稳定的,不想把资源释放出来,就导致共识很差,效率很低,收益特别小。后来把VPA改成平台维度。
右边是K8s与VPA联动的架构图,上面是 VPA 管理平台:策略管理/数据运营/黑名单/预警。
活动重保
活动开始前做活动了解
活动形式:直播/点播/秒杀/抽奖…
重点场景:不同活动重点不一样,弹幕互动、抽奖、送礼
活动对外链接:全链路保障
活动推送:站内推送、弹窗推送
活动后的场景:直转点、二次热点
时间线
容量预估
基础资源
交换机带宽、源站带宽
静动态CDN
业务资源
PaaS、laaS
Cache、MQ
压测&演练
内部压测分三轮:
第一轮:现有资源下压业务瓶颈;
第二轮:资源就绪后按照之前的预估人数做容量压测;
第三轮:所有优化和保障方案上线后压测演练。
演练层面两部分:
预案演练
故障演练:包括上下游依赖、中间件依赖、节点故障、HPA能力。
复盘清单
活动清单检查
关闭混部
关闭VPA
活动链路服务开启HPA
技保能力&预案
技术保障能力是侧重问题发生前的,你具备哪些高可用能力,有哪些能力保障业务稳定性。比如多活、跨机房降级、熔断等等,还有HPA、VPA等等。预案是问题发生之后应该怎么办,它们俩有不同侧重点,预案做攻击、容量、服务故障等三方面预案。
现场重保&复盘
看好监控大盘,把活动核心指标做定时同步,比如S赛,一场比赛结束之后就把这场比赛数据同步一下,包含前面讲的技术资源、业务资源、服务有没有出现一些高可用问题,比如有没有出现一些异常、限流。把活动中问题变更记录下来,复盘时不仅做活动当天复盘,还把活动从前期准备的问题统一复盘。
SLO 实践与反思
SLO
前面讲的是稳定性保障、高可用,服务可用性怎么度量?
我们先看一下 Google 的定义:
SLO 为服务可靠性设立了一个目标级别,它是可靠性决策的关键因素,是 SRE 实践的核心。
Google 甚至说没有 SLO 就没有SRE。为了使采用基于 SLO 的错误预算的可靠性工程方法,服务利益相关方认可 SLO,甚至服务可以达到 SLO。
基于 Google 的理论,B站基于现有分为两部分:服务分级与SLO系统。
服务等级分四级,L0-L3。对象包含业务(产品)=> 应用 => API。
业务就是产品,比如评论等级是 L0,评论下是应用,应用的等级不能超过产品等级。应用下有 API(发评论/拉评论),API的等级也不会超过应用的等级。
等级出来之后用于服务标准化、变革流程管控、报警测量,不同服务等级报警测量/稳定性要求不一样,比如服务有没有降级能力/多活能力。
服务分级&SLO
这是实践 SLO 的流程,首先创建业务&定级&定SLO;然后创建应用&定级;之后创建接口&定级&算SLI指标;最后基于接口聚合到业务上。
这种模型没有运转下去。
我们的反思:
新的模式:
事故定级
优化服务分级之后,也解决了事故定级中的问题。事故定级以前有两个指标,业务损失&服务等级:故障时间&PV损失,因为之前分级模型比较复杂,有业务/应用/接口,出现故障哪个等级作为故障的等级,我们经常在这里扯皮不清。
对业务分级做了优化之后,只对主场景定级,事故时看业务损失&业务定级&业务主场景系数。
SRE的培养与转型
工作分层
工作分层:最上面是比较传统的日常答疑、变更、报警处理等。再往下是 SRE 横向的串联、协作、拉通,再往下是SRE或运维核心,对业务做支持,比如业务迁移重构&改造,中间件推广、技术运营、应急响应等等。基于上面三层抽象出稳定性体系,再将各种稳定性实践整合成稳定性体系。
运维能力:基本运维能力、网络、OS/内核、架构能力
开发能力:工具开发、运维平台开发、工程能力等
合作共赢:项目管理能力、团队协作、同理心、情商与运营意识
个人潜质:学习能力、好奇心、逆向思维能力
责任心与担当。
培养与转型
SRE 培养有四方面:
SRE文化:团队要认可SRE文化,从团队Title和组织名称可以看到对SRE的重视;从上到下传达SRE的转型;SRE职级序列;
SRE方法论:学习 SRE 理论知识,主要是《SRE工作解密》《SRE工作手册》;
SRE讨论会:SRE方法论专题分享。基于理论做实践落地。方法论掌握之后再拉大家做讨论会,讨论SRE的章节、内容,包括SRE稳定性、基础运维架构的知识;
开发转型:SRE 绕不开开发,内部也鼓励做开发转型,B站基于Golang,SRE 也是基于 Golang,鼓励 SRE 先做工具开发,能力达标之后会分配专业开发导师,参与 SRE 平台开发实践,最终开发平台又提升了SRE工作效率,实现正向循环。
近期好文:
“高效运维”公众号诚邀广大技术人员投稿
投稿邮箱:[email protected],或添加联系人微信:greatops1118。
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...