Flask/Python/WSGI中类似PHP Apache共享内存存储的好方法是什么?

10 投票
2 回答
1690 浏览
提问于 2025-04-16 11:37

我在PHP上做了几年大型游戏服务器的开发。负载均衡器的作用是把进来的请求分配给集群中的某一台服务器。为了提高性能,我们开始在集群中的每个实例上缓存所有静态数据(基本上就是游戏世界的模型对象),直接存储在Apache的共享内存中,使用了apc_storeapc_fetch这两个函数。

由于一些原因,我们现在开始用Python开发一个类似的游戏框架,使用Flask这个微框架。乍一看,这个实例的内存存储似乎没有直接对应的Python/Flask的解决方案。目前,我们考虑在每个实例上本地运行Memcached(这样可以避免从我们的主Memcached集群中传输相对较大的模型对象)。

那我们可以用什么来替代呢?

2 个回答

5

我觉得在这种情况下,你可能会想要考虑使用一个集中式的键值存储系统,而不是在每台服务器上都用独立的存储系统。因为如果你的负载均衡器没有总是把同样的用户引导到同一台服务器上,就可能出现用户的请求每次都被分配到不同的服务器上,这样每个节点就得去获取游戏状态,而不是从共享的缓存中直接访问。

另外,每台系统上本地的键值存储可能会增加内存负担,这样可能会拖慢你的游戏服务器执行其他功能的速度。不过这主要还是看你缓存的数据量有多大。

一般来说,最好的办法是先做一些基准测试,看看使用memcached集群和本地存储时,性能表现如何,以及你存储的对象类型。

根据你对键值存储的其他需求,你可能还想考虑一些替代方案,比如mongodb(http://www.mongodb.org)。

2

[五个月后]

我们的游戏框架完成了。

最后,我们决定把静态数据存储在每个网络服务器上完全初始化的sqlalchemy模型实例中。当一个新的游戏服务器启动时,这些实例会通过访问一个共享的MySQL数据库来构建。

由于我们的模型工厂使用了实例池,所以每个服务器在每次部署时只需要构建一次模型实例——这点很重要,因为在我们的规模下,MySQL在持续负载下会崩溃。我们通过将物品定义尽量靠近应用代码来实现了不通过网络传输这些数据的目标:直接在应用代码中。

我现在意识到我最初的问题有些天真,因为与LAMP架构不同,Flask服务器在请求之间会持续运行,服务器的内存本身就是“共享内存”——不需要像APC这样的东西来实现。实际上,任何在请求处理范围之外的东西,以及Flask的线程安全本地存储,都可以被视为“共享内存”。

撰写回答