负载增长时悄然袭来的42个怪兽问题

发表于:2013-05-15来源:InfoQ作者:Todd Hoff点击数: 标签:负载
负载增长时悄然袭来的42个怪兽问题! 随着负载的增长,你精心设计的程序可能会遭遇很多突如其来的问题:系统原有的平稳将被打破,我们将对这些问题逐一考察。当然,你可以进行横向或纵向的扩展,也可以选择编写出更好的程序,让你的系统可以处理更高的负载。这样做可以

  随着负载的增长,你精心设计的程序可能会遭遇很多突如其来的问题:系统原有的平稳将被打破,我们将对这些问题逐一考察。当然,你可以进行横向或纵向的扩展,也可以选择编写出更好的程序,让你的系统可以处理更高的负载。这样做可以节省更多的硬件开支,并让你的整个应用更加可靠,具有更快的响应时间。对于程序员来说,这必将获得非常大的满足感。

  大量的对象

  当系统中的对象数量增长到一定程度,我们通常将面临规模问题。随着对象数目的增长,所有类型的资源开销显然会带来很大的压力。

  持续的故障会产生一个无穷事件流

  在大型网络的故障场景中,我们没有时间进行系统恢复。因为我们始终处于一个持续的压力状态下。

  大量的高优先级任务

  举个例子,重选路由(rerouting)是个高优先级的活动。如果存在大量不能分发(shed)或取消(squelched)的重选路由任务,资源将连续不断的被消耗以支持高优先级任务。

  更大的数据流

  当媒体资源大小增长得更大时,系统的负载将会增长。系统负载会随着请求来源数目的增长而增长。

  功能变更

  在系统原有设计之外添加更多的功能后,系统中的漏洞也随之暴露。

  客户端的增长

  更多的客户端意味着更多的资源消耗。需要设置线程为客户端推送事件;客户端队列会消耗内存;通信会消耗带宽;需要为每个客户端维持一份独立数据。

  不够好的设计决策

  以下是一些会加剧规模问题的设计问题。

  设计未考虑处理大量对象。

  缺乏端到端应用级别的流控。

  应用级别的重试将导致资源再分配和消息发送。

  内存中代码库的开销。

  并不真正可靠的发布。

  特定数据结构过度占用内存。

  消息协议没有处理所有故障场景。

  使用磁盘作为存储。

  磁盘同步没有使用块复制。

  认为应用层协议会更有好。

  依靠大功耗的CPU来提升功能负载。

  操作系统不支持进程架构。(译者注:该点讨论见原文链接处的评论)

  缺乏对于某些敏感操作(甚至是单条消息的删除)的硬件支持。

  特别的网络问题,比如ARP数据包,当网络负载增长时就会出现丢失。

  无效的假设

  你所做的大部分假设都是无效的,比如你需要使用多少内存,某些任务需要运行多少时间,设置多少超时时间才算合理,一次会消费多少资源,可能发生什么样的故障,系统在不同点的延迟,你的队列需要多大,等等。

  内存不足

  内存使用基线的增长和内存使用峰值的增长,都会导致内存不足。

  CPU饥饿

  随着对象操作的增加,将需要占用更长的时间,这是因为这些操作需要操作更多的对象。可用CPU将变得更少从而导致其他的操作将面临CPU饥饿。系统一处出现了饥饿,就会传播到其他各处。这样一来就没有足够的CPU来处理那些需要去完成的必要任务。导致这样的原因可能是任务的基数过高或某些情况下很多高优先级的任务需要完成。

  原始资源使用率增长

  更多的对象将占用更多的内存。如果某人想要支持1000个并发对象,很可能是做不到的,因为你可能根本就没有足够的内存。

  隐式资源使用率增长

  大多数功能中,针对“原始”资源使用开销中的每项资源,都将会需要大量的额外资源。如果你将一个对象存储在两个不同的列表里,你的对象数目和内存开销将是原来的两倍;队列大小可能也需要向上调整;磁盘的数目需要增加;将数据复制到从机的时间在增长;将数据加载到应用中的时间在增长;为了处理这些工作CPU的使用率在增长;启动时间也在增长。

  事件的叠加

  很多系统面临的一个新的现实是无穷工作流。Web服务器和应用服务器服务着非常大的用户群,这是一个真实的可预计的关于新工作的无穷流。而工作将永不结束。一周7天24小时都会有请求进来。以100%的CPU使用率进行工作可以很容易使服务器达到饱和。

  习惯上我们将100%的CPU使用率视为一个不良的信号。作为补偿,我们将创建复杂的基础设施来对工作进行负载均衡,复制状态并做好主机集群。

  CPU永不疲倦,所以你可能会认为我们应该尝试使用尽可能多的CPU。

  在其他领域我们试图通过最大限度的利用资源来提升生产率。

  而在服务器的世界里,我们尝试通过人为的方式强制地降低CPU使用率从而保证一定的响应水平。该理由是因为如果我们没有更高的CPU可用性,我们将无法在合理的延迟时间内响应新的工作或完成现有的工作。

  CPU使用率达到100%真的存在问题吗?我们在对系统做架构设计时,宁可使用CPU可用性和任务优先级作为架构设计认知上简略的一种解释依据,也不愿意先去理解下我们系统的底层工作流,从而使用这些信息再来做出明确的规划决策。难道这不正是真正的问题所在吗?

  我们基于负载均衡服务器做出了拙劣的架构决策,通过主观臆想猜测了使用的线程数以及这些线程的优先级。除了以上这些,我们根本没有使用工具做过任何其他事。

  扩展一个系统需要仔细地关注架构。在当前框架的应用程序中,却很少有对所辖应用是如何运行的进行说明。

  延迟的增长

  你所经历的延迟增长与规模增长可能是完全不同的。CPU饥饿是该问题的主要原因。

  任务优先级被证明是错误的

  任务优先级方案可以有效地工作在较小负载下,但是在高负载下就会产生问题。举个典型的例子,有一套简陋的流控装置,一个高优先级任务向一个较低优先级的任务传递工作将会导致工作丢失和内存使用峰值,因为低优先级的任务的运行机会将会很少。

  队列容量不足够大

  大量的对象意味着可以进行更多的并发操作,这意味着队列容量将很可能需要扩充。

  启动时间更久

  更多的对象需要更久的时间才能将它们从磁盘加载到应用中。

原文转自:http://www.infoq.com/cn/articles/42-monster-problems