粘性会话/会话亲和负载均衡策略的利弊?

56

高可扩展性的一种方法是使用网络负载均衡来将处理负载分配给多个服务器。

这种方法面临的一个挑战是,当服务器具有状态感知能力时,它们会在“会话”中存储用户状态。

解决这个问题的方法之一是“粘性会话”(也称为“会话亲和力”),其中每个用户被分配到一个单独的服务器,并且他/她的状态数据仅在会话期间完全保存在该服务器上。

“粘性会话”方法的优缺点是什么?您是否使用它?如果是,您是否满意?

1个回答

82

优点:

  • 易于使用--不需要应用程序更改。
  • 更好地利用本地RAM缓存(例如,只需查找用户个人资料一次,对于来自同一用户的后续访问可以重复使用它)。

缺点:

  • 如果服务器崩溃,会丢失会话。 (请注意,这是将会话信息本地存储在Web服务器上的缺点,而不是粘性会话本身的缺点)。 如果会话中的内容对用户非常重要(例如,草稿电子邮件)或对网站很重要(例如,购物车),那么失去一个服务器可能非常痛苦。
  • 根据您负载均衡器中“粘性”实现的不同,可能会将不均等的负载分配给某些服务器而不是其他服务器。
  • 启动新服务器不能立即给新服务器带来大量负载。 如果您有动态负载平衡系统来处理峰值,则粘性可能会减慢您快速响应峰值的能力。 也就是说,这在某种程度上是一个特例,真正适用于非常大和复杂的网站。
  • 如果您的用户相对较少,但单个用户的流量可以淹没一个服务器(例如,使用SSL、AJAX、动态生成的图像、动态压缩等复杂页面),则粘性可能会损害终端用户的响应时间,因为您没有将单个用户的负载均匀地分散在各个服务器上。 如果您有很多并发用户,则这不是问题,因为所有服务器都会被淹没!

但是如果您必须使用服务器本地会话状态,则粘性会话肯定是正确的选择。 即使您不使用服务器本地会话状态,粘性也具有缓存利用方面的优点(请参见上文)。 您的负载均衡器应该能够查看HTTP cookie(而不仅仅是IP地址)以确定粘性,因为IP地址可能在单个会话期间更改(例如,在有线和无线网络之间对笔记本电脑进行停靠)。

更好的方式是,在 Web 服务器上根本不使用会话状态!如果会话状态很难以丢失(例如购物车),请将其存储在中央数据库中,并定期清除旧会话。如果会话状态不重要(例如用户名/头像 URL),则将其放入 cookie 中--只需确保不要将过多数据塞入 cookie 中。
默认情况下,现代版本的 Rails 将会话变量存储在 cookie 中,原因如上所述。其他 Web 框架可能有“存储在 cookie”和/或“存储在数据库”选项。

1
好的答案!请问您能否再详细解释一下“您的负载均衡器应该能够查看HTTP cookie(不仅是IP地址)”的含义吗?您指的是什么?负载均衡器如何知道是否是同一用户? - JaskeyLam
Web应用程序通常会向客户端发送Cookie,以便当该客户端返回发起另一个HTTP请求时,服务器可以识别相同的用户或会话。一些负载均衡器可以查看HTTP cookie头以标识用户,并可以使用该cookie值(而非IP地址)确定应该接收该请求的服务器。 - Justin Grant
如果我将状态存储在db/memcache中,那么我可以认为应用程序是无状态的吗?但有些人会说,要使应用程序无状态,我们必须在客户端中维护状态。 - JaskeyLam
@jaskey - 这是一个很好的问题,我建议你为此开一个新的问题。 - Justin Grant
是的,请在这里回答:http://stackoverflow.com/questions/27016314/does-ststate-transfer-in-rest-mean-that-state-must-be-held-by-client - JaskeyLam
我想指出将可识别的数据(例如用户名)存储到cookie中的建议虽然在技术上可行,但在某些国家可能是不合法的。根据我的了解,特别是欧盟对可以存储在cookie中的内容施加了限制。 - Oliver Hausler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接