Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >B站高可用用架构实践

B站高可用用架构实践

原创
作者头像
腾讯云开发者
发布于 2020-04-22 10:31:13
发布于 2020-04-22 10:31:13
241.1K96
举报

流量洪峰下要做好高服务质量的架构是一件具备挑战的事情,本文是B站技术总监毛剑老师在「腾讯云开发者社区沙龙online」的分享整理,详细阐述了从Google SRE的系统方法论以及实际业务的应对过程中出发,一些体系化的可用性设计。对我们了解系统的全貌、上下游的联防有更进一步的帮助。

一、负载均衡

负载均衡具体分成两个方向,一个是前端负载均衡,另一个是数据中心内部的负载均衡。

前端负载均衡方面,一般而言用户流量访问层面主要依据DNS,希望做到最小化用户请求延迟。将用户流量最优地分布在多个网络链路上、多个数据中心、多台服务器上,通过动态CDN的方案达到最小延迟。

以上图为例,用户流量会先流入BFE的前端接入层,第一层的BFE实际上起到一个路由的作用,尽可能选择跟接入节点比较近的一个机房,用来加速用户请求。然后通过API网关转发到下游的服务层,可能是内部的一些微服务或者业务的聚合层等,最终构成一个完整的流量模式。

基于此,前端服务器的负载均衡主要考虑几个逻辑:

  • 第一,尽量选择最近节点;
  • 第二,基于带宽策略调度选择API进入机房;
  • 第三,基于可用服务容量平衡流量。

数据中心内部的负载均衡方面,理想情况下会像上图右边显示那样,最忙和最不忙的节点所消耗的CPU相差幅度较小。但如果负载均衡没做好,情况可能就像上图左边一样相差甚远。由此可能导致资源调度、编排的困难,无法合理分配容器资源。

因此,数据中心内部负载均衡主要考虑:

  • 均衡流量分发;
  • 可靠识别异常节点;
  • scale-out,增加同质节点以扩容;
  • 减少错误,提高可用性。

我们此前通过同质节点来扩容就发现,内网服务出现CPU占用率过高的异常,通过排查发现背后RPC点到点通信间的 health check 成本过高,产生了一些问题。另外一方面,底层的服务如果只有单套集群,当出现抖动的时候故障面会比较大,因此需要引入多集群来解决问题。

通过实现 client 到 backend 的子集连接,我们做到了将后端平均分配给客户端,同时可以处理节点变更,持续不断均衡连接,避免大幅变动。多集群下,则需要考虑集群迁移的运维成本,同时集群之间业务的数据存在较小的交集。

回到CPU忙时、闲时占用率过大的问题,我们会发现这背后跟负载均衡算法有关。

第一个问题,对于每一个qps,实际上就是每一个query、查询、API请求,它们的成本是不同的。节点与节点之间差异非常大,即便你做了均衡的流量分发,但是从负载的角度来看,实际上还是不均匀的。

第二个问题,存在物理机环境上的差异。因为我们通常都是分年采购服务器,新买的服务器通常主频CPU会更强一些,所以服务器本质上很难做到强同质。

基于此,参考JSQ(最闲轮训)负载均衡算法带来的问题,发现缺乏的是服务端全局视图,因此我们的目标需要综合考虑负载和可用性。我们参考了《The power of two choices in randomized load balancing》的思路,使用the choice-of-2算法,随机选取的两个节点进行打分,选择更优的节点:

  • 选择backend:CPU,client:health、inflight、latency作为指标,使用一个简单的线性方程进行打分;
  • 对新启动的节点使用常量惩罚值(penalty),以及使用探针方式最小化放量,进行预热;
  • 打分比较低的节点,避免进入“永久黑名单”而无法恢复,使用统计衰减的方式,让节点指标逐渐恢复到初始状态(即默认值)。

通过优化负载均衡算法以后,我们做到了比较好的收益。

二、限流

避免过载,是负载均衡的一个重要目标。随着压力增加,无论负载均衡策略如何高效,系统某个部分总会过载。我们优先考虑优雅降级,返回低质量的结果,提供有损服务。在最差的情况,妥善的限流来保证服务本身稳定。

限流这块,我们认为主要关注以下几点:

  • 一是针对qps的限制,带来请求成本不同、静态阈值难以配置的问题;
  • 二是根据API的重要性,按照优先级丢弃;
  • 三是给每个用户设置限制,全局过载发生时候,针对某些“异常”进行控制非常关键;
  • 四是拒绝请求也需要成本;
  • 五是每个服务都配置限流带来的运维成本。

