首页 > 解决方案 > 持有TCP连接的大规模websocket系统设计

问题描述

假设您有一个非常大的系统(在任何给定时刻都有数亿用户活跃),并且您需要主动将消息/通知从服务器推送到其客户端端点。有几千台机器专门用于与活动用户保持 TCP 连接是否很常见?

如果是这样,我想在这些机器前面有一个“查找服务”,它决定哪台机器user_id应该连接到哪台机器(例如:使用映射user_id到 a的哈希函数server_id),对吧?

我的问题是,像 Facebook/Twitter 的通知层这样的大型系统是这样构建的吗?通过使用大量专用于保持 TCP 连接的机器,并在前面有一个映射user_id到的查找服务server_id?如果是这样,他们如何处理服务器故障的情况?当您需要添加更多服务器时会发生什么,因为服务器编号发生了变化,我们不需要重新散列所有用户吗?

谢谢!

标签: linuxsocketswebsockettcpredis

解决方案


对此有许多不同的方法,但它们都归结为“分而治之”的技术。

这些技术将网络划分为“区域”,其中每个“区域”负责数据/网络的一个子集。

这些“区域”可以进一步细分为更小的“区域”,以便随着需求的变化进一步扩展。

这个“区域”树上的每个叶节点都可能拥有一整套机器(负载均衡器、缓存(即内存缓存)、数据库或 API 端点),具体取决于应用程序的要求。

AWS 受欢迎的部分原因是因为它提供了很多工具,使可扩展性更易于管理。

这取决于您的用例,但在地理上划分区域是有意义的(考虑 CDN 的工作方式)。

例如,可以将应用程序划分为每个大陆的区域,即亚洲、欧洲、美洲、非洲、大洋洲等。

这些区域中的每一个都可能按国家/州进一步划分。

由于流量大(第三层路由/重定向),某些州可能需要多个(子)区域。

这些子区域中的每一个都将拥有自己的(子)域、负载平衡器和许多管理该区域的连接和数据的机器。

这个地理划分的例子可以(理论上)通过地理定位 DNS 响应来最小化网络流量和延迟。这将允许(例如)纽约市的流量保持在纽约市,除非需要“跨境”通信。

“跨境”通信有时会延迟和聚合,以最大限度地减少流量和数据库事务(对于实时应用程序您不会这样做)。

显然,这有许多并发症。例如:如果美国用户在英国旅行怎么办?我们是将他的数据移动到不同的区域,还是将连接路由到美国服务器,并具有所有延迟?...

然而,最终,别无选择,只能“分而治之”。即使是数据库也无法在一台机器上保存所有数据,必须将数据划分为不同数据库上的子集。

此外,一些数据(如区域分配)很难划分。有些数据坚持“全局”(例如,我们如何知道用户属于哪个区域?)......这通常是使用哈希值的地方。

使用哈希值计算分布时,以后重新分布数据变得更加困难。这仍然是可能的,尤其是在使用对数区域划分时,但这只是众多可能解决方案中的一种方法。


推荐阅读