B站2017年之前没有SRE,当时主要负责的事情就是效率优先,需求响应(比如变更、标准化、报警治理和琐事优化)。2018年引入SRE文化,开始理解业务架构、推进读的多活建设、探索 SRE 里的 Oncall 制度/复盘文化在B站的落地。
2019年正式进入落地,首先做了琐事优化(释放人力),将工单变更通过平台来自助审批。之后做了 SLO 体系探索,包括平台、基于 SLO 的服务分级体系、应急响应制度、复盘平台、问题管理制度建设等。
2020年 SRE 稳定性体系初步完善,20年B站做了很多活动(S10、跨晚、最美的夜等)。有了故障前的应急响应及故障后的复盘,开始探索故障前混沌工程和故障演练;质量之后是容量,B站是容器化部署(探索 PaaS 容量管理体系),在一系列落地之后,2020年稳定性体系初步完善。2021年至今SRE继续转型,从 Oncall 制度逐渐转向 BP 制度,更加关注稳定性和降本增效。之前做了多活、服务分级、SLO都会在今年重新做优化建设。全员现在在做 SRE 转型。
下面介绍一下转型过程中具体的解析。首先是稳定性保障(高可用、多活、容量管理、活动保障)。
先看下整体架构。用户首先从 CDN 层到接入层,接入层有4层 LB/7层 SLB,还有逐渐推广的 API GW。
之后进到服务层,服务侧会有一个 BFF(服务网关),下面是 Service、Job、Admin等。
这是接入层架构,用户通过 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 类似,这里不再重复。
上面说了南北向(接入层),现在来看看东西向。对 SRE 来说,这一层一定要了解(微服务架构),如果不了解一旦服务出现故障给不出业务故障止损预案。
服务调用是通过内部 Discovery 服务发现组件进行调用,服务部署了多活(可用区A和B),每个机房服务都是多节点部署,不同节点所运行的物理机(比如是CPU型号不一导致单核算力不一,要看 K8s 有没有做算力规划)。
这个过程可能出现问题,比如容器节点算力不一,服务B流量过载、可用区故障等,也有几种高可用能力:
一是可用区的降级,当服务B在某可用区故障,服务A调用B可以通过服务发现组件降级到其他可用区;另外是做多活的时候,服务在本可用区没有做部署的情况下降级到其他可用区;
内容质量降级,服务B故障服务A可以访问本地缓存/降级服务。在我们场景里,如果播放地址失败会降级到灾备播放地址。B站首页APP推荐可能是动态的,推荐系统故障也会降级给用户热门视频。
服务还有一种故障场景是中间件的依赖。
看看核心服务对中间件依赖,比如服务写数据,对评论、弹幕数据可以接受最终一致,把写的数据扔到 MQ,用 Job 消费消息队列,写入DB。DB 层面会挂一个 Canal 组件,来消费数据库binlog,将消息写回消息队列,再刷到缓存里。
我们用到最常见的组件就是缓存/MQ/DB。
缓存在生产系统里有三种模式,Redis Cluster、Redis单节点/分布式、Memcache(内部是按这个顺序做推荐建议),每种语言在生产环境 SDK 都出现过各种各样的 Bug。
比如短连接风暴,之前搞拜年纪活动,活动一开始充电服务就故障了。后来发现,Jedis 的并发数量超过配置的 Total 之后,后续连接会变成短链接。redis单线程机制,长连接和和短连接性能相差10倍的数量级,一旦遇到短连接性能就会急剧下降。
我们用过各种语言,连 Redis 之后,往一个节点发一些cluster nodes 或者 slot 风暴这种请求,甚至可能会固定往一个节点发请求,很快把一个节点打死了。
当发生 cluster 风暴,再遇到短连接就会出现雪崩,根本没办法恢复。想恢复只能重建缓存或做一个冷重启。后来我们对缓存做了统一的 proxy 代理(sidecar 模式,或者通过 proxyless sdk),也是为了降本增效,把单容器改成 sdk 模式进行部署访问。
消息队列主要做临时持久化,异步写DB。集中式代理,不用 sidecar 模式部署,我们内部支持 redis 和 gRPC 两种协议。2020年B站做了很多扩圈活动,kafka topic数量急剧增加,当时代理是 kafka 的 Sarama SDK,这个 SDK 也是各种炸,不停出现故障。
数据库层面,内部提供数据库 proxy,用 sidecar 模式部署。对业务做读写分离,对业务透明。对异常SQL做拦截,比如慢SQL。为了降本增效,现在也提供了SDK模式。
前面说了很多架构层面的内容,SRE 一定要了解业务架构,如果不懂架构只能做日常需求(那和配管没区别),不懂业务架构的 SRE 是没有灵魂的。
那有了高可用能力,B站就不炸了吗?2021.7.13故障,B站/微博/知乎全网热搜,我们做一下复盘。
2021.7.13 晚 10:52,用户反馈B站无法使用,内部大量服务、域名接入层报警不可用。
10:57分,Oncall 同学发现 SLB 故障。
11:17,内网登陆也受影响,17分核心成员才陆续进入内网系统。
11:23分,读多活业务基本恢复。多活机房 SLB 容量过载,多活机房服务层正常/接入层挂了(容量涨了4倍左右)。
11点之后流量逐渐下降,重启恢复。当时直播业务也做了多活,首页接口没做多机房流量分发(所以没有恢复)。
11:17分登陆分析问题,开始怀疑是 SLB 组件问题,联系最近在SLB层面做了三次引擎 Lua 层的变更,也没有恢复。
此时面临2个选择,一是继续排查问题(底层Debug,SLB具体是什么故障?);二是给业务一个可以预期的止损手段。
当时选择新建一套 SLB,尝试隔离流量恢复业务。之后验证流量隔离是有效的。
1:00左右,新建 SLB 全部完成,开始做业务流量切换。
1:40左右,业务已经全部切到新集群,核心业务全部恢复。
这里能看到很多问题:
通过 7.13 故障能看到:
对于多活元信息定义做了标准化,业务多活 CRG 的定义(CRG 定义参考了蚂蚁的多活模式)。
对机房进行梳理,当时上海有很多机房(都在一个地域内,机房定位比较混乱)。梳理后将上海的4个机房划成两个逻辑可用区,同城双活(Gzone 类型服务)部署在上海;把江苏可用区作为 Rzone 单元化服务部署模拟异地;我们又规划华北/华南的可用区,来做单元化、Czone 服务部署(30ms-40ms网络延迟)。
组件层面也做了优化。流量的 Router 是在 DCDN 层面,分发到各个机房,各个机房的服务在读写存储,主要是 KV、DB,Proxy 来做接入,同城双活的可用区只支持读,写都是通过 Proxy 转到主机房。通过 GZS 来做多活状态管理。
对这些组件优化主要是这几个:
GZS 内部叫 invoker,基于 API 的元信息管理,结合内部 CMDB 系统(CMDB 存储业务元信息/审批平台),同时联动内部几个多活组件,比如 DCDN/KV存储/DB存储/API GW 组件来做流量切换。核心就是优化上面四部分:
实际多活编排和切量流程是,编排先选择业务(评论/弹幕/播放)、选择业务类型(同城双活/单元化)、编排接入层规则。
数据库层编排是 KV、DB,要把多活各个维度资源编排出来,业务就可以发起切量。
业务和业务域。业务域(直播/电商/社区),业务域下会有业务(社区有评论/弹幕/点赞等),切量编排是对流量编排或存储编排。
切量完成之后触发审批。审批之后是巡检,巡检主要为三部分:
除了质量之外,前面提到降本增效一定是今年很多互联网公司的目标,下面说如何通过容量管理做降本增效。
容量管理之前,SRE 要想一个问题,要管什么容量?
对 SRE 来讲,容量管理的核心应该是应用。
容量管理做出之后谁关注?
不同角色关注是不一样的,比如研发/SRE/平台/预算团队等等。
目标收益是做之前要想清楚的。这里是每个角色对容量管理的预期:
思考这些问题之后,内部围绕 K8s 形成了容量管理,右边是架构图。
底层是 K8s 平台,上层是基于 K8s 应用基础数据搜集(集群容量/资源池容量/Node容量/应用容量/应用基本画像);
再往上是VPA/HPA/合池/配额管理。VPA 是面向 SRE平台(对研发不可见),VPA 的好处是动态调整服务 Request 指标,提升 K8s 可调度资源数量;
HPA,横向弹性伸缩,面向研发,解决服务扩容的问题;
合池,Buffer 复用,增加弹性资源能力。要解决机器维度的差异或者 Node 节点的差异;
配额管理,没有合池每个部门只能看到独立资源的物理资源,合池之后看不到物理资源(只能看逻辑资源,LIKE云平台),Limit 作指标。
最上面就是容量可视化和报表运营,底层的元数据和容量保障之上给业务提供统一可视化平台/运营平台,查询部门资源容量/排序,某个组织/业务的容量和数据。
VPA 是降本增效的利器。首先看几个概念,在应用维度K8s有三个指标,一个是CPU Used(实际用了多少CPU,比如Limit 配了8个C,Request能配4个C,超卖的2倍,业务实际应用了2个c,Used 2c/Request 4c/Limit 8c;应用 CPU Limit/CPU Request=业务超卖率)。B站一开始超卖是应用维度超卖,就是给到研发自己配置。
遇到一些痛点,当 Request 分配完,Used 特别低时,资源池没有资源可调度,SRE找研发按应用维度调整超卖率,对研发来讲想抢占资源,这个服务是稳定的,不想把资源释放出来,就导致共识很差,效率很低,收益特别小。后来把VPA改成平台维度。
改造平台维度之后,研发不关注超卖率,只关注 Limit,不再感知 Request,VPA 的指标放到平台维度,业务实际用了多少 CPU/CPU total=物理资源 CPU 使用率。CPU Limit/CPU Total=资源池超卖率。CPU Request/CPU Used=资源冗余度。内部情况物理资源 CPU 使用率低于40%,会调整 VPA 策略,动态回收 Request,比如有一个业务部门资源使用率特别低,直接调整为 VPA 策略。
右边是K8s与VPA联动的架构图,上面是 VPA 管理平台:策略管理/数据运营/黑名单/预警。
比如某些业务不适合VPA,比如Job类型/推送服务(一天只运行5-10分钟),给这个服务做VPA没有任何意义。
做活动时整个资源池应用CPU使用率会增加,这个时候开启VPA,会导致第二天资源池分配的 CPU request 会增加,导致资源池没资源可用。
同时做 VPA 之后也对 VPA 做了很多预警策略,发现VPA是否符合预期。
中间是 VPA 与 K8s 联动 VPA 策略引擎。
底层是 K8s 提供的 VPA API。VPA主要解决两个场景。一是新增一个Pod,比如一台机器挂了,pod做一个漂移很常见,这种场景通过 K8s 的 APIServer 层面 Webhook 对所有新增的 Pod 做VPA;二是下发 VPA 策略对存量所有 Pod 做 updater,存量和新增的 Pod 都可以VPA。
规则按照这四个来:服务等级/服务画像/资源类型/度量指标。举个例子,内部L0服务,以CPU Used 7天P99指标,来 VPA 所有容器 CPU 资源,L2服务既要做CPU的VPA,也要做内存的 VPA。基于1天的指标来做就会更有利。
这是线上合池K8s资源使用率,有两个指标,一个是只看容器CPU使用率,另外是一看物理机维度CPU使用率怎么样,在8月初,物理机使用率达到50%以上,整个容器层面也可以超过40%。在VPA之前,我们一个资源池CPU使用率高峰期可以达到20%-30%就不错了。今年上半年都没有加资源,就靠VPA满足业务新增所有需求。
前面讲了高可用、多活,B站每年会有很多活动,比如S11、跨网拜年纪。2021年S11当天直播在线人数突破千万。
活动保障流程主要是活动了解->容量预估->压测演练->复盘清单->技保能力&预案。
前面讲了高可用、多活,B站每年会有很多活动,比如S11、跨网拜年纪。2021年S11当天直播在线人数突破千万。
活动保障流程主要是活动了解->容量预估->压测演练->复盘清单->技保能力&预案。
活动形式:直播/点播/秒杀/抽奖…
重点场景:不同活动重点不一样,弹幕互动、抽奖、送礼
活动对外链接:全链路保障
活动推送:站内推送、弹窗推送
活动后的场景:直转点、二次热点
时间线
交换机带宽、源站带宽
静动态CDN
PaaS、laaS
Cache、MQ
内部压测分三轮:
第一轮:现有资源下压业务瓶颈;
第二轮:资源就绪后按照之前的预估人数做容量压测;
第三轮:所有优化和保障方案上线后压测演练。
演练层面两部分:
预案演练
故障演练:包括上下游依赖、中间件依赖、节点故障、HPA能力。
活动清单检查
关闭混部
关闭VPA
活动链路服务开启HPA
技术保障能力是侧重问题发生前的,你具备哪些高可用能力,有哪些能力保障业务稳定性。比如多活、跨机房降级、熔断等等,还有HPA、VPA等等。预案是问题发生之后应该怎么办,它们俩有不同侧重点,预案做攻击、容量、服务故障等三方面预案。
看好监控大盘,把活动核心指标做定时同步,比如S赛,一场比赛结束之后就把这场比赛数据同步一下,包含前面讲的技术资源、业务资源、服务有没有出现一些高可用问题,比如有没有出现一些异常、限流。把活动中问题变更记录下来,复盘时不仅做活动当天复盘,还把活动从前期准备的问题统一复盘。
前面讲的是稳定性保障、高可用,服务可用性怎么度量?
我们先看一下 Google 的定义:
SLO 为服务可靠性设立了一个目标级别,它是可靠性决策的关键因素,是 SRE 实践的核心。
Google 甚至说没有 SLO 就没有SRE。为了使采用基于 SLO 的错误预算的可靠性工程方法,服务利益相关方认可 SLO,甚至服务可以达到 SLO。
基于 Google 的理论,B站基于现有分为两部分:服务分级与SLO系统。
服务等级分四级,L0-L3。对象包含业务(产品)=> 应用 => API。
业务就是产品,比如评论等级是 L0,评论下是应用,应用的等级不能超过产品等级。应用下有 API(发评论/拉评论),API的等级也不会超过应用的等级。
等级出来之后用于服务标准化、变革流程管控、报警测量,不同服务等级报警测量/稳定性要求不一样,比如服务有没有降级能力/多活能力。
SLO 系统提供的核心能力就是做 SLO 指标的选择/计算/定义。
这是实践 SLO 的流程,首先创建业务&定级&定SLO;然后创建应用&定级;之后创建接口&定级&算SLI指标;最后基于接口聚合到业务上。
这种模型没有运转下去。
我们的反思:
新的模式:
说一下现在的玩法:创建一个业务只对业务主场景定级,比如评论核心就是发评论/拉评论(对这个场景定级)。应用不再需要定级,只需要打标。算 SLI 对多个对象/多条SLI指标做计算,某个API就是业务某一个具体波动的体现,也算它的指标数据。对业务指标,比如业务一些在线人数、播放量、发送的评论这是业务,我们会算三个维度的SLI指标。对这些指标做SLO的运营和质量运营。
仅度量SLI是没有任何意义的,核心是SLO报警和质量运营。
甚至SLO报警的重要性比质量运营更高,因为质量运营和SLI度量都不能帮业务提供什么东西,但 SLO 报警会帮业务第一时间发现问题,提升报警准确率。
优化服务分级之后,也解决了事故定级中的问题。事故定级以前有两个指标,业务损失&服务等级:故障时间&PV损失,因为之前分级模型比较复杂,有业务/应用/接口,出现故障哪个等级作为故障的等级,我们经常在这里扯皮不清。
对业务分级做了优化之后,只对主场景定级,事故时看业务损失&业务定级&业务主场景系数。
主场景故障系数是故障功能对主场景影响程度,这种模型完全把服务分级复杂模型包进去,不用在故障时扯皮。
工作分层:最上面是比较传统的日常答疑、变更、报警处理等。再往下是 SRE 横向的串联、协作、拉通,再往下是SRE或运维核心,对业务做支持,比如业务迁移重构&改造,中间件推广、技术运营、应急响应等等。基于上面三层抽象出稳定性体系,再将各种稳定性实践整合成稳定性体系。
对 SRE 的能力要求:
SRE 培养有四方面:
武安闯,2016年加入B站,深度参与B站微服务拆分、云原生改造、高可用建设、SRE转型和稳定性体系落地等项目。当前主要关注B站在线业务的SRE稳定性体系建设和推广,对SRE的实践有深入的探索与思考。
当前文章:2021.7.13故障后,哔哩哔哩SRE稳定性保障揭秘
网页网址:http://www.shufengxianlan.com/qtweb/news23/445473.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联