在限流策略上,我们首先采用的是分布式限流。我们通过实现一个quota-server,用于给backend针对每个client进行控制,即backend需要请求quota-server获取quota。

这样做的好处是减少请求Server的频次,获取完以后直接本地消费。算法层面使用最大最小公平算法,解决某个大消耗者导致的饥饿。

在客户端侧,当出现某个用户超过资源配额时,后端任务会快速拒绝请求,返回“配额不足”的错误,有可能后端忙着不停发送拒绝请求,导致过载和依赖的资源出现大量错误,处于对下游的保护两种状况,我们选择在client侧直接进行流量,而不发送到网络层。

我们在Google SRE里学到了一个有意思的公式,max(0, (requests- K*accepts) / (requests + 1))。通过这种公式,我们可以让client直接发送请求,一旦超过限制,按照概率进行截流。

在过载保护方面,核心思路就是在服务过载时,丢弃一定的流量,保证系统临近过载时的峰值流量,以求自保护。常见的做法有基于CPU、内存使用量来进行流量丢弃;使用队列进行管理;可控延迟算法:CoDel 等。

简单来说,当我们的CPU达到80%的时候,这个时候可以认为它接近过载,如果这个时候的吞吐达到100,瞬时值的请求是110,我就可以丢掉这10个流量,这种情况下服务就可以进行自保护,我们基于这样的思路最终实现了一个过载保护的算法。 

我们使用CPU的滑动均值(CPU > 800 )作为启发阈值,一旦触发就进入到过载保护阶段。算法为:(MaxPass * AvgRT) < InFlight。其中MaxPass、AvgRT都为触发前的滑动时间窗口的统计值。

限流效果生效后,CPU会在临界值(800)附近抖动,如果不使用冷却时间,那么一个短时间的CPU下降就可能导致大量请求被放行,严重时会打满CPU。在冷却时间后,重新判断阈值(CPU > 800 ),是否持续进入过载保护。

三、重试

流量的走向,一般会从BFE到SLB然后经过API网关再到BFF、微服务最后到数据库,这个过程要经过非常多层。在我们的日常工作中,当请求返回错误,对于backend部分节点过载的情况下,我们应该怎么做?

  • 首先我们需要限制重试的次数,以及基于重试分布的策略;
  • 其次,我们只应该在失败层进行重试,当重试仍然失败时,我们需要全局约定错误码,避免级联重试;
  • 此外,我们需要使用随机化、指数型递增的充实周期,这里可以参考Exponential Backoff和Jitter;
  • 最后,我们需要设定重试速率指标,用于诊断故障。

而在客户端侧,则需要做限速。因为用户总是会频繁尝试去访问一个不可达的服务,因此客户端需要限制请求频次,可以通过接口级别的error_details,挂载到每个API返回的响应里。

四、超时

我们之前讲过,大部分的故障都是因为超时控制不合理导致的。首当其冲的是高并发下的高延迟服务,导致client堆积,引发线程阻塞,此时上游流量不断涌入,最终引发故障。所以,从本质上理解超时它实际就是一种Fail Fast的策略,就是让我们的请求尽可能消耗,类似这种堆积的请求基本上就是丢弃掉或者消耗掉。

另一个方面,当上游超时已经返回给用户后,下游可能还在执行,这就会引发资源浪费的问题。

再一个问题,当我们对下游服务进行调优时,到底如何配置超时,默认值策略应该如何设定?生产环境下经常会遇到手抖或者错误配置导致配置失败、出现故障的问题。所以我们最好是在框架层面做一些防御性的编程,让它尽可能让取在一个合理的区间内。 

进程内的超时控制,关键要看一个请求在每个阶段(网络请求)开始前,检查是否还有足够的剩余来处理请求。另外,在进程内可能会有一些逻辑计算,我们通常认为这种时间比较少,所以一般不做控制。

现在很多RPC框架都在做跨进程超时控制,为什么要做这个?跨进程超时控制同样可以参考进程内的超时控制思路,通过RPC的源数据传递,把它带到下游服务,然后利用配额继续传递,最终使得上下游链路不超过一秒。

五、应对连锁故障

结合我们上面讲到的四个方面,应对连锁故障,我们有以下几大关键点需要考虑。

第一,我们需要尽可能避免过载。因为节点一个接一个挂了的话,最终服务会雪崩,有可能机群都会跟着宕掉,所以我们才提到要做自保护。

第二,我们通过一些手段去做限流。它可以让某一个client对服务出现高流量并发请求时进行管控,这样的话服务也不容易死。另外,当我们无法正常服务的时候,还可以做有损服务,牺牲掉一些非核心服务去保证关键服务,做到优雅降级。

