我是 Holly Cummins,是红帽公司的首席工程师,协助创建了 Quarkus。Quarkus 是一个超级可持续的运行时,我花了很长时间测量并优化 Quarkus 的碳足迹。我在这里想谈的是我在做顾问期间经常遇见的事,老实说也是现在我和客户交谈时常碰见的,这是什么呢?是僵尸威胁。不是《最后生还者》中的那类僵尸,而是电脑僵尸,但问题是一样的严重。这种东西只要你开始寻找,就会发现它们无处不在。
举个例子,前不久我在推特上看到一条推文,有人说 AWS 每月收他两美元,但他不敢把这个关掉又懒得去找是什么造成的带宽收费。他还收到过一个客户安装了八年的 WordPress 发来的邮件,但他很确定客户已经转去使用内部部署,没有再继续用 WordPress 了。虽然 WordPress 每月还在尽职尽责地给他发邮件,但他不知道该怎么访问这东西然后把它停掉。
这种情况下,他也确实进行了一番清理,关掉了自己在 2013 年创建的 Digital Ocean 数据包,这已经是九年前的事了。他也删掉了八年前也就是 2014 年创建的快照,这七年来他每月都要为这份快照交 74 美分。这类事情林林总总,无处不在。
无独有偶,在一次工作面试中参观实验室,几台老古董服务器引起了他的注意,他问这几架看起来很有年头的服务器是做什么的,然后得到了一个非常自信的答案:一个是另一个的备胎。倒是没错,但这些服务器是干什么的?这时空气似乎凝滞了,因为其实几十年来都没人知道这些服务器是干什么的。这家公司规模非常大,而在这么大的公司里,这些事情就会被遗漏,这也会发生在任何规模的任何地方,说起来容易但我其实也干过这种事。
我刚开始学习用 Kubernetes 的时候,我创建了一个集群练手。但后来事情太多我有好几个月没管这个集群,等我想起来的时候才发现我设置把这个集群设置得非常精细 ,每月租金都要一千美元。再加上这件事发生在我开始考虑可持续性之前,现在我无时不刻不在想着可持续性。但你猜怎么回事,就在我准备这篇关于僵尸的演讲的时候,我的待办清单上就有一件类似的事。对 Quarkus 来说,我们要在不同的硬件上运行 CI/CD,但 GitHub Actions 不太支持 Mac M1,所以我设置的这个自托管运行程序很难运行,最后被禁用了,这个集群实际没有运行任何构建,它里面只是一个运行起来会花钱的实例,虽然没多少钱,一个月 159 美元,但却是闲置不用的,非常可惜非常浪费。
僵尸实例的问题有多严重?
这个问题有多严重呢?传闻是一回事,但就和任何的性能优化一样,我们必须要以数据为根据。对僵尸来说这点很棘手,因为按照定义来说,僵尸是不可见的,这也是它们成为问题的原因。Anthesis Group 在这方面做了很多研究,我们可以很方便地参考他们的成果。他们在 2015 年对大约 4000 台服务器做过调查,其中大概 30%的服务器都没有在做什么实际的工作,没有任务也没有流量进出。他们在 2017 年又重复了这项研究,结果很类似。2017 年的 16000 台服务器中有 25%都没有在做什么有用的工作,“没有有用”是多没用呢,相当的没用。他们对“僵尸”的定义是在六个月或更长的时间内没有提供任何信息或计算服务的服务器,他们称这些为休眠服务器。这些服务器很长时间都没有为任何人做任何事了。
还有一类是未充分利用的服务器。这些是还有些生命体征僵尸,可能还有 5%的时间活着,但这种也是非常不活跃的。换成人来说,如果我有 95%的时间都坐在沙发上无所事事,那我周围所有人包括我的雇主都会非常生气,他们会想办法把我优化掉。但我们却能容忍这样的服务器。美国自然资源保护委员会(NRDC)指出,美国的数据中心所耗费的能源大部分都是供给 1200 多万台几乎没有实际工效的服务器。在气候危机和日益严重的金融危机背景下,这些毫无意义的浪费是如此荒谬。把这些统计数字换种算法,就相当于是正常服务器只运行 12%到 18%的能力,但却耗费了最大功率 30%到 60%的电量。这种比率并不理想,利用率不足的服务器虽然只减少了一小部分电量消耗,但却少做了许多工作。这些利用率不足的服务器占比很大,活跃时间占比少于 5%的服务器有 29%,和完全不活跃的服务器数量差不多的。这就意味着我们一旦把这两个数字加在一起,那几乎三分之二的服务器都没有存在的理由。
我提到过经济后果,而这种情况下的经济后果是巨大的。2021 年有一项由不同作者进行的研究显示,仅仅在共有云中,一年就有 266 亿美元巨资被永远在线的云实例浪费。这些就像是我自己的 GitHub M1 runner,启动后即使它没在做什么有用的事,我也不会把它关掉。 这很糟糕,现在大家都非常关注数据中心的效率,关注电力的来源。在某些情况下,如果你所处的地区非常环保,那么这部分金钱和电力就可能是绿色电力。但没有任何电力是真正绿色的,即使是绿色电力,也是没算上运行时成本问题,硬件也会有所谓的“隐含碳”。隐含碳是指服务器在制造过程中排放的碳,这一部分可能会非常可观,对笔记本电脑或手机来说,隐含碳是多数是受设备的影响。对服务器来说,由于服务器在正常使用过程中会消耗大量电能,因此隐含碳的占比较少,根据运行地点的不同,隐含碳可能依旧不容小觑。这就意味着,使用更为环保的电力或许并没有我们所希望的有效果,这仍然是我们需要解决的问题。
机器管理的复杂性
在解决问题之前,我们首先要明白到底问题是什么。我认为只是一个更大问题的冰山一角。在 2023 年,虽然我们已经掌握了这么多技术,但管理机器仍然非常困难。这是个我喜欢的故事,是僵尸故事的对立面。几年之前,一台失踪四年的 Novell 服务器被发现,这台努力工作的服务器不是僵尸,它工作认真,人人喜爱,但就是没人找得到它的物理位置。最终人们才发现是维护的人把它砌进了墙里,所以才没人能找得到它。这是服务器丢失的极端案例。丢服务器时常发生,在先前提到的研究中发现,被找到的服务器中有四分之一都是僵尸服务器,人们想破脑袋也不明白这是怎么发生的,最后只能认为是有人忘了关服务器。
如果我们仔细分析是什么造成了机构对这类事情的忽视,就会发现情况大概如下;一种情况是项目结束了但用的服务器却没有退役,也有可能是业务流程发生变化,不再需要支持旧流程服务器。造成这种浪费的一个常见原因是过度配置,没人愿意承担配置不足的责任,所以大家都谨慎地选择过度配置。另一个技术原因则是没人愿意因为隔离不足而导致系统因为漏洞而暴露。有些技术对多租户的支持更好,但即使是在 Kubernetes 集群中,CRD 也是共享的。多租户是有限的,为了确保适当的隔离,最终都会选择集群作为部署单位。归根结底,这其中很大一部分都是因为风险规避,这是很正常的组织现象。我曾经听说一个故事,有人怀疑自己的二十台服务器都是僵尸服务器,在基本确认后还是因为繁琐的文书工作,花费将近九个月才把这些系统全部关闭。
未充分利用的服务器可能情况有所不同,但也常常是出于风险规避。前段时间我拜访了我的一位客户,谈到了他们是如何管理服务器的,他们有一类专门在周末运行的批处理任务,但运作的服务器是全周都在线;还有一类进程和服务器只在英国的工作时间运作,但也是全天候运行。这类事情听起来像是自动扩展能解决的,但许多自动扩展算法也是在规避风险。这些算法优化的是可用性,而不是降低资源使用率,热衷于向上扩展保证没有请求会被拒绝,不愿向下扩展因为没人希望自己编写的自动扩展算法会导致服务不可用。
绿色计算模型
我们可以将这些因素放到一个模型中。目前有几种不同的绿色模型,其中就有绿色软件工程原则。“绿色软件基金会”的模型很好,这个模型很好,也是我能构想出来的,所以这个对我很有用。我能把这个模型映射到绿色软件基金会或绿色原则中。我偏向于用四个单词描述绿色计算,弹性、利用率、效率和实用性。
我们先说弹性和利用率。利用率是指系统中有多少被使用,理想情况下是系统大部分都能被使用,表明了你很好地利用了系统,很好地利用了隐含碳,没有一台僵尸服务器也没有一台未充分利用的服务器。顺风顺水就是高利用率。但如果负载增加呢?你会发现自己的系统过度利用,是人人都想避免的最糟情况。因为我们对过度利用唯恐避之不及,但又没又足够的能力满足进入系统的请求,结果反而适得其反出现利用不足的情况。虽然也能给用户带来良好的体验,但服务器却几乎不做任何事情,非常浪费。要如何解决这个问题?要如何实现持续的高利用率?这就是弹性的作用所在。弹性是衡量系统向上或向下扩展的难易程度,在高利用率且负载上升的情况下,我们希望系统也能向上扩展,这样才能保持良好的利用率,而不是被需求压垮。此外,如果负载下降,我们也不能光看着,而是要向下扩展系统,从而保持良好的利用率。
效率怎么说?效率很重要,在开始关注工具类后,我想原因大概会很明显。我很喜欢一位管理顾问,Peter Drucker 的一句话,“没有什么比高效率地干不该干的事更没用了” ,他考虑的不是僵尸服务器,而是流程。效率非常好,思考 Quarkus 的效率是我工作的一部分。我认为,在提高流程和系统效率之前,我们应该先扪心自问,我们是否真的应该这么做?
一般来说,计算机中的实用性问题是指做了很多不一定有价值的事,比如运行 CI 任务但又完全不关心结果。或者说,如果你想听一首歌,最方便方式是去油管上找到这个视频,播放视频但又不看,只是后台播放或者去做别的事情,视频虽然加载了但却没有被使用。你大概能看到其中差别,这是我们没有谈到问题,我们关注的是僵尸服务器,不是不接受流量但也不一定能让人开心,而是压根没有流量指向它们。
要怎么解决僵尸问题?
在说到僵尸和解决问题时,想着让僵尸更有效率是不对的。我们不想让僵尸少用一点电,因为这些僵尸都是优化到极致的,我们应该想办法摆脱僵尸。那我们要怎么做?要怎么解决问题而不是对僵尸的效率稍加改善?解决僵尸问题的方法有两部分:发现和消灭。听起来很有趣,就好像是在《行尸走肉》的世界里找到了燃烧瓶。但正如你所料的,这一切并没有听起来的那么有趣,我们手里没有燃烧瓶。这往往是一个系统考古的过程,对系统进行筛选、层层挖掘,试图理清哪些是有价值的,哪些是没价值的。
有一种类似捷径的方法是所谓的“尖叫测试”,这种技术是用于测试你不了解用途的服务器。拔掉电源或关掉开关,看看哪个会叫出声。如果没动静,那就说明你做出了一个正确的决定。这种方法虽然有效率但也很危险。在做尖叫测试的时候,尖叫声是真实的,我们都害怕犯错。我前些天听一家战略外包公司的 CIO(首席信息官)和我讲过一件事,他们公司想找到闲置的内部应用程序,最终他们找到了一台内部的服务器,但却想不明白这台服务器是干什么用的,他们不希望出现僵尸也没理由让这台服务器继续运行,于是决定给它断电。不幸的是,他们随后听到了一声响亮的尖叫,虽然服务器是内部区域, 但尖叫却是来自公司外部,一位客户的网络主干突然消失了。原来,出于某些原因,客户网络的主干被托管在了这台被标为内部的服务器上,真是尴尬。但这样也有好处,这种做法有些类似“混沌猴”,一种通过关掉东西测试系统弹性的手段,不过相比混沌猴,这倒更像是“生态猴”,关掉那些应该是没用的实例并希望系统能够保持正常运行。
如果你不想做事这么刺激,还是有其他方法的,比如开会。我先前有一个英国银行的客户,他们的 CIO 试图理清并控制自己的云资产和云成本。他在一次会议上召集了所有的利益相关者,说要一起逐条检查资产,理清楚到底在付钱给什么东西。我不太推荐这个方法,那场会议大概是我这辈子参加的最无聊的会议,在场每个人都有同感。不想开会时我们常常会寻求另一种替代品,邮件,“请关掉你的云实例”,“有人知道这个是什么吗?”“我们用了很多云产品,能关掉它们吗?”同样,这种技术也不是很有效。我见过另一种更为有效的方式是打标记。实例的标记依赖于很多方面,它需要人们能记住标记的内容,需要有人手动查找带有标记的内容,理解标记的含义,知道哪些可以删除、哪些不能删除。最后是管理,虽然有标记协助,但仍然需要人工的操作。
我们不希望手动的操作,想要一切都能自动化。根绝 DevOps,任何问题都会有相应的解决方案(Ops),比如 DesignOps、DevOps 等等。僵尸问题很棘手,所以我们有很多的操作方案,具体来说是五个方案。第一个方案是 GreenOps,这是个比较新的方案,谷歌还不怎么搜索得到,排名第一的条目是一家看起来不是这个领域的公司,第二条维基百科页面,点进去之前你大概会觉得自己找对了方向,可惜 GreenOps 是一种中型三叶虫。
通常情况下,在考虑 GreenOps 理念的时候,我们最好还是从 FinOps 说起。FinOps 试图实现的是金融信息实时自动化,我更倾向于把它看作是成功找出公司里是谁忘了关掉云服务。在我们掌握了这些信息时,我们就有了猎捕僵尸的工具。现在有很多 FinOps 的工具,这是一个不断发展的领域,其中我很喜欢的是 Backstage。Backstage 有很多插件,成本洞察是这个领域中非常不错的一个插件,它将成本问题推向工程层面,而作为工程师,我们也可以利用这些信息做出明智的优化。在 Backstage 中还有一个云碳足迹的插件同样也能提供一些信息,其中很多是关于僵尸,但也有一些可以协助寻找合适电力来源的。
另一个非常有用的是 AIOps。前面我提到过标记不是个很好的方式,因为需要手动进行标记,还需要有人手动进行查看,我们需要实现这些流程的自动化。这方面的工具很多,有 Densify、Granulate、Turbonomic、TSO Logic。这里面我知道的有 Turbonomic,因为 IBM 几年前收购了 Turbonomic。最近我为 IBM 的 CTO 和 CIO 交流,他说他们最近在企业内安装了 Turbonomic,你可能会问,IBM 收购 Turbonomic 已经是几年前的事情了,为什么现在才安装?原因大概也猜得到,要做的事情总比能做的多。他对安装的结果赞叹不已,因为他们可以说是仅仅安装了 Turbonomic,没有做任何的优化,但成本、占地面积等等都降低了 21%,相当于是不花钱就消减了臃肿部分。
此外,你也可以看看流量的监控,但尽量不要手动做这件事。通过查看哪些地方没有流量进出,就能清楚地知道哪些地方存在僵尸,然后我们就可以使用工具进行管理,消灭僵尸问题。
了解只是成功的一半
即使是有了这些工具,我认为识别出僵尸也只是成功的一半。“宜家效应”是指手动搭建家具的人会更喜欢宜家的家具而不是店里购买的成品家具,因为他们会意识到劳动所带来的热爱。在我们为某样事情劳作时,你对对它产生感情,服务器也是如此。就和我前面提到的 Mac stadium 一样,我在它的配置上花了不少功夫,所以我很不愿意关停它,再加上我只用过它一次,自动化也不是很值得。这种情况随处可见,人们不愿意关闭集群,以防万一日后需要,以防万一工作需要。
我是在开始研究 Quarkus 时开始考虑这个问题的,因为 Quarkus 可以作为本地编译的二进制文件运行,也可以在 JVM 上运行。它作为本地编译的二进制,运行速度快得离谱,我用灯泡做基准测试,它甚至比现代 LED 灯泡还快。启动时间加速的确有帮助,但光是这点还称不上弹性。灯泡开关可以说得上是极致的弹性,关掉、打开,我们从来不会因为担心自己一会还要用而不愿意关灯。如果一会还有需要,那就直接打开开关,灯就会亮。我们也不会担心如果现在把灯关了一会还能不能再打开。但对服务器来说,这种情况时常发生,我们不会关掉服务器,因为之后服务器有可能没法重新启动。其实,我们的目标应该是实现电灯开关的形式,系统的设计要让关机和重启的速度都很快。原生系统解决了这个问题,前提是它真的能有用。系统重启前后的表现必须一致,这是幂等性;系统也必须能够启动,这是弹性。
我开始思考一种我称之为“LightSwitchOps”的方案。LightSwitchOps 的发展方向是类似电灯开关的体验,但对象是服务器,无论是手动操作还是自动化,我们都可以毫无后顾之忧地因为一些小事开关机器,比如离开房间随手断电之类。这些脚本可能非常简单但也非常有效。我听 Jeff Smith 讲过一个故事,他以前和多数人一样,让应用程序全天候运行,但一个在晚上关闭程序的脚本就可以让云计算的账单减少 30%,真是惊人。我还听一位在学校从事 IT 工作的人说,一个她编写的可以在晚上关闭电脑的脚本,为学校节省了 1.2 万欧元。这些都是相对简单的小事却能节省巨额的开支。
当然,在开关电脑之前,你还得有自信能重新创建系统。这就是 GitOps 的用武之地。我所说的 GitOps 不一定是指某个具体的产品,我知道 WeWork 之类已经在研究这方面的问题了。我所说的其实就是基础设施即代码,基础设施即代码让我们可以拥有一次性的服务器,随时将服务器开机关机,然后再开机关机,无论多少次都可以,这种可以是 kubectl 应用程序,也可以是 ansible-playbook,这些技术都能让你毫无后顾之忧地重新创建系统。除了晚间关闭系统或集群外,这种方式还有很多好处。大家可能觉得晚上关掉几个 pod 没什么问题,但关掉整个集群就会有点紧张,但减少系统赘余是积少成多的事。
我们日常的工作负载常常需要再多个区域运行,或者出于故障时切换的需求而认为自己需要,这种冗余非常昂贵。我之所以考虑这个问题,是因为我在和一位客户交流时,他说他的应用程序不需要全天候可用,但也不希望有尴尬的中断事件发生,于是他把系统分成了两个区域。我当时就在想,这可真贵啊。但因为基础设施即代码的系统架构,这种分区方式其实没必要。故障发生时我们可以很快地在新区域启动一个新集群。当然在这么做之前你得先运行测试,测试之后你就会知道故障的恢复速度,从而真正减少冗余,减少僵尸。一个有趣的现象是,很多技术都越发地先进,我们有 GitOps、基础设施即代码、AIOps 等等,消灭僵尸有时可能真的很简单。
我听说的另一个故事是发生在 2013 年,是云计算刚刚兴起的时候。当时一家银行有一套供应系统,他们发现在自己的供应系统上还实施了一套租赁系统。默认情况下,配置完成的程序会存活两周,两周之后就会关停,当然关停之前它会给你发邮件什么的,让你有机会续租。对于使用时间较短的服务器来说,只要有这种默认设置,他们的 CPU 使用率就会有 50%的降低,这种减幅非常大。我觉得我们应该更多地采用这类系统,有了时间限制和最后期限,我们就能集中精神,也能防止遗忘,这些都很有帮助。
帮不上忙的部分
我想在这里提一下那些或许帮不上忙的东西。或许其中也有有用的部分,或许也还有尚未决断的部分。云计算让我们更倾向于一次性的基础设施,某种意义上来说,这是好事,让我们远离雪花。相比物理服务器云计算有一个问题,那就是“眼不见心不烦”。一般来说,就和其他自动扩展算法和弹性算法一样,云计算让更多硬件的配置变得非常容易,但却不一定能在摆脱硬件上帮上忙。
说回技术层,另一个不一定有帮助的是虚拟化。乍一看,虚拟化似乎是有帮助的,因为我们给服务器的多租户增加了密度,共享昂贵的物理资源。2019 年的那份研究中发现虚拟服务器和物理服务器结果相似,他们在 2019 年回顾了 2017 年的数据,并以不同形式对统计数据进行切分。当时那份数据中称 25%的服务器没有做任何工作, 而虚拟服务器中则有 30%的虚拟服务器没有在干实事,而这 30%中有一半的活跃时间少于 5%。把这两项加起来,就会发现虚拟服务器中只有 20%的服务器得到了真正的利用。虚拟服务器价格昂贵,许可证费用高昂,管理费用也不低,虚拟化似乎的确让这些账单很容易就堆积起来了,但即使有了虚拟化,我们也要记得把虚拟机关机。虚拟化了不代表我们就能让它们一直跑下去。虚拟服务器的问题之一就在于这些无比高昂的开销,因此也会支持更多的租户。
无服务又怎么样呢?我对无服务有些疑问,因为从现代化到无服务是一个很大的提升,因此不是人人都能实现无服务。无服务大概不适合对延迟敏感的工作负载。无服务还一个历史问题,无服务工作负载为解决冷启动问题,供应商在幕后做的是不计费地保持实例运行。无服务的另一个问题在于系统开销可能会非常高,你的架构中会存在控制面板或类似的东西,如果运行的工作负载较低,控制面板所占的比重可能会更大,我们需要注意到这一点。无服务方面有一些相当有趣的研究,如果你感兴趣的话可以读一读,这不是一件非黑即白的事。这篇论文发现,虚拟化的开销意味着,每个功能请求的能耗开销相较普通 HTTP 服务器请求要高出 30 倍,Docker 的能耗是普通 HTTP 服务器的 10 倍。这种权衡是与支持更高密度和更出色扩展能力相悖的。关于无服务另一件需要考虑的是系统的弹性问题,如果实例数量缩减,但却还在固定大小的无服务容器中运行,那么我们或许并没有达到预期的效果。
有些东西是必然无济于事的,其中之一也是最反直觉的,就是预防。很多组织都会试图组织僵尸服务器的出现,就好像是在马匹离开之前就关上了马厩门,听起来不错,但问题出在了预防的方式上。通常情况下,预防工作是重头戏,表格要填六份,实例申请的批准要经过五层领导,这样我们又回到了宜家效应。如果服务器的获取不易,人们自然不愿意放弃,我们需要确保一个丝滑的获取过程,这样才能带来丝滑的取消过程。
互联网的背景噪音
在我们今天谈到的内容中,重点一直在僵尸服务器上。当然,僵尸的不仅只有服务器,或者说机器中的鬼魂、废弃物、幻影,这些都不仅仅是指服务器,数据也是一样。世界上有庞大数量的无用或未使用数据,挑战在于要如何找到它们。世界上同样也有庞大数量的无用或未使用网络流量,我指的并不是视频浏览这类,而是那些永远到达不了目的地的、在互联网上飘荡的僵尸数据包,它们和服务器一样,不过是以小小数据包的形式出现。这些一同构成了“互联网背景噪音”,这个令人叹服的现象。
我能找到的最好的数据是来源于 2010,流量从那时到现在已经有了很大的增长。每秒都有 5.5 千兆比特的流量在互联网上传输,这些流量虽然指向 IP 地址或端口,但却没有网络设备来接收,因此这些流量永远无法到达目的地。以上这些都会带来问题,但这也是好事,这些尚未解决的问题和技术挑战对我们来说都可能是很好的机遇。关闭设备不仅是对生态负责,还能节省大量资金,是经济效益和气候效益的双赢。
总结
如果你是用户,请试图提高系统的利用率,追求弹性、尽量限制 Kubernetes 等类型的蔓延,理清自己在使用什么东西,并通过关闭机器来摆脱僵尸。用户要想做到这些,还需要工具编写者的帮助。如果你在编写工具,请试着支持更好的利用率,建立多租户机制和弹性,然后再通过基础架构即代码的方式建立可处置性,在真正有帮助的部分建立可见性。有了这些,再加上 GreenOps、FinOps、AIOps、GitOps、LightSwitchOps 这些解决方案 ,我们就有能力带来真正巨大的变化。
查看英文原文:
Why Cloud Zombies Are Destroying the Planet and How You Can Stop Them
评论