草庐IT

B站接入层网络演进实践

SYS-网络团队 2023-03-28 原文

01 网络设计背景

1.1 稳定性和扩展性 

在设计任何网络结构时,网络的稳定性和扩展性是两个必然要考虑的因素。丢包、拥塞、扩容三大标准决定了网络质量的上限和下限。任何程度的网络质量波动都会对点直播视频业务的生产和消费造成最为直接的影响。基于B站始终把用户体验放在第一位的前提下,在设计网络前必须对网络的流量模型,业务对网络的要求做出充分调研。继而从设备选型、网络规划、技术应用、协议设计、生态演进等多维度做出最贴合当下B站客户需求的网络方案并落地实施。

1.2 带宽和流量模式

随着视频化时代到来,承载业务的数据中心其规模也与日俱增,新增的数据中心所包含的服务器容量从几千台迅速攀升至数万台。传统的树形网络结构中,在网络结构和带宽容量方面,未曾考虑到数据中心内东西向流量的需求,大多是为了满足南北向流量的大带宽应用而设计,因此这种结构虽然能满足业务一时的应用场景。但是由于各层上下联带宽存在较高的收敛比现象,后期如果需要扩容带宽,就需要通过升级各网络元件,如扩容核心设备的业务板卡、Fabric等。

同时,在线、离线主机应用程序,比如AI、大数据计算集群,产生了显著的东西向流量。一些特定应用和场景(比如多活改造),需要集群间的大量数据复制。传统的树形结构在满足东西方向大带宽需求上捉襟见肘,要么组网成本太高,要么无法实现,因为整个组网受限于商用物理设备形态限制,比如设备端口密度等等。

1.3 成本优化

B站的网络基础设施CAPEX(Capital Expenditure)在整体IT成本中占比显著。因此,技术团队通过优化个别网络单元的成本来改善这一现象。具体可以用以下两种实现方式:

统一所有的网络元素,最好使用相同的硬件类型或相同的设备。执行批量采购的同时,引入多家网络设备供应商,充分竞争,从而达到降低成本的目的。

为了丰富厂商的多样性,需要制定标准的网络参数要求。这一措施大大提高了厂商选择的灵活性,同时为白盒化设备提供基本的技术指标。

1.4 高效运营

随着网络设备数量增加,网元故障频次必然增多,缩小网络故障域是降低网络OPEX(Operational Expenditure)的一个重要指标。网络中容易产生广播和单播风暴,这会对网络稳定性和可靠性造成影响。如何高效运营管理网络,这是一个热门的话题。在网络设计之初,按全路由设计能缩小故障范围,将故障域设定在更小的网络范围中。在全路由设计时,尽量使用同一种路由协议(比如BGP协议),来简化设备控制面复杂度,从而降低网络崩溃的概率。

02 B站接入层结构演进

2.1 DCN V1.0网络结构

B站DCN V1.0方案中,接入层和核心层均采用堆叠组网方案,网关配置在Spine设备,整个网络处于一个大型的二层广播域。如图1:

图1 DCN V1.0结构

在堆叠方案中将两台接入交换机虚拟为一台,起到冗余备份的作用,服务器通过Bond接入交换机,提升接入层面网络的可靠性和稳定性。Spine层也是将两台核心网络设备通过堆叠虚拟为1台。堆叠带来的好处是设备控制面只有一个,两台交换机进行集中式配置,减少了频繁登录不同设备的操作时间,整体简化了网络设备管理成本;两台接入交换机的表项依靠堆叠心跳线进行同步。但在组网方案和后期运维中堆叠方案逐渐暴露了两个风险。

风险一:软件风险

无论是哪个厂商的设备,都无法保证软件系统不存在BUG,一旦出现BUG就需要对设备软件升级补丁或软件版本。虽然有类似ISSU的技术可以实现不中断升级,但ISSU的适用范围仅限两个版本差距很小的情况,且在实践过程中各厂家无损升级技术复杂度高,升级风险较大,成功率低,会或多或少引入额外问题,导致升级过程中网络连通性异常。另外堆叠成员节点单独升级会影响控制面,影响网络稳定性。

风险二:分裂风险

交换机之间互联的堆叠线路出现故障或者异常时,将导致堆叠分裂,虽然不常见,但是在实际运行过程中仍会遇到,B站历史上就曾经出现过此类Case。产生的问题是分裂后,等同于网络中出现了两台配置完全相同的交换机,造成网络配置冲突,最终导致堆叠系统所承载的业务中断。