第三,在重试策略上,在微服务内尽可能做退避,尽可能要考虑到重试放大的流量倍数对下游的冲击。另外还要考虑在移动端用户用不了某个功能的情况下,通常会频繁刷新页面,这样产生的流量冲击,我们在移动端也要进行配合来做流控。

第四,超时控制强调两个点,进程内的超时和跨进程的传递。最终它的超时链路是由最上层的一个节点决定的,只要这一点做到了,我觉得大概率是不太可能出现连锁故障的。 

第五,变更管理。我们通常情况下发布都是因为一些变更导致的,所以说我们在变更管理上还是要加强,变更流程中出现的破坏性行为应该要进行惩罚,尽管是对事不对人,但是还是要进行惩罚以引起重视。

第六,极限压测和故障演练。在做压测的时候,可能压到报错就停了。我建议最好是在报错的情况下,仍然要继续加压,看你的服务到底是一个什么表现?它能不能在过载的情况下提供服务?在上了过载保护算法以后,继续加压,积极拒绝,然后结合熔断的话,可以产生一个立体的保护效果。 经常做故障演练可以产生一个品控手册,每个人都可以学习,经常演练不容易慌乱,当在生产环境中真的出现问题时也可以快速投入解决。

第七,考虑扩容、重启、消除有害流量。

如上图所示的参考,就是对以上几个策略的经典补充,也是解决各种服务问题的玄学

「腾讯云开发者社区」公众号回复「在线沙龙」获取PPT下载链接~

六、Q&A

Q:请问负载均衡依据的 Metric是什么?

A:我们用服务端的话,主要是用CPU,我觉得CPU是最能体现的。从客户端角度,我是用的健康度,健康度指的是连接的成功率。延迟也是一个很重要的指标,另外我们要考虑到每一个client往不同的back end发了多少个请求。

Q:BFE到SLB是走公网还是专线?

A:这个其实有公网也有专线。

Q:如果client就几千量级,每10s pingpong 一下,其实也就几百 qps?会造成蛮高的cpu开销?

A:如果你的client是几千,但上游你的各种服务加起来client实际上是非常多的可能过万。 所以它是会造成蛮高的CPU开销的,因为好多个不同的应用来healthcheck,其实这个量就非常大了。

Q:多集群的成本是怎么考虑的?

A:分集群。前文提到的多集群更多是在同一个机房内布置多套机群,那么这个多套集群,首先它肯定资源是冗余和翻倍的。 这个确实是需要一定成本,所以我们也不是所有服务都会来做这种冗余,只会针对核心服务。所以本质上就是花些钱,做些冗余,来尽可能提升我们的可用性,因为你越底层的服务一旦故障,它的故障面真的是扩散非常大。 

Q:超时传递是不是要求太严格了,如果有一个节点出问题就不行了。

A:这个策略就是超时传递,我们默认是传递的,那么在有一些case情况下,即便超时仍然要继续运行,这个行为实际上是可以通过我们的context上下文把它覆盖掉,所以还是看你代码的逻辑处理。

Q:用户的接入节点的质量和容量是怎么平衡的?

A:取决于调度的策略。通常来讲需要先看你的服务是什么用途,如果是那种面向用户体验型的,或者功能型的,我觉得质量是优先考虑的。其次,在你转发的机房不过载的情况下,尽可能交付到最近的节点,那么极端情况下有可能你机房过载,那么这种情况下其实是不得已通过接入节点来转发到其他的核心机房。 

讲师简介

毛剑,bilibili技术总监,腾讯云最具价值专家(TVP)
毛剑,bilibili技术总监,腾讯云最具价值专家(TVP)

毛剑,bilibili技术总监,腾讯云最具价值专家(TVP)。负责bilibili数据平台部,拥有近十年的服务端研发经验。擅长高性能、高可用的服务端研发,熟悉Go、Java、C等语言。在B站参与了,从巨石架构到微服务的完整转型,包含微服务治理、微服务可用性设计,微服务数据一致性设计,微服务中间件,微服务监控,微服务日志收集,微服务负载均衡,和微服务RPC框架开发等。

