云计算 频道

【技术解读】开发者的云容量规划指导手册

  【IT168 资讯】如果你们是一家拥有宏大梦想的小公司,相比于传统的系统供应商,云基础设施供应商对于你们最大的优势就是,他们可以帮助你灵活调整应用程序所用的源。你们再也不用为了一些需要花费六个星期才能安装完成的服务器,而与托管服务供应商商谈机架空间的事宜。现在,这整个冗杂的过程通过API调用可以得到简化,同时,服务器可以在几秒种内即可准备完毕。

  旧模型的主要供应策略很简单:供应过量,并且过量许多。扩充容量的时候,你至少要以“一个服务器”为单位来增加容量,并且由于改动部署方案的人力成本和时间成本都很高,所以需要分批进行改动。这一点使你需要花费比预期多得多的部署精力,而且要扩充部署规模,而并不仅是在已有的狭小空间内寻求最优化的方案。

  最新的云技术使得DevOps团队得以用非常先进的颗粒化方式部署了新的源,只要多花一些金钱,就可以对抗任何容量问题。这通常是一个很有效的策略,但它需要我们在云的容量规划方面做得更好。

【技术解读】开发者的云容量规划指导手册

  桌上赌注

  相比于一次性制定正确的容量规划,如何应对错误的容量规划则更为重要。你需要采用便于挑整应用程序的架构和开发策略。否则,你就没有很好地利用上供应的灵活度——调整应用程序的人力成本将盖过云的灵活度这一优势,你就会止步于云时代之外。更糟糕的是,你还要为了没有利用上的灵活度功能付额外费用。

  选择便于扩充容量的架构

  大多数应用程序会使用两种扩展容量的方式:水平扩展(“买更多的箱子!”)和垂直扩展(“买更大的箱子!”)。业内已经总结出了几个非常有效的架构方法,我们没有必要再去开发新的方法了。

  你可能会最终选用n层架构,数量庞大的应用程序服务器利用着非常小的数据库(或者其他后台数据存储)。这是网页应用程序部署的最常见模型,因为它可以在应用程序层利用水平扩展,在数据库利用垂直扩展。

  在不进行任何基础改动的条件下,在世界最大的生产部署原型中 ,这个架构对于何种环境和规模都可以很好的运行。如果你们公司想要发展成谷歌或者Facebook那样的公司——假如真的实现了,你们将需要上千个工程师来处理扩展问题。

  将应用程序编码与部署环境的知识分离开

  尽管这是几十年间非常好的方法,但假如你在应用程序的整个使用过程中只扩充一、两次API服务器,硬编码的API服务器并不是一个大问题。当你想要迅速扩充时,你需要应用程序(或部署/供应过程)来处理配置的变化。

  近来有许多管理方面的优秀的开源选择、例如,Consul可以很方便的探索服务——服务器会直接通知Consul有哪些服务是可用的。消费者们可以通过API寻找服务,或者当服务运行时进行DNS 搜索,此搜索可以遍及整个服务器。

  在使用服务为基础的架构或多层架构时,你会发现一个无处不在的交流层,它使得你可以任意改变服务的大小、添加新的服务,以便满足应用程序的需求。你有很多种选择——在我的经验里,NSQ的表现十分出色,而且是一个容易采用的消息总线。Kafka也有许多拥护者。普遍性和标准化是应用程序很重要的两大方面,它使得我们可以专注于处理一些棘手问题的内部加工和操作过程(而非强调制造商和顾客间复杂度为n^2的互动),并且解决了关于如何更改应用程序的争论,对于这个问题,答案过去通常是“在NSQ里面再输入一个事件”。

  “那些不与控制基础设施直接相关的应用程序或服务器,不需要察觉到服务器的加入或退出”是你应当选用的黄金准则。它们需要了解的就是如何连接到路由要求通往以及它要连接到的网络。

  这或许听起来很复杂,但最近科技的迅速进步使得一个小型开发团队就可以轻易的完成这件事。在我最新一家公司中,一个从未着手处理过类似工作的非专业的工程师,只花了大约两周的时间就开发了一个“泡泡糖胶带”版本的基础设施。其他开发团队已经为你开辟了道路,你就不用再重新经历太多困难——即使还会遇到一些困难,你距离应用程序的商业价值已经更进一步了。

  自动化供应和部署

  尽管通过点击供应商的线上界面就可以发布实例并进行SHH,来供应云的源,你还需要花费大量时间来管理服务器、处理它们之间的不一致、清理操作错误。你需要尽早投资服务器(或者其他源)的自动化供应以及应用程序的自动化部署。

  在我最新一家公司中,我们使用了Ansible来自动化服务器的配置。Chef、Puppet、Salt以及普通的shell脚本也是可供选择的。传送可理解的Ansible脚本以及自动化服务的部署并不是一件易事,但我们可以在几分钟内就抓住机会来优化架构,多花费一些工程成本也是值得的。

  除了可以简化容量优化,自动化供应和部署还可以显著简化操作过程。我们可以像对待牲畜一样对待箱,而非像对待宠物那样——修复一次性问题的关键步骤是直接杀掉并替换箱,而非尝试弄明白问题的原理到底是什么。我们的运行手册将不再区分满的硬盘、干扰的邻近设备、失败的硬件或是糟糕的部署等问题——“直接将它丢弃,没有必要花费时间来诊断问题并手动修正它。”

  有些应用程序最终会达到一定的规模,有些部署也会达到它的成熟期,此时应用程序要负责自行扩展和修复。这对于大多数读者来说可能很难懂,因为复杂度提高了许多。这时,你可能会需要开发者或操作团队使用常见自动化工具来手动调整资源。这位自动扩展提供了一条途径,因为你可能会需要在计算机做出可以面对所有特殊情况的稳健决定之前,花上几个月或几年来处理“只发生在生产当中的问题”。

  运供应商提供一些可以帮助你处理扩展的工具。它们可以帮助自动化一些应对自然增长的需求或者应用程序使用度的跨期变化的机制(服务器不需要在用户睡眠时被唤醒)。这也就是说,你可能需要在供应和操作方面足够智慧,来机动应对需求的变化,使得自动扩展要么会引发生产的问题,要么积累没必要的巨额账单。

  容量规划的费米估计

  在大多数应用程序的初期,过度重视精确度会导致高成本。你应该最初通过一个预期的工作量来进行供应,然后随需求进行调整。

  在设计阶段,最有用的的问题是“我们期望先突破什么?”例如,在之前的一个公司,我们发布了一个应用程序,其中包含了十多种服务。对它们进行严格的规模估计是很困难的,但这也并不是必要的:高度内部利用、所选用技术的运行以及明显的开发耗费,显然服务一开始就会崩溃。这意味着在固定基础上需要最多的源,还需要最多的工程操作时间。我们应该重点着手在服务的容量规划,而放弃其他这些工作。

  当你决定了要专注于哪一部分,你需要找到是什么影响着容量要求,以及哪个源是操作的限制因素。

  查找驱动器

  应用程序不需要扩展。如果删除一些要求,编码也不需要。但商业有时候需要,所以严谨的考虑商业对于特定服务的要求是很重要的。

  在我们的项目中,应用程序是一个游戏,服务由初级AI和游戏世界的世界状态来提供的。如果服务超过了容量,那么一部分玩家将无法进行游戏。可能会令人惊讶的是,对于重要商业应用程序的工程师来说,为了峰值负载而调整容量,从而放弃90%+的玩家是完全可以接受的工程权衡。(峰值负载和典型高水位线的差别在一周内超过500。)

  替代这种方案,我们按照游戏的目标使用来调整初始容量,按照这种目标使用持续下去,我们认为可以获得一个良好的公司事业,并且在事业越来越好的同时不断增加目标容量。其他公司可能需要支撑峰值负载,而不是支撑更低的基线——稳定负载。

  由于我们系统的设计要求在玩家游戏的期间持续工作,我们利用“每小时的活跃玩家”来描述峰值负载。其他大多数应用程序可能会使用“每秒的要求”来描述峰值负载。

  查找限制因素

  不同的技术栈和工作量消耗源的方式具有很大的区别。例如轨道应用程序中的Ruby通过增加进程来水平扩展,比起其他系统源,这些进程常常占用更大比例的内存。(在稳定状态下,有些轨道应用程序很快就可以达到几百兆的RAM用量。因为每个轨道过程可以服务一个请求,可以通过买内存来获得额外容量:

  内存需求=(每秒的目标请求)*(每秒的请求平均长度)*(稳定状态下的过程平均尺寸)

  所以,如果一个应用程序想要每秒对1000个请求进行服务,一个请求的平均长度约为350ms,一个进程的平均大小约为250MB,我们大约需要350个进程,这消耗大约90GB的RAM。假如有96GB的空间,我们可以供应12个箱,每个8GB,也可以供应24个箱,每个4GB。

  部署环境除了RAM以外还有许多其他的特征,包括CPU容量、硬盘接入速度和网络带宽。我们忽略这些特征,因为它们并不是大多数轨道应用最先耗尽的因素:内存最先耗尽。如果不是病态运行了系统,我们永远也不会达到箱的CPU限制。如果达到了,我们再另想对策(我们也会在生产中监管CPU利用,因为无论是错误或是错误但未察觉的假设,都代价极高。)

  这个方法模型并不适用于所有的栈和工作量,尤其是对于那些具有异源性的响应次数分布的(例如,使用一个不太可靠而你无法监管的API)。它致力于降低执行的成本,并且足够精确,使你可以放心地建立系统,而不是去支撑硬件要求。

  在不确定的情况下估算性能

  如果没有一个和非常好的规则相近的选择,你可能需要进行一些试验。以下是一些你可以尝试的手段。

  CPU每秒可以处理多少请求?10个显然太少了,计算机是很快的。1000个可能太多了,有的请求需要花费很多精力,有的内部服务很奇怪,还有的栈本身就很缓慢。100个看起来是个合适的折中。我们就假设每秒可以处理100个。

  运行微型标准检测程序

  你可以开发一个微型标准检测程序,模拟一个你的应用程序的简单请求/响应、应用程序的单个元素或者整个端到端的数据流。这些工作人们之前就已经进行过,TechEmpower对于设计标准检测程序有很好的的建议,它们也有一些关于现代栈和硬件的成果。

  在实际应用程序上进行负载测试

  你可以编写并运行脚本来模拟应用程序可能的使用情况,在开放网络、工作环境中,向结拨号,直到某一环节崩溃。这很困难。几乎没有脚本可以精确的捕捉成产工作量。尽管工程成本增加,但你也找不到一个比以上方法更精确的了。

  无论你选用哪一种方法,当你估算了理想容量以及一单位源提供多少容量之后,容量规划都是一个简单的任务。虽然距离容量问题的解决还有很大一段距离,但你已经拥有了开始的基础。

  我们什么时候调整空间?

  为了削减成本

  在基础设施和其规划上付出大量时间是很具有诱惑力的,因为你会遇到新奇困难的问题,并且还非常有趣。但是,它在应用程序的初期可能不会贡献很多商业价值。

  根据经验来看,如果你每月在基础设施上的花费少于1000美金,那么你根本不应该考虑优化空间。你更适合花上等量的工程来发展应用程序或事业的其他部分。

  当你的花费增加到每个月几万美金之后——许多应用程序大概永远也不会达到——你就有充足的理由定期重新评估非配源的方式,以及是否值得花费所需的工程时间来对源或应用程序进行修正。这与定期举办云修剪排派对一样简单。由于工作可以察觉到非常高产的小规模工作量,它非常适合活动项目,也使缓冲成为一个很良好的活动。许多工程师对于云花费很不理性,因为它具有神秘的有形性。浪费掉可以维持m3.medium的2.40美元也会很令人心痛。你要记住,比起未激活的实例,工程师在桌前遛弯的90秒更是一种浪费。

  为了增加容量

  总的来说,你想要增加超出需求的容量。超出多少,你决定沿着预期增长曲线增加多长,由你增加额外容量的进程有多可靠来决定。当扩充容量会带来损失、风险和高成本时,你常常会想要过多的扩充容量。当扩充容量的成本降低时,你就可以更频繁地进行小规模扩充。

  根据经验来看,如果扩充容量对于你来说需要一周,你很可能想要沿增长曲线购买6到12月的容量。如果仅需要一天,便可以缩短到一个月。如果仅需要几分钟,那么你可以每次只购买一周。手动进行大于每周一次的频率则没有什么必要。

  如果你足够精通DevOps,可以利用应用程序的使用周期,并且可以增加或减少复杂度,那么恭喜你!请连续运行它。达到这一步是非常非常困难的,而且即使知道很实际的基础设施开销,大部分的应用程序大概都无法评估它是否达到有限工程时间的非常好的使用程度。

  愿意承受失误

  云的内容规划并不意味着要得到绝对正确的答案,也不意味着得到差不多对的答案。你是在最优化规划过程,使它足够轻量而不会阻碍传送商业价值,使它足够准确而保障生产不会崩溃。即使只是得到一个差不多的优化方案,也会让你更智慧地分配时间和注意力,决定了公司的成功,例如合适的“产品/市场”比,以及可以吸引合适顾客的可扩展性。

0
相关文章