面对这个分裂风险,当然也有相应的解决办法,就是一旦系统检测到分裂情况,就会将除去堆叠口、管理接口以及管理员指定的例外端口之外的其他端口全部DOWN掉,来防止分裂后对网络造成影响。虽然这种方式规避了配置完全相同的两台交换机出现在网络里面,但代价也是显而易见的,业务恢复操作变得复杂,远程恢复操作变得极难。

基于以上两个风险点及其他堆叠组网带来的隐患,B站当前数据中心接入层组网堆叠技术已不再使用。

2.2 DCN V2.0网络结构

为了解决堆叠方案的问题,2019年初开始,团队开始对DCN网络结构进行重新设计。Leaf接入层采用M-LAG技术(跨设备链路聚合组)取代原来的堆叠方式,Spine层不再使用堆叠,每台设备独立运行,同时为了更好的冗余和提升带宽收敛比,在Spine层增加网络设备数量。Spine-Leaf层运行EBGP路由协议,破除大二层网络带来的广播风暴风险。DCN V2.0网络结构如下图2:

图2 DCN V2.0结构

M-LAG(Multichassis Link Aggregation Group)跨设备链路聚合组,是一种实现跨设备链路聚合的机制,让两台接入交换机以同一个状态和被接入的设备进行链路聚合协商,从而把链路可靠性从单板级提高到了设备级,组成双活系统。在被接入的设备看来,就如同和一台设备建立了链路聚合关系。相比DCN V1.0结构,V2.0结构有效解决了交换机软件版本升级难问题,两台接入交换机可以独立进行升级,保证有一台设备正常工作即可,对正在运行的业务几乎没有影响。同时接入层面做一些配置优化,如配置Monitor联动设备上下行端口,BGP路由协议配置优化等,相比V1.0时代网络稳定性和可扩展性提升了一个层级。但与此同时,DCN V2.0网络结构中还是存在以下问题:

  • 收敛比:指单台网络设备的上行与下行带宽比例,一般按不同的业务应用设计不同收敛比,很难做到1:1的收敛比。由此带来的运维问题是需要随时监控Spine上行带宽容量,达到预定阈值时需要及时扩容带宽;
  • 扩展性:因Spine使用高功率框式交换机,在IDC机房包间扩容时,只能采购指定品牌交换机的业务板卡,不利于扩展,另外由于整个机框的端口密度受限,也会限制整个DCN规模扩展;
  • 高电柜:现有框式交换机由于整机功率高,对机房环境有硬性要求,机房物理机柜、电力、空调等均需要按需求进行改造。引入额外成本支持,同时改造完后机房内可能还是存在机房内局部过热情况;
  • 心跳线:组网中接入层虽然由原来的堆叠升级到M-LAG技术进行组网,但同样两台设备需要通过心跳线控制两台交换机同步数据,始终未做到接入层设备独立的情况,在设备升级和日常运维中还是会带来不少挑战;
  • OPEX&CAPEX高:框式设备对软件特征的要求高,限制了选择厂商设备的灵活性,无法充分引入竞争;维护多种芯片架构,增加了测试、培训、维护的要求。
基于以上M-LAG组网带来的相关问题,B站网络团队在DCN组网结构上继续探索,砥砺前行寻找最新DCN结构组网方案,由此B站DCN V3.0组网结构登场。

03 DCN V3.0网络结构

2020年底B站网络团队与国内外互联网头部企业、设备供应商等广泛交流与学习,开始调研新一代DCN盒式组网方案,并于2021年中旬完成DCN V3.0网络结构整套方案验证。且于2021Q3在新建数据中心落地应用3.0组网结构,经过半年的灰度验证,整个组网稳定运行,当前此组网方案已全量在B站数据中心部署;DCN 3.0网络结构如图3所示:

图3 DCN V3.0结构

