可扩展的Web架构和分布式系统设计(四)

负载均衡器

最后,任何分布式系统的另一个关键部分是负载均衡器。负载平衡器是任何体系结构的主要部分,因为它们的作用是在负责服务请求的一组节点之间分配负载。这允许多个节点透明地为系统中的相同功能提供服务。 (参见图1.18。)它们的主要目的是处理大量的并发连接并将这些连接路由到其中一个请求节点,从而允许系统通过添加节点来扩展以服务更多请求。

                       图1.18:负载平衡器

有许多不同的算法可用于服务请求,包括选择随机节点,循环,甚至根据某些标准选择节点,例如内存或CPU利用率。负载平衡器可以实现为软件或硬件设备。一个广泛采用的开源软件负载均衡器是HAProxy)。

在分布式系统中,通常在系统的最前端找到负载平衡器,以便相应地路由所有传入请求。在复杂的分布式系统中,将请求路由到多个负载均衡器的情况并不少见,如图1.19所示。

与代理一样,某些负载均衡器也可以根据请求的类型不同地路由请求。 (从技术上讲,这些也称为反向代理。)

负载平衡器面临的挑战之一是管理特定于用户会话的数据。在电子商务网站中,当您只有一个客户端时,很容易让用户将东西放在购物车中并在访问之间保留这些内容(这很重要,因为如果您出售产品,则更有可能它们返回时仍然在用户的购物车中)。但是,如果用户被路由到一个节点进行会话,然后在下一次访问时被路由到另一个节点,则可能存在不一致,因为新节点可能缺少该用户的购物车内容。 (如果您在购物车中放入6包Mountain Dew然后回来并且它是空的,你不会感到不安吗?)解决这个问题的一种方法是使会话变得粘稠,以便用户始终路由到同一个节点但是,很难利用自动故障转移等可靠性功能。在这种情况下,用户的购物车将始终具有内容,但是如果他们的粘性节点变得不可用,则需要特殊情况并且内容的假设将不再有效(尽管希望这个假设不会被内置到应用程序中)。当然,这个问题可以通过本章中的其他策略和工具来解决,比如服务,还有许多未涵盖的(如浏览器缓存,cookie和URL重写)。

如果系统只有几个节点,那么像循环DNS这样的系统可能会更有意义,因为负载均衡器可能很昂贵并且增加了不必要的复杂层。当然,在较大的系统中,存在各种不同的调度和负载平衡算法,包括诸如随机选择或循环的简单算法,以及考虑利用率和容量之类的更复杂的机制。所有这些算法都允许分发流量和请求,并且可以提供有用的可靠性工具,如自动故障转移或自动删除坏节点(例如,当它变得无响应时)。但是,这些高级功能可能会使问题诊断变得繁琐。例如,当涉及高负载情况时,负载平衡器将删除可能很慢或超时的节点(因为请求太多),但这只会加剧其他节点的情况。在这些情况下,广泛的监控很重要,因为整体系统流量和吞吐量可能看起来正在下降(因为节点服务的请求较少),但各个节点正在变得最大化。

负载平衡器是一种允许扩展系统容量的简单方法,与本文中的其他技术一样,它在分布式系统架构中发挥着重要作用。负载平衡器还提供了能够测试节点运行状况的关键功能,这样,如果节点没有响应或过载,可以从池处理请求中删除它,利用您的不同节点的冗余。系统。

队列

到目前为止,我们已经介绍了很多快速读取数据的方法,但扩展数据层的另一个重要部分是有效的写入管理。当系统简单,处理负载最小且数据库较小时,写入速度可以预测很快;但是,在更复杂的系统中,写入可能需要几乎不确定的长时间。例如,可能必须将数据写入不同服务器或索引上的多个位置,否则系统可能处于高负载状态。在写入或任何相关任务可能需要很长时间的情况下,实现性能和可用性需要在系统中建立异步;一种常见的方法是使用队列。

                              图1.20:同步请求

想象一个系统,每个客户端都在请求远程服务任务。每个客户端都将其请求发送到服务器,服务器尽快完成任务并将结果返回给各自的客户端。在小型系统中,一台服务器(或逻辑服务)可以像它们一样快地为传入的客户端提供服务,这种情况应该可以正常工作。但是,当服务器收到的请求数超出其处理能力时,则会强制每个客户端等待其他客户端的请求完成,然后才能生成响应。这是同步请求的一个示例,如图1.20所示。

这种同步行为会严重降低客户端性能;客户端被迫等待,有效地执行零工作,直到其请求得到解答。添加额外的服务器以解决系统负载也无法解决问题;即使有效的负载平衡到位,也很难确保最大化客户性能所需的工作均匀公平分配。此外,如果服务器处理请求不可用或失败,则上游客户端也将失败。有效地解决这个问题需要在客户端的请求和为服务它而执行的实际工作之间进行抽象。

                             图1.21:使用队列管理请求

输入队列。队列就像听起来一样简单:任务进来,被添加到队列中,然后工作人员接受下一个任务,因为他们有能力处理它。 (参见图1.21。)这些任务可以表示对数据库的简单写入,也可以表示为生成文档的缩略图预览图像这样复杂的任务。当客户端向队列提交任务请求时,他们不再被迫等待结果;相反,他们只需要确认请求已正确接收。此确认可以在以后作为客户需要时工作结果的参考。

队列使客户端能够以异步方式工作,提供客户端请求及其响应的战略抽象。另一方面,在同步系统中,请求和回复之间没有区别,因此它们不能单独管理。在异步系统中,客户端请求任务,服务以确认收到任务的消息进行响应,然后客户端可以定期检查任务的状态,仅在结果完成后请求结果。当客户端等待异步请求完成时,它可以自由地执行其他工作,甚至可以对其他服务进行异步请求。后者是如何在分布式系统中利用队列和消息的示例。

队列还提供一些服务中断和故障保护。例如,创建一个高度健壮的队列非常容易,该队列可以重试因瞬态服务器故障而失败的服务请求。最好使用队列来强制执行服务质量保证,而不是直接将客户端暴露给间歇性服务中断,这需要复杂且经常不一致的客户端错误处理。

队列是管理任何大型分布式系统的不同部分之间的分布式通信的基础,并且有许多方法来实现它们。有很多开源队列,如RabbitMQ,ActiveMQ,BeanstalkD,但有些也使用像Zookeeper这样的服务,甚至像Redis这样的数据存储。

1.4 结论

设计具有快速访问大量数据的高效系统是令人兴奋的,并且有许多很棒的工具可以支持各种新应用程序。本章仅介绍几个例子,几乎没有表面,但还有更多 - 并且只会继续在这个领域进行更多的创新。

 

原文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值