移动互联网高速发展的早期,企业更多关注业务扩张,用成本投入来换取市场占用率。但如今移动互联网经历了近十年的高速发展,互联网人口红利逐渐消退,几乎没有公司能够再忽视成本。无论是苹果公司的供应链、库存管理,还是特斯拉通过国产化降低成本,又或者是各大云厂商对企业 IT 成本的优化,都是这些企业保持高速发展的重要因素。
企业在早期的资源使用上以满足业务需求为第一要务,资源的使用率管理相对粗放。无论是机器规划的多样化还是容量规划问题,或者是在离线资源的整合问题,归纳起来其实都是额外预留了不需要的资源,导致成本浪费。
近些年随着云原生的兴起和建设,服务已经具备快速迁移能力。基于此,资源容量就可以按需申请,最小化闲置资源,业务也可以在不同的时间段在相同的机器上按需要部署,不同规格的机器可以基于超高规格的机器(256C/2T)混合部署,化零为整,大幅降低资源成本。微博在云原生改造过程中也尝试进行了各种能力建设,并梳理了以下 6 种有效的成本优化手段。
手段 1:混合编排(提高单机利用率)
业务在选择机器规格时,选到一个最合适的规格是几乎不可能的事情。不同业务使用的机器规格差异巨大,从 CPU 密集型、内存密集型,到网络、IO 密集型甚至容量密集型,涉及成百上千种规格,而实际上无论是 IDC 自采的机器还是公有云提供的机器,可选规格都是有限的。这种差异就会导致成本大量浪费,有一些典型的内存密集型场景可能会有 1C/128G 的规格需求,CPU 存在大量的浪费,如果能够使用适合的机型必然就能够优化成本。
而云原生时代构建以 Docker、Kubernetes 为代表的基础设施,能够解决多业务混部编排中存在的端口冲突、单网络空间端口数量限制、业务间资源隔离等问题。通过超卖、大规格机器(256C2T)共享冗余度等手段还可以进一步节省成本,但是也会引入服务部署过于集中的重大难题。如果一台大型机宕机的话,则可能会引起 30+业务应用和 200+资源实例宕机。面对这样的风险,就必须要有资源/服务治理措施,通过快速降级、迁移、下线等处理保障业务的稳定性。
神龙装箱示意图
微博的业务应用设备大部分配置 16C32G,考虑吞吐和时延等因素,堆大小一般设置小于 10G,加上堆外内存使用,整体内存利用率不高,CPU 利用率较高。后端资源如 MC、Redis、Pika 等,资源特性决定了对内存要求较高,利用率较高,但对 CPU 利用率偏低。考虑业务应用和后端资源两种服务各自的特性,混合部署可以做到完全互补。
为了满足不同业务能混合编排在同一规格机器上的需求,我们将各种小机置换为大规格机器,围绕 Kubernetes 搭建的容器编排体系,对 Numa 节点、绑核、磁盘、网络进行了精细化的调度,通过服务/资源治理平台进行快速治理,在加上快速扩容、快速数据分发的能力,基本可以达到分钟级恢复,30min 内完成整机迁移。
从成本优化成果来说,在高密度容器混部编排后,整机利用率 CPU 提升一倍多,内存提升近一半,成本优化可达 15%以上。
手段 2:异地部署(物理成本)
IT 成本除了服务器自身的成本外,还包括部署服务器的成本、机房建设的成本、电力成本以及网络带宽和专线的成本等。一方面,一线热门城市由于土地资源有限等原因,机房建设成本相比于其他城市要高出不少;另一方面,由于一些地区电力资源丰富,其电力成本相比于其他的城市会更低一些。综合考虑多方面成本,选择在综合成本更低的地区建设或租用机房,或者选择公有云单价更低的可用区,可以明显地降低业务的 IT 成本。以公有云为例,不同地域间的成本会有 5%-30%的差距。
阿里云 ecs(ecs.c6.4xlarge)官方报价
在理想情况下,业务服务全部上云,同时新上的服务也不需要与已有服务互通,那么直接在单价更低的可用区部署服务就可以立即降低成本。但现实中的大多数情况是,业务已经在自建机房或公有云其他可用区做了部署,并且服务之间存在大量依赖。在这种情况下就需要将专线带宽的成本与业务耗时的影响考虑进去,使其综合收益最优。
以北京市为例,很多总部位于北京市内的互联网公司通常也选择租用北京市内的机房或是选择公有云位于北京地区的可用区,但与位于北京市西北方向的张北县或乌兰察布市相比,后者机房的成本相对更低,只不过由于相距 200~300 多公里,部署于两地的服务器 ping 耗时也有几毫秒到 10ms 左右。
为了降低时延对业务服务质量的影响,同时减少专线带宽传输的内容、降低专线成本,在部署在线业务服务器的同时,可以将访问量高的后端资源与在线应用一同部署,减少绝大多数跨专线的请求。此外,我们还使用了多机房消息同步的组件,使得单个机房的请求内循环,从而减少跨机房跨专线的请求,进一步提升了整体服务的可用性。
微博异地部署架构示意图
手段 3:自动扩缩容(降低服务常备冗余度)
一般而言,业务常规流量都是有规律的,大部分业务全天流量都存在很明显的波峰波谷现象。正常情况下业务需要预备足够多的机器数以满足服务日常峰值,除此之外,为了安全起见还要预留一定的冗余度,就是我们通常说的常备冗余度。
但是在一天的大部分时间里,业务流量都要比日常峰值低,如果线上日常维持能够扛住日常峰值流量并且冗余 30%的机器数量,就会造成很大的资源浪费。如果能够在保障服务稳定性、足以支撑业务峰值流量的前提下,降低服务的冗余度,甚至不需要备足常备峰值流量的机器,那服务的成本就能够大大降低。正常情况下,综合考虑常备机和按量机的占用时长及成本,那些波峰波谷清晰的业务能降低大概 30%的成本,若是波峰短暂且明显的话,成本还可以进一步降低。
某业务动态冗余度
微博场景下,我们根据线上实时流量的情况来进行动态扩缩容,使线上始终维持一定的冗余度,常备机器只需要能够扛日常峰值流量即可,这样即使动态扩缩容不能正常工作,也能保证线上服务正常运行。通过这种方式既能保证资源的有效利用,又能维持业务的常备冗余度。
而微博热点事件属于比较特殊的流量情况,有些业务甚至能在十分钟之内流量翻 10 倍之多。为了保证业务的稳定性,最简单的手段就是准备充足的机器,流量翻多少倍就准备能应付多少倍的机器。而随着用户的不断增长,流量会呈几何倍增长,那需要机器数量也会呈几何倍增长,为了能够动态应对随时可能超越之前历史峰值的流量,就需要具备极强的弹性扩缩容能力。在我们之前的文章《业界前所未有:10分钟部署十万量级服务资源、1小时完成微博后端异地重建》中也提到,目前微博已经具备 5 分钟 2000 台机器的闪电交付能力,后续基于神龙裸金属可以提供 5 分钟 8 万台机器的交付能力。此外,通过自研的数据恢复中心微博已经实现快速的数据分发能力,能做到 10 分钟百 T 级的数据恢复,1 小时完成整个微博后端重建。在降低冗余度后,只有具备快速扩容、快速数据分发能力才能保障服务稳定性,做到降容不降质。
对于快速发展中的业务,对复杂系统进行精确的容量规划难度非常高。近些年对于无状态服务,已经可以通过结合容器化基于 K8s 进行编排实现快速扩容,但对于大规模有状态的复杂业务场景,在提供服务之前,有海量的数据需要迁移,上百 T 数据的迁移甚至需要耗时数天,因此典型的方式还是要通过提升冗余度解决容量规划问题。
手段 4:错峰应用(共享服务间冗余度)
在上文中我们提到,业务流量自身的均值和峰值在数值上是有规律的,除此以外,其趋势往往也伴随周期性的高峰和低谷,具有很高的自相关性。不同业务的流量高峰低谷不尽相同,按业务的流量高峰做常备冗余部署资源,在其它业务的流量周期往往存在明显的资源浪费,例如一些周期性的运营活动(打卡/签到/抢购等)所属不同的业务服务,就会出现不同程度的资源浪费。如果这些业务的部分机器能够统一协调起来,让各个业务间共享冗余度,就可以很大程度地避免浪费从而降低成本。
面对上述场景,我们建设了微博服务数据画像平台,除了提供常规的时序特征,还支持各类指标趋势的预测服务:通过收集分析历史指标数据,对未来一段时间的指标趋势进行预测,从而确定各个服务的流量高峰及低谷对应的周期,并指导后续的资源调度。
根据我们的经验,当业务流量具有很高的自相关性时,使用简单的线性历史平均或指数历史平均就能取得不错的预测效果,使用常见的时序模型(Holt-Winters、时序数据分解、ARIMA)时 Mean Percentage Error (MPE) 一般都低于 5%,使用 XGBoost 或其它 Boost 模型拟合更是可以达到 1% 左右的 MPE。
某后端业务流量及自相关数据
结合上述服务画像平台提供的时序预测服务,调度侧可以针对性地进行资源全局调度:对于不同高峰时期的服务,整体规划资源互借,减少常备冗余资源的空闲程度,减少资源浪费,提高利用率;对于低谷期集中的服务,调度层做统一的资源回收,并放入整体的冗余资源池,提供给离线业务做固定周期的资源调度与整合(机器学习模型训练、数据分析与挖掘等)。从目前微博的实践情况看,通过上述手段,整体机器成本节省可超过 15%。
手段 5:在离线整合 (共享服务间冗余度)
在离线整合是错峰应用的一个典型场景,简单点说就是,服务器上白天跑应用,晚上用来跑离线任务,CPU 和磁盘 IO 都会被充分利用起来。在线业务日常 CPU 利用率的均值都不高,晚上机器会大量空闲,而离线业务则主要进行大规模的数据计算、日志处理和 AI 训练等,晚上常态利用率可能会比较高,随着业务的增长可能会出现资源不足导致任务跑不完的情况,而白天又刚好相反。面对这些现状,只有将离线、在线服务统一规划才能够充分使用资源,提升资源利用率,从而减少在线与离线服务器的采购成本。
但在离线整合并不是所有场景都适用,从网络架构到硬件架构,到操作系统、再到服务架构,以及周边的调度体系,这是一个复杂的工程。在离线整合的难点在于全自动化调度系统,我们需要同时保证在线不受到影响且离线运行良好。
在离线整合模式切换
在微博场景下,一是离线业务补给在线业务,微博业务每天中高峰及晚高峰都会存在,在这些时段下会将离线业务的部分实例拆分到在线业务;二是在线业务补给离线业务,大部分业务每天夜间基本流量很低,不到晚高峰流量的 1 成,这样的场景下会将在线业务实例整合为离线业务实例。以在线业务的冗余度作为在线业务的关键指标,通过冗余度指标进行决策调度(谁补给谁,补给多少),采用离线避让机制、在线业务兜底扩容等机制,最终保障在线不受到影响,离线运行良好。例如:一个 1000 台机器的在线业务,对等 1000 台机器的离线业务,典型的波峰波谷业务场景,预计可以节省成本 15%。
手段 6:Intel 换成 AMD(物理成本)
在 x86 服务器市场上,Intel 的 CPU 得益于其长久以来出色的稳定性和性能,占据了绝大多数的市场份额。但随着 AMD Zen 架构的 EPYC 处理器的推出,在同等性能下每核心的价格相比 Intel 的 CPU 更低。同时,AMD EPYC 的 CPU 最高提供单芯片 64 核 128 线程的规格,使得单台双路服务器能提供的最大规格达到了 128 核 256 线程,搭配上 2048GB 内存和 40GE 甚至更高速率的网卡,单台服务器能够部署更多的服务。若单个机架部署的服务器数量不变,则单个机架能够支撑的服务也更多,提升了机架的使用率,进一步降低了基础 IT 建设成本。以公有云厂商为例,同等规格的服务器采用 AMD 大概能降低 5%的成本。
AMD Numa 部署结构
大规格服务器节省成本的同时也带来了一些新的问题,在我们之前的《以微博核心业务为例,解读如何仅用1台服务器支持百万DAU》文章中也提到过,单机部署更多实例可能会带来可用性风险以及 AMD 双路服务器拥有 8 个 NUMA 节点导致绑核问题等。在微博业务中实际使用最多的场景是 256 线程的 AMD EPYC CPU 搭配 2048GB 内存,每个 NUMA 节点上拥有 32 线程及 256GB 内存,我们在每个 NUMA 节点上部署 2 个 12 线程 16GB 的 Pod 用于部署在线核心业务应用,部署 1 个 7 核 210GB 的 Pod 用于部署 Redis、Memcached 等缓存类资源,每个 Pod 都绑核在所在 NUMA 节点上,每台服务器共部署 24 个 Pod。
当然,为了保证可用性,我们对在线业务类 Pod 和缓存资源类 Pod 都制定了各种服务治理策略,用来保障业务服务的稳定性,当服务访问出现问题或是 Pod/机器的核心指标出现异常时,会根据服务治理策略进行快速处理,包括业务降级、资源摘除、服务/数据迁移等。
小结
如前文所述,我们总结了 6 种不同的成本优化手段,适用于目前微博普遍存在的场景。不管是降低物理成本、共享冗余度,还是降低服务/单机冗余度等,最终目的都是为了提高单机利用率,降低单机成本,在地域-硬件-业务-机器之间做拆分和整合,进而达到优化成本的目标。但与此同时,这些优化手段也会带来服务稳定性的巨大挑战,加大了服务和资源治理的难度,而解决这些问题则需要指标体系、调度体系、混合云、服务画像、硬件资源等方方面面的相互协作。
在微博的业务场景下,我们进行了不同程度的实践,并将以上 6 种手段的优化程度和难度简单梳理如下,供大家参考。
当然,微博还存在一些独特的业务场景,可以通过带宽优化、存储优化、冷热分离、应用优化等等手段做进一步优化,受限于文章篇幅,这里就不展开讨论了。
作者简介:
微博研发中心基础架构部 胡云鹏、孙云晨、胡忠想、刘燕和、胡春林
胡云鹏,微博基础架构部云平台技术负责人,2017 年加入微博,主要负责微博基础服务的架构改造升级工作,目前主要方向为混合云、资源云、服务/资源治理等。
孙云晨,微博基础架构部业务改造负责人。2015 年加入微博,参与并负责微博多个业务系统架构升级改造工作。目前主要关注资源服务化及业务研发效率的提升。
微博基础架构部前身是微博平台部门,从 2011 年起负责微博核心系统的研发和保障工作,构建了微博的高可用架构、缓存、存储、消息队列、稳定性、监控、服务化、混合云、AB 测试等后端基础架构和工具体系,并承担微博全站热点、三节和日常的业务运维和资源运维等稳定性保障工作。团队在混合云、弹性调度、高可用架构、热点峰值应对等方向处于业界领先水平,诚挚欢迎有志之士加入,共同打造业界一流的技术团队。
系列文章推荐:
评论 2 条评论