代码之家  ›  专栏  ›  技术社区  ›  SAL9000

切分(sic!)Web层以防止负载平衡器瓶颈?

  •  7
  • SAL9000  · 技术社区  · 17 年前

    不能完全无状态的大型网站如何在Web层实现极端的可伸缩性?

    有些网站像易趣和亚马逊,不能完全无状态,因为他们有购物车或类似的东西。将购物车中的每个项目编码为URL是不可行的,也不可能将每个项目编码为cookie并在每个连接处发送。所以亚马逊只是将会话ID存储到正在发送的cookie中。因此,我理解易趣和亚马逊的网络层的可伸缩性应该比谷歌搜索引擎的可伸缩性要困难得多,在谷歌搜索引擎中,一切都可以被编码成RESTful到URL中。

    另一方面,eBay和亚马逊的规模都非常庞大。有传言说易趣有大约15000台J2EE应用服务器。

    这些站点如何处理这两者:极端的可伸缩性和状态性?由于站点是有状态的,所以不可能进行简单的DNS平衡。所以可以假设这些公司有一个基于硬件的负载均衡器,比如bigip、netscaler或者类似的东西,它是该站点的单个IP地址背后的唯一设备。此负载均衡器将解密SSL(如果已编码),检查cookie并根据cookie的会话ID决定哪个应用程序服务器保存该客户的会话。

    但是这不可能工作,因为没有一个负载均衡器可以处理数千个应用服务器的负载?我可以想象,即使这些硬件负载均衡器也不能扩展到这样的水平。

    此外,负载平衡对于用户来说是透明的,即用户不会被转发到不同的地址,但仍然会一直集中在www.amazon.com上。

    所以,我的问题是:有没有一些特殊的技巧可以实现像透明的Web层(而不是通常所做的数据库层)切分这样的功能?只要不检查cookie,就无法知道哪个应用服务器正在保存此会话。

    编辑: 我意识到,只要有必要对网站进行蜘蛛网和书签,就只需要透明度。例如,如果网站仅仅是一个Web应用程序,比如飞机或火车票预订系统,那么将用户重定向到不同URL后面的特定Web服务器集群应该没有问题,例如a17.ticket reservation.com。在这种特定的情况下,只使用多个应用服务器集群是可行的,每个集群都在自己的负载平衡器后面。 有趣的是,我没有找到一个使用这种概念的网站。 编辑: 我发现了这个概念 discussed 在 highscalability.com ,其中讨论引用了雷竹的一篇文章 "Client Side Load Balancing for Web 2.0 Applications" . LeiZhu使用交叉脚本透明地进行客户端负载平衡。

    即使存在诸如书签、XSS等缺点,我也认为对于某些特殊情况(即几乎无内容的Web应用程序)来说,这听起来是一个非常好的主意,这些应用程序不需要进行蜘蛛网或书签(例如,订票系统或类似系统)。那么就不需要透明地进行负载平衡。

    可以简单地从主站点重定向到服务器,例如从www.ticketreservation.com重定向到a17.ticketreservation.com。从那里用户留在服务器A17。A17不是服务器,而是集群本身,通过它可以实现冗余。

    初始重定向服务器本身可以是负载平衡器后面的集群。这样,就可以实现真正高的可伸缩性,因为WWW后面的主负载均衡器在每个会话开始时只被命中一次。

    当然,重定向到不同的URL看起来非常糟糕,但是仅仅是Web应用程序(不需要蜘蛛网、深度链接或深度书签),这应该只是用户的一个光学问题吗?

    重定向集群可以轮询应用集群的负载并相应地调整重定向,从而实现平衡,而不仅仅是负载分布。

    4 回复  |  直到 9 年前
        1
  •  1
  •   Mark Brackett    17 年前

    容易的。Web服务器是无状态的,是负载平衡的。保存会话数据的应用程序服务器(中间层)不是。Web服务器可以使用会话ID cookie来确定要联系的应用服务器。

    Memcached和Microsoft的Velocity是解决这一确切需求的产品。

    编辑:Web服务器如何知道要联系哪个应用服务器?这是嵌入到会话ID散列中的,通常可以根据需要进行。它可以像会话ID是server:guid一样简单。 Memcached 不过,它基于散列值。

    重要的一点是,客户机必须能够以无状态的方式找出要联系的应用服务器。最简单的方法是将它嵌入到键中,尽管注册表(可能在它自己的层上)也可以工作并且可以提供一些容错性。

    edit2:返回 some 易趣网 interviews 我可能对它们的实现细节有点理解错误。他们不做缓存,也不在中间层做状态。他们所做的就是按功能划分负载平衡的中间层(应用服务器)。因此,它们将拥有一个服务器池,例如用于查看项目。然后是另一个卖东西的池子。

    这些应用服务器有一个“智能”DAL,可以路由到分片数据库(按功能和数据划分,因此数据库1上的用户A-L、数据库2上的用户M-Z、项目1上的项目1-10000等)。

    它们在中间层没有状态,因为它们是按函数划分的。因此,一个正常的用户体验将涉及一个以上的应用服务器池。假设您查看了一个项目(viewAppServerPool),然后对一个项目(bidappServerPool)进行竞价。所有这些应用服务器都必须保持同步,然后需要一个分布式缓存来管理所有内容。但是,它们的规模如此之大,以至于没有一个分布式缓存能够有效地管理它,也没有一个数据库服务器。这意味着他们必须共享数据层,并且任何缓存实现都必须跨相同的边界分割。

    这是 类似的 我在上面贴的,只是向下移动了一层。应用服务器不是让Web服务器确定要联系哪个应用服务器,而是确定要联系哪个数据库。只有在eBay的情况下,由于他们的分区策略,它可能实际上会攻击20多个数据库服务器。但是,同样,无状态层有一些规则,它使用这些规则来联系有状态层。不过,eBay的规则比我上面解释的简单的“user1 i s on server10”规则要复杂一些。

        2
  •  2
  •   Panos    17 年前

    您可能会发现下面这篇文章很有用,它介绍了一些Amazon_的核心服务用来提供__Always on_157;体验的高可用性密钥值存储系统的设计和实现:

    朱塞佩·迪卡迪亚、丹尼斯·黑索伦、马丹·贾姆帕尼、冈纳瓦德汉·卡库拉帕蒂、阿维纳斯·拉克什曼、亚历克斯·皮尔钦、斯瓦米·西瓦苏布拉曼尼、彼得·沃索尔和维尔纳·沃格斯 ,阿哥 Dynamo: Amazon's Highly Available Key-Value Store _157;,第21届ACM操作系统原理研讨会论文集,华盛顿州史蒂文森,2007年10月。

        3
  •  2
  •   carson    17 年前

    您可能需要在其中一个地方的工程团队中才能确定,但是有一些人从交谈和其他信息中做出了有根据的猜测,这些信息来自于这两个地方:

    Ebay Architecture 和 Amazon Architecture

    在当今世界,仅仅一个负载均衡器本身就相当于过去几年的DNS循环。今天你有 anycast 让你玩各种各样的把戏。你可以很确定,像易趣和亚马逊这样的公司确实使用负载均衡器,而且它们使用的很多。

    当您考虑到它可能如何工作时,您可能希望将其简化一点,因为很多流量是无状态的。在页面的单个请求中,可能有许多对象不需要了解状态。通过从无状态系统(这是anycast的切入点)为这些对象提供服务,可以将它们从图片中去掉,并且请求的数量会显著减少。

    如果这不能使您达到单个负载均衡器可以处理负载的程度,那么下一步就是使用IP路由和/或geo dns中断事务。像eBay和Amazon这样大的网站将位于许多不同的数据中心,每个数据中心都有大量的互联网连接。你从Internet Pop Quest West获取所有信息并将其发送到西海岸数据中心的“Quest”服务器,从Att West获取的信息发送到西海岸数据中心的“Att”服务器,从Quest East获取的信息发送到东海岸数据中心的“Quest”服务器,等等。这些系统中的每一个都可以是一个孤岛,一个负载均衡器,一个负载均衡器。T可以处理负载,一些负载均衡器可以每秒处理数十万个事务,甚至是经过SSL加密的事务。在背面,您不断地向每个数据中心批量复制数据,但数据中心可能不同步。

        4
  •  2
  •   MarkR    17 年前

    我不知道他们是怎么做的,但这里有一些建议:

    • 为了避免负载均衡器主机本身过载,请使用循环DNS或
    • 根据负载、设置、地理位置等将不同的客户端重定向到不同的群集地址

    为了分配中间层负载,

    • 按照其他人的建议,将中间层会话服务器的ID嵌入会话ID cookie中。这样一来,你击中的前端盒就不相关了,它们就可以在不受任何影响的情况下被添加/删除。
    • 如果它足够重要,那么就有一种机制,在会话期间将客户机重定向到另一个中间层服务器,这样就可以将一台服务器取下来进行维护等。
    • 客户端在启动新会话时开始使用新调试的中间层服务器

    分发后端数据库加载

    • 每个账户或每个用户数据“实时”的“常规”切分
    • 异步复制变化缓慢或相对静态的数据;用户可能会发现它已过时(但大多数时间不会如此)。中间层和Web服务器连接到本地数据库,并连接到自己的位置