主页 > 新闻 > 游戏中结合了AFK的实践,两种云原生技术在弹性计算的使用、原理和思考

游戏中结合了AFK的实践,两种云原生技术在弹性计算的使用、原理和思考

时间:2024-08-27 08:56 来源:网络 作者:辣手摧花

近年来,以容器计算和功能计算为代表的云本地技术已经彻底改变了我们构建和部署应用程序的方式。AFK (Sword and Crusade)也在发射前完成了战斗验证场景的集装箱化登陆。集装箱给我们带来了操作维护简单、弹性扩容等好处。然而,在推出后,我们逐渐发现容器在弹性伸缩延迟方面不够,于是将注意力转向另一种云原生技术:函数计算。本文结合AFK的实践,分享两种云本地技术在弹性计算中的使用、原理和思想。

- Lade, AFK(剑和远征)主程序

一、相关概念

什么是弹性拉伸

随着需求的增加和减少,系统可以扩展系统容量,实现高可用性。当业务下降时,可以通过降低系统容量来降低成本。简而言之,它是一种低成本的可扩展计算。

什么是冷启动

游戏中结合了AFK的实践,两种云原生技术在弹性计算的使用、原理和思考

冷启动是应用程序从不存在到准备服务的过程。在游戏互动领域,超过5秒的等待时间通常是不可接受的。

什么是集装箱技术

Docker几乎等同于容器,它提供了一种标准的方式来将应用程序的代码、运行时、系统工具、系统库和配置打包到一个实例中。Kubernetes(以下简称K8S)是一款集装箱集群管理系统,可实现集装箱集群的自动部署、自动修复、自动扩容、应用无缝升级等功能。

什么是函数计算

函数计算又称Faas,是函数即服务的全称,它是Serverless(云计算的方向之一)的一个子集,是整个Serverless的核心。Serverless,也被称为“Serverless”,是在一个完全由第三方管理的无状态计算容器中运行服务器逻辑的开发人员。Faas具有细粒度调用、实时扩展和不关心底层基础设施的特性。

是什么战斗检查

战斗校验和是在服务器上运行的一段战斗逻辑代码,用于验证玩家的客户端是否上传了未被操纵的战斗。

战斗体检的弹性要求

战斗验证通常是一帧一帧的计算,CPU消耗很高,1个V1团队的战斗通常需要n毫秒,5个V5团队的战斗需要5N毫秒。以AFK中文服务器为例,每天的全天重置任务也是整个战校集群的业务高峰,每天晚上,随着上线人数的减少,整个战校集群进入业务低谷。两者在CPU消耗上有10倍的差异。

二、容器的弹性膨胀

根据旋转训练监控的指标数据自动伸缩容器,并根据算法进行调度。调度主要由资源层的Pod和Node完成。

应用维度

从应用场景的角度来看,应用层维度可分为水平扩展和垂直扩展。在篇幅有限的情况下,本文介绍了主流水平扩张:

1. 下丘脑-垂体-肾上腺轴的

水平Pod自动缩放是Kubernetes中实现Pod自动水平缩放的一个特性。HPA组件每30秒从Metrics Server和其他监控组件获取CPU等监控指标,并根据算法计算出预期的份数,通知Depolyment和其他组件进行扩容。

期望的豆荚= ceil(sum(MetricValue)/目标)

例如,当前HPA设置CPU阈值为70%。目前有3个pod有90%的CPU。那么预期荚果数= CeiL(90%*3/70%) = 5。在这一点上,HPA将创建2个新的pod水平扩展。

HPA CPU

根据CPU配置进行缩放比较容易,但有一个缺点,如果毛刺负载大于100%,则HPA你无法从一次计算中计算出需要多少个pod,所以你需要多次调整它们。每次调整还需要间隔一次膨胀冷却循环,默认为3分钟。如下图所示,一个Pod从1到8需要三个周期。

HPA每秒