DCN V3.0网络结构说明:

  • 组网中相关名词解释:接入层交换机ASW(Access Switch),汇聚层交换机PSW(Polymerizes Switch),分发层交换机DSW(Distribute Switch);
  • POD内部的ASW/PSW/DSW 网络设备使用同种规格芯片(当前主流使用的Tomahawk3芯片),均为盒式交换机,设备轻便,易安装使用;
  • 服务器万兆接入场景下,单Server-Pod包含4台PSW和64台ASW,PSW上下行带宽收敛比达到1:1,单个POD支持64组机柜,按单机柜20台服务器接入,单POD最大可支持1200台服务器规模;
  • 服务器25G接入场景下,单Server-Pod包含8台PSW和64台ASW,保持PSW上下行带宽收敛比1:1的同时,25G接入场景下单个POD服务器规模容量不变;
  • 单个POD内的服务器规模可以根据业务需求变更PSW的上下行收敛比,做到单个Server-POD容量规模更大,同时可横向灵活扩展Server-POD数量,支撑整个机房的规模应用;
  • 整个组网去框化,机房现场无需改造机柜电力、空调等物理环境,直接使用现有普通机柜就可满足,且避免了局部过热的情况;
  • POD中两台ASW为一组,中间无心跳线连接,两台设备完全独立,服务器接入层通过Bond接入,开启双发ARP特性,组网去堆叠化;
  • 组网成本上,在相同收敛比的情况下,Capex采购成本相比上一代网络显著降低,达到降本增效的目的;
  • 超大规模机房引入Cluster概念的方式进行扩展,同时在机房内部增加SuperSpine平面,支持整个机房规模容量扩展。

3.1 组网参数优化

3.1.1 ARP配置优化

  • 接入层ASW开启ARP Proxy功能,抑制同一台交换机下的服务器通过二层直接转发流量;
  • 接入层交换机ASW更改业务网段的VLAN MAC地址,指定两台ASW设置相同的MAC地址,用于交换机转发流量到服务器;
  • 接入层ASW开启加快ARP超时时间设置,默认ARP超时时间各厂家不完全相同,统一配置ARP超时参数,加快ARP表项更新,避免故障情况下产生路由黑洞的可能性。
3.1.2 ASW风暴抑制

  • 接入层ASW下联服务器的聚合接口抑制二层广播转发/组播、二层未知单播转发,使得全网不存在二层转发流量,实现全路由转发。
3.1.3 LACP配置优化

  • LACP,即链路汇聚控制协议,全称: Link Aggregation Control Protocol ;
  • 服务器为默认采用Bond Mode 4,部分场景存在Bond Mode 0的情况;
  • ASW与服务器对接的聚合口需要设置相同LACP SystemID,对端的设备在逻辑上认为收到是LACPDU 报文是从同一台设备上发出;
  • ASW内两台ASW设置不同的LACP Device ID,使得服务器看到LACP成员端口编号不同;
  • 由于部分业务的特殊性,服务器网卡工作在Bond Mode 0场景下以充分利用网卡带宽。
3.1.4 DHCP配置优化

  • DHCP,即动态主机配置协议,全称: Dynamic Host Configuration Protocol ;
  • ASW设备的DHCP请求开启option 82特性,将DHCP relay source ip设置为本机loopback地址,避免dhcp server回包异常。
3.1.5 Hash配置优化

  • B站DCN 3.0网络结构中,由于DSW、PSW、ASW设备采用相同的芯片,因此存在HASH极化的风险,甚至在采用二层链路捆绑的情况下会加剧HASH极化的可能性。为避免出现Hash极化,所有设备均配置负载分担模式为五元组,即sip+dip+sport+dport,并调整ASW、PSW、DSW设备的偏移参数algorithm。
3.1.6 BGP配置优化

  • 全网运行EBGP路由协议,并根据实际情况不同路由类型的优先级;
  • 全网根据不同的业务类型将不同的路由条目设置Community属性;
  • 接入层ASW开启ARP转32位主机路由,并通过BGP重分发至网络,且设置community属性在DCN网内传递;
  • 所有设备开启BGP Balance特性,默认情况下流量经过ECMP进行负载分担。
3.1.7 服务器网络配置

  • 服务器网卡默认工作在Bond Mode4,部分特殊场景工作在Bond Mode0;
  • 服务器重新编译ARP内核模块,使服务器双网口支持ARP报文双发能力,目的是让接入层两台不同的ASW同时学习到服务器ARP地址,形成流量负载分担能力;
  • 当服务器接入层发生DOWN/UP时,在监控到网口UP后加入Bond同时批量发送本 Server的所有ARP到两个Bond成员口,同步ARP表项,解决单向流量问题。