开源业内比较有影响力的项目: goim https://github.com/Terry-Mao/goim 分布式IM长连接广播服务; bfs https://github.com/Terry-Mao/bfs 分布式小文件存储

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
96 条评论
热度
最新
见证社死时刻 ...
见证社死时刻 ...
回复回复1举报
打卡,感谢分享~~
打卡,感谢分享~~
回复回复点赞举报
程序员何必为难程序员 纵观历史 谁都有过头疼的时刻
程序员何必为难程序员 纵观历史 谁都有过头疼的时刻
回复回复点赞举报
看这么多评论,你们运营部要加薪么
看这么多评论,你们运营部要加薪么
回复回复点赞举报
慕名而来
慕名而来
回复回复点赞举报
打卡
打卡
回复回复点赞举报
大卡
大卡
回复回复点赞举报
奥利给
奥利给
回复回复点赞举报
全网呼叫蒙古上单
全网呼叫蒙古上单
22点赞举报
跟我们内蒙古有关系么
跟我们内蒙古有关系么
回复回复点赞举报
哈哈哈哈
哈哈哈哈
回复回复点赞举报
来打个卡...
来打个卡...
回复回复点赞举报
加载更多
推荐阅读
编辑精选文章
换一批
东方证券企业架构之技术架构转型实践
微服务架构是近几年受到各行业广泛追捧的技术之一,微服务架构具有轻型化、便捷化、敏捷化等特点,不仅能够适应业务创新和变化的需要,而且易于维护、变更、升级,契合当前证券业务发展的需要。然而向微服务架构转型也面临不少挑战,东方证券通过构建统一的服务治理框架,打造了一个多语言、多协议、可视化、灵活配置的服务管理平台,支持东方证券企业技术架构向以微服务为核心的现代化架构转型。本文将介绍东方证券 gRPC-Nebula 服务治理框架与星辰服务治理平台的建设成果,并介绍转型过程中的实践经验。
深度学习与Python
2020/09/14
9280
微服务系列 2:微服务化框架的模型和治理能力设计
紧接上一篇,微服务系列 1:微服务化框架落地的挑战和核心需求,那么基于这些核心诉求,我们整个的微服务框架的模型是如何?又该具备哪些核心的治理能力呢?通过本文来一一知晓!
Allen.Wu
2023/03/01
7800
微服务系列 2:微服务化框架的模型和治理能力设计
工作十年,在腾讯沉淀的高可用系统架构设计经验
👉腾小云导读 在系统的开发过程中,很多开发者都为了实现系统的高可用性而发愁。本文从研发规范层面、应用服务层面、存储层面、产品层面、运维部署层面、异常应急层面这六大层面去剖析一个高可用系统的架构设计需要有哪些关键的设计和考虑。希望腾讯的经验方法,能够给广大开发者提供参考。内容较长,您可以收藏后持续阅读。 👉看目录点收藏,随时涨技术 1 高可用系统的架构设计思想     1.1 可用性和高可用概念     1.2 高可用系统设计思想 2 研发规范层面     2.1 方案设计和编码规范     2.2 容量规划
腾讯云开发者
2023/03/14
5.4K0
工作十年,在腾讯沉淀的高可用系统架构设计经验
熔断、隔离、重试、降级、超时、限流,高可用架构流量治理核心策略全掌握
对于人类的身体健康来说,“三高”是个大忌,但在计算机界,系统的“三高”却是健康的终极目标。本文将介绍一下流量治理是如何维持这种“三高”系统的健康,保障数据流动的均衡与效率,就如同营养顾问在维持人类健康饮食中所起的作用一般。
腾讯云开发者
2023/12/27
2.5K0
熔断、隔离、重试、降级、超时、限流,高可用架构流量治理核心策略全掌握
QQ音乐高可用架构体系
在分布式系统建设的过程中,我们思考的重点不是避免故障,而是拥抱故障,通过构建高可用架构体系来获得优雅应对故障的能力。QQ音乐高可用架构体系包含三个子系统:架构、工具链和可观测性。
腾讯技术工程官方号
2023/03/08
2.4K0
QQ音乐高可用架构体系
聊聊高可用的 11 个关键技巧
面对一个庞然大物,如果没有一个合理的分工分层。任何一个小小失误都会被无限放大,酿成巨大灾难。
微观技术
2022/05/27
3950
聊聊高可用的 11 个关键技巧
【字节跳动】第十五讲 微服务架构原理与治理实践| 青训营笔记
周余发:2018年硕士毕业,曾在美团点评研发效率中心、抖音服务架构担任系统开发。目前为字节跳动Service Mesh研发人员。
了凡银河系
2022/08/22
7780
【字节跳动】第十五讲 微服务架构原理与治理实践| 青训营笔记
基础总结(系统设计/微服务/中间件)
注: 此系列内容来自网络,未能查到原作者。感觉不错,在此分享。不排除有错误,可留言指正。
fliter
2023/06/18
2830
基础总结(系统设计/微服务/中间件)
全面!一文理解微服务高可用的常用手段
在定义什么是高可用,可以先定义下什么是不可用,一个网站的内容最终呈现在用户面前需要经过若干个环节,而其中只要任何一个环节出现了故障,都可能导致网站页面不可访问,这个也就是网站不可用的情况。
DevOps时代
2019/08/12
4.3K0
全面!一文理解微服务高可用的常用手段
架构详解
所谓网站架构模式即为了解决大型网站面临的高并发访问、海量数据、高可靠运行灯一系列问题与挑战。为此,在实践中提出了许多解决方案,以实现网站高性能、高可靠性、易伸缩、可扩展、安全等各种技术架构目标。
奥耶可乐冰
2024/01/10
2960
架构详解
高并发高可用高性能的解决方案汇总整理
大家好,又见面了,我是你们的朋友全栈君。 难题与方案 1、亿级流量电商网站的商品详情页系统架构 面临难题:对于每天上亿流量,拥有上亿页面的大型电商网站来说,能够支撑高并发访问,同时能够秒级让最
全栈程序员站长
2022/08/04
2.8K0
高并发高可用高性能的解决方案汇总整理
11个高可用设计实战技巧,轻松应对大厂面试
面对一个庞然大物,如果没有一个合理的分工分层。任何一个小小失误都会被无限放大,酿成巨大灾难。
微观技术
2024/07/04
2711
11个高可用设计实战技巧,轻松应对大厂面试
优雅应对故障:QQ音乐怎么做高可用架构体系?
导语 | 故障是开发者高频关注的问题。在分布式系统建设的过程中,我们思考的重点不是避免故障,而是拥抱故障,通过构建高可用架构体系来获得优雅应对故障的能力。本文作者冯煦亮从架构、工具链、可观测三个维度,介绍了QQ音乐多年来积累的高可用架构实践。期望对你有帮助。 QQ音乐高可用架构体系全景 故障无处不在,而且无法避免。在分布式系统建设的过程中,我们思考的重点不是避免故障,而是拥抱故障,通过构建高可用架构体系来获得优雅应对故障的能力。QQ音乐高可用架构体系包含三个子系统:架构、工具链和可观测性。 架构:架构包
腾讯云开发者
2023/01/06
2.4K1
优雅应对故障:QQ音乐怎么做高可用架构体系?
微服务架构原理与治理实践|青训营笔记
对于单体服务,不同模块通信只是简单的函数调用,对于微服务,服务间通信意味着网络传输。
白泽z
2022/08/18
3710
微服务架构原理与治理实践|青训营笔记
微服务设计原则——高可用
(2)调用的下游不是为高并发场景设计;比如提供异步计算结果拉取的服务,并不需要考虑各种复杂的高并发业务场景,提供高并发流量场景的支持。每个业务场景应该在拉取数据时缓存下来,而不是每次业务请求都过来拉取,将业务流量压垮下游。
恋喵大鲤鱼
2024/03/25
2830
微服务设计原则——高可用
大话微服务架构的故障隔离及容错处理机制
8、限流器和负载开关(Rate Limiters and Load Shedders)
技术zhai
2018/08/27
2.5K0
大话微服务架构的故障隔离及容错处理机制
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
【基础的内容考察 ——回答原则:简单的问题不能答错(一道面试题就能淘汰一个人),新手和老手都要注意】
寻求出路的程序媛
2024/08/05
2330
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
【年度精选】高并发学习笔记
遵循"design for failure"的设计原则,未雨绸缪,具体优化方法有故障转移、超时控制、降级、限流
会玩code
2022/04/24
6070
【年度精选】高并发学习笔记
B 站崩了,总结下「高可用」和「异地多活」
不用想象一种异常场景了,这就真实发生了:B 站晚上 11 点突然挂了,网站主页直接报 404。
悟空聊架构
2021/07/16
8340
B 站崩了,总结下「高可用」和「异地多活」
用一个简单的方法构建高可用服务端
一. 什么是高可用性 服务端,顾名思义就是为用户提供服务的。 停工时间,就是不能向用户提供服务的时间。 高可用,就是系统具有高度可用性,尽量减少停工时间。 停工的原因一般有: 服务器故障。例如服务器宕机,服务器网络出现问题,机房或者机架出现问题等。 访问量急剧上升,导致服务器压力过大。导致访问量急剧上升的原因有: 时间和访问量都可以预见的,例如秒杀活动,售票系统。 时间和访问量都不可以预见的,例如特发性新闻(马航失联的事件) 停工的原因,可以理解为灾难,所以系统的高可用性就是容灾,即应对灾难的能力,系
Java架构
2018/06/19
1.1K0
推荐阅读
相关推荐
东方证券企业架构之技术架构转型实践
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档