因此HPA具有自定义度量扩展,而QPS是常用的。通过设置单个Pod的QPS值大于10,当流量达到QPS阈值时,集群会自动扩展。QPS是一种潜在的约定,其中集群每秒的CPU消耗相对平均,并且当给定时间点上CPU消耗请求的数量大幅增加时,QPS无法适当地测量它。导致集群容量无法满足业务需求。

2. CronHPA

结合以上可以发现,HPA扩容调度存在一定的延迟。当业务出现毛刺时,HPA无法及时调整THE NUMBER of PODS到预期的服务数量,导致部分应用不可用。这种商业焦虑可能会给玩家带来非常糟糕的体验。为了解决这个问题,我们引入了CronHPA,它有点像Linux的Crontab。根据业务前的周期性规律,资源提前10分钟准备,以满足高负荷的需求。CronHPA与HPA不同,HPA是一个官方版本,提供了实现方法。CronHPA基本上依赖于开源社区或云供应商的实现方法。AFK使用的是阿里云的CronHPA。以下是CronHPA的进化过程:

大多数供应商现在都有CronHPA

目前,大多数云厂商仍然采用这种方式实现,包括之前的阿里云。CronHPA和HPA都直接控制部署,以计划应用程序的扩展和收缩。由于它们不能相互感知,所以由CronHPA扩展的Pod很快就会被HPA恢复,并且它们是不兼容的。如下所示:

为了同时得到HPA和CronH对于PA特性,AFK一直保持双SVC配置,分别支持HPA和CronHPA。每次和阿里云集装箱同学交流的时候,我们都在督促彼此进步。

阿里云的新版本CronHPA

正如您可以看到的,这个实现总是在调整HPA Min值,而不是当前的Replicas号。这样的设计有一个巧妙之处。例如,我们的HPA是min/ Max:10/99999, n-n +4是业务的高峰。我们可以配置n-1:50扩展到100,而N-10:10(不需要等待到12:00)收缩到10。我们发现,虽然HPA Min在n10被调整为10,但当前的pod数量仍然由CPU计算。它不是直接下降,而是随着业务量的减少逐渐接近HPA Min。这样就不需要将整个n-n +4点的规模保持在100,大大减少了资源的浪费。

在实践中,CronHPA非常适合周期性应用场景。但是,需要将HPA配置为处理低估流量或意外流量的最终保证。

资源层维度

在资源层维度上,目前主流的方案是通过Cluster Autoscaler实现节点水平伸缩。当pod不足时,Cluster Autoscaler安装由Cluster配置的扩展实例规范,从云供应商的公共资源池购买实例,在初始化后注册实例,Kube Scheduler将新的pod调度到节点。链接越长,越容易出错,结果往往是集群不反弹。

集装箱的冷启动环节

除了长链路导致的不稳定,整个资源层扩容大约需要2-3分钟。为了解决扩展时间过长的问题,社区发布了一个新的组件Virtual KUbelet,通过它可以将K8S节点伪装成其他服务。例如,阿里云的ECI底层采用基于型的安全沙箱容器,深度优化容器运行环境,提供比虚拟机更快的启动速度。整个资源层扩容时间可缩短至30秒以内。

第三,弹性函数的计算

如上所述,Faas是Serverless的核心。让我们首先纠正两个常被误解的术语:

无服务器并不意味着您不需要服务器。最好称其为“服务器免费”。这仅仅意味着程序员可以忽略服务器而专注于业务实现。对于那些使用Erlang的人,而不是像c++那样手动分配和释放内存,您可以将它交给GC,但它仍然存在。

函数计算实际上是作为一个代码单元运行的,而不是作为代码中的一个单独的函数。函数可以被解释为一个函数,或者像main这样的函数条目可能更合适。

函数计算的调度

相对于K8S的复杂逻辑,函数计算对开发者来说非常友好,整个调用过程如下:

如图所示,调度系统感知到有请求到来:

函数计算通过监视更细粒度的函数执行,将复杂性引入基础设施。客户端请求服务,如果有空闲的实例,则直接返回它们进行计算。如果所有实例都很忙,就会很快创建新的实例以增加压力(没有算法,只是暴力)。

函数计算冷启动环节

通过函数计算冷启动环节的例子也很简单,如下所示:

链接简介:

忽略业务逻辑的执行逻辑,FAAS从调度到ECS采集到服务启动大约需要1秒的时间。

四、实际业务用途

当我们谈到弹性时,我们必须考虑负载平衡,当服务负载不是均匀分布时,那么可能导致部分服务不可用。让我们以AFK为例,看看在业务使用中容器计算和函数计算的区别:

加载配置

一般情况下,容器的SVC需要通过挂载SLB来对外提供服务。负载均衡依赖于负载均衡的轮询机制。轮询机制不知道Pod的实际负载,可能导致负载失衡。下面是一些AFK实际使用中负载不平衡的例子:

问题:一段战斗验证码,概率非常小,计算出非常大的坐标,导致逻辑循环,导致停滞的进程无法响应来自SLB的请求,SLB无法感知Pod,将继续发送新请求,新请求将继续失败。

解决方案:引入超时报警机制,在业务层做监控,记录超时数据,本地恢复修复。

问题:在AFK是一个Node上的多个Pod之前,Node作为SLB的服务器单元,因为每个Node上的Pod数量不一致,导致每个Pod处理的请求数量不一致,导致负载不均衡。

解决方法:直接将Pod作为服务器单元挂载到SLB的后面。

问题:这是一个Node上有多个pod引起的问题。部分节点有两个pod,导致该节点的CPU超过50%。Linux系统调度成本更高,导致Pod性能下降,处理相同的请求时负载增加。

解决方法:尽量在节点上均匀分布pod,保证节点的cpu基本一致。或者在节点上部署Pod。

问题:模型不一致,导致荷载不均匀。第六代机器的性能比第五代机器高15%左右。混合使用第五代机器将导致更高的Pod负荷。

解决方案:集群扩张时,将第六代模型放在首位,尽量保证模型不混在一起。

函数计算,发展人们不必担心负载,调度系统将对每个请求进行适当的安排,以确保有实例及时处理请求。对于上面提到的死循环问题,函数计算还提供了一个超时处理机制,避免了死循环造成的代价问题。

伸缩配置

游戏中结合了AFK的实践,两种云原生技术在弹性计算的使用、原理和思考

容器需要配置HPA和CronHPA,配置如下:

功能计算不需要进行伸缩相关配置,调度系统仍然会根据请求实时取出空闲实例或创建新的实例来处理请求。

通过对比可以发现,函数计算并不关心与负载和伸缩相关的配置,这大大减轻了开发人员的负担,使他们更多地关注业务本身。

5. 容器和功能的计算,如何选择?

可以互相弥补吗

由于函数计算具有极大的弹性,它通常很适合我们的弹性业务需求。然而,功能计算目前还不是一个社区产品。它是由云供应商实现的,是一个黑盒。我们不能登录到实例来查看场景,因此我们必须严重依赖跟踪来定位问题。容器虽然没有功能那么有弹性,但对我们来说是免费的。两者在使用中,不需要进行代码修改,所以AFK的最终解决方案是将容器优先级给予,将函数计算的方式,结合非正常容器请求后,将函数计算重试(当然也建议一些请求彼此给予优先级,要主动削减一些流程功能的计算,只有达到一定的水平,云供应商才会热情支持)。这确保了大多数请求都落在容器上,从而允许我们定位问题。当出现意外流量或流量估计不足时,系统可以快速扩展以满足业务需求。两种云产品的结合也提高了容错能力。毕竟,两种产品的弹性取决于某个复杂的环节。

甚至相互结合,目前,一个名为Knative的社区产品正在进行公开测试。Knative定位为基于K8S的功能计算解决方案,将容器和功能计算相结合。通过引入queue-proxy模式满足了将容量降至0的要求,引入KPA算法将应用层的容量扩展降至10秒以内。Knative团队一直在努力工作。在解决了探测、膨胀等问题后,应用层的扩展有望达到第二层,让用户感觉不到任何东西。

免责声明:本篇文章内容及配图来自互联网,供学习和分享使用,不代表本站的观点,内容和图片如有侵权请及时联系删除QQ。

相关新闻