3.1.8 Failover配置优化

  • 当ASW的上联接口全部DOWN时,下行接入服务器无法感知到,服务器会继续向故障接入交换机发送数据,此时由于ASW的上行端口全DOWN,交换机会将数据包全部丢弃,造成网络异常。开启ASW上下行接口Monitor-Link功能来规避此问题,当上行接口全部故障时,关闭下行接口。同时当上行接口UP时,下行接口也做延迟UP,预留一定时间供设备路由协议收敛,以避免出现路由黑洞的情况产生。

04 未来展望

B站网络团队按稳定和高效原则设计网络结构。底层物理网络通过物理线路、硬件设备和网络技术,形成了一张稳定且可靠的DCN网络,为上层业务提供高效和快速的转发通道。基础网络下承机房基础设施、上接业务,需要解决业务需求变化快和基础网络升级难这一对永恒的矛盾点。未来基础网络会继续紧跟技术发展潮流,根据业务需求,探索新型网络结构,为B站业务提供更稳定、更高效及高扩展的网络服务。

作者:哔哩哔哩系统部网络团队

负责B站数据中心网络规划、设计、建设、运维与优化,为公司业务提供稳定且可靠的网络服务。整个团队专注于数据中心内网、骨干网络、负载均衡、传输网络、虚拟化网络以及国际化网络的落地和应用,并根据业务的发展需求不断迭代更新底层基础网络设施。

有关B站接入层网络演进实践的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  3. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  4. unity---接入Admob - 2

    目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里​编辑 3.解析依赖到项目中

  5. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  6. ruby-on-rails - Rails 中同一个类的多个关联的最佳实践? - 2

    我认为我的问题最好用一个例子来描述。假设我有一个名为“Thing”的简单模型,它有一些简单数据类型的属性。像...Thing-foo:string-goo:string-bar:int这并不难。数据库表将包含具有这三个属性的三列,我可以使用@thing.foo或@thing.bar之类的东西访问它们。但我要解决的问题是当“foo”或“goo”不再包含在简单数据类型中时会发生什么?假设foo和goo代表相同类型的对象。也就是说,它们都是“Whazit”的实例,只是数据不同。所以现在事情可能看起来像这样......Thing-bar:int但是现在有一个新的模型叫做“Whazit”,看起来

  7. ruby-on-rails - 向 Rails 3 添加 Ruby 扩展方法的最佳实践? - 2

    我有一个要在我的Rails3项目中使用的数组扩展方法。它应该住在哪里?我有一个应用程序/类,我最初把它放在(array_extensions.rb)中,在我的config/application.rb中我加载路径:config.autoload_paths+=%W(#{Rails.root}/应用程序/类)。但是,当我转到railsconsole时,未加载扩展。是否有一个预定义的位置可以放置我的Rails3扩展方法?或者,一种预先定义的方式来添加它们?我知道Rails有自己的数组扩展方法。我应该将我的添加到active_support/core_ext/array/conversion

  8. ruby - 检查网络文件是否存在,而不下载它? - 2

    是否可以在不实际下载文件的情况下检查文件是否存在?我有这么大的(~40mb)文件,例如:http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm这与ruby​​不严格相关,但如果发件人可以设置内容长度就好了。RestClient.get"http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm",headers:{"Content-Length"=>100} 最佳答案

  9. Ruby 最佳实践 : working with classes - 2

    参见下面的示例,我想最好使用第二种方法,但第一种也可以。哪种方法最好,使用另一种的后果是什么?classTestdefstartp"started"endtest=Test.newtest.startendclassTest2defstartp"started"endendtest2=Test2.newtest2.start 最佳答案 我肯定会说第二种变体更有意义。第一个不会导致错误,但对象实例化完全过时且毫无意义。外部变量在类的范围内不可见:var="string"classAvar=A.newendputsvar#=>strin

  10. ruby - 404 未找到,但可以从网络浏览器正常访问 - 2

    我在这方面尝试了很多URL,在我遇到这个特定的之前,它们似乎都很好:require'rubygems'require'nokogiri'require'open-uri'doc=Nokogiri::HTML(open("http://www.moxyst.com/fashion/men-clothing/underwear.html"))putsdoc这是结果:/Users/macbookair/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/open-uri.rb:353:in`open_http':404NotFound(OpenURI::HT

随机推荐