BRP*_*ock 7 database-design architecture
我正在使用一些相当深奥的元素(理论上很好但在实践中很少使用)重写 MMORPG 服务器引擎,并且有点怀疑。其中的一些元素是“可靠的”——但做“又一个 MMO 服务器”的目的是在生产级代码中测试其中的一些概念。
然而,我希望这里的某个人可能对 PostgreSQL 分区模型有一些实践经验,并且能够“借”一些专业知识给这个项目。
下面有一个 TL;DR 版本。
entities
表中存储一列,指示它属于哪个“服务器位置池”,或者是提供该映射的单独表,或具有该效果的某些内容。COMMIT
,我们就不会在崩溃时非常关心我们是否获得任何特定交易的“之前”或“之后”图像。我想我在口头上混淆了这个概念:换句话说,为了崩溃恢复的目的,我们并不十分担心整个交易是否丢失,只要我们丢失整个交易。丢失集群主机(例如机器着火)的可能性在规划器级别处理,如果我们检测到心跳丢失,则可以相当快地重新分配该主机的责任区域。我们有一堆带有 PostgreSQL 的 Linux boxen。我们有一些函数可以接收数据的子集,这些数据可以使用SELECT
或VIEW
在这些主机上运行来定义,并且写出几乎与读取一样多的更改。
这是它变得脆弱的地方:
组件直接映射到关系表和行。例如,假设最终有一个 Position 组件。实体 ID 将是表上的主键,对于一致性检查,也是entities
仅包含 PKSERIAL8
字段的表的外键。位置表然后有,比方说,x NUMERIC, y NUMERIC, z NUMERIC
列。
然后,想象一个需要位置、质量和惯性组件的重力系统,以及另一个使用这些组件和物理体积组件的碰撞系统。
在完美(即性能无关紧要)的世界中,我们知道系统将使用SELECT
具有某些标准的 SQL 来处理哪些实体。也许 PhysicalVolume 可能有一个边界框,可以快速剔除那些不占用物理体积,或者明显远离可能与之碰撞的任何其他实体的实体(一些不太花哨JOIN
的 Position 和 PhysicalVolume )。因此,我们有一个枚举系统定义:它将需要从哪些组件中获取数据,以及一个SELECT
查询以获取作为时间点、不可变记录结构的数据。这些记录被一一输入系统的run
功能,并执行任何必要的更改。如果系统写入它不读取的组件,我们会提前声明,以保留数据局部性。
当然,问题是SELECT
来自远程磁盘的SQL不是人们想要在主模拟循环的每个“帧”中执行的那种事情。其中一些系统的运行频率可能超过 10Hz。
现在,我知道,“在此之前没有优化”,但这似乎是一个“注定要失败”的模型,除非有一种方法可以实时使用该理论模型。
作为大型安装的进一步必要选项,规划器系统可能还希望将实体“池”(最有可能是那些“物理上位于”游戏世界某个区域的实体)迁移到单个主机上,以平衡加载并保持必须命中任何通用后端数据库的“缓存未命中”相当低。
给定的
SERIAL8
REFERENCE
s的非连续选择)……有没有合理的方法来创建
如果这是一个不合理的设计,我的后备概念是通过尝试将视图预加载到 RAM 中的临时表或其他东西来基本上模拟相同的效果,尽管我没有花太多时间考虑这可能会表现得有多差。
任何可以为基础理论模型服务的合理替代方案都值得赞赏。
这是一个很长的问题。
首先,我当前的项目(我是数据库人员,有 MMO 引擎专家来处理)是一种基于现成引擎的 MMORPG 形式。卷就像《Eve Online》或《坦克世界》卷。
现在给出一个正交的简短答案:
当然还有更多,但我建议你过度思考这个问题并搬起石头砸自己的脚。我只是将与投资银行业务相同的技术应用到 MMO 中,因为在我看来,大多数高容量系统应该收敛到类似的架构