Replication Graph:大连接数下的同步选型
September 5, 2024About 3 min
Replication Graph:大连接数下的同步选型
Replication Graph 是 UE 的一套可选同步框架,常和属性级脏标记配合使用,目标是支撑几十个客户端连接下的实时同步,并把服务器 CPU 压下来。下面记录为什么要用它、它和原生框架的差异,以及一条完整的同步链路。
为什么要用 Replication Graph
性能与可扩展性
原生同步框架要求每个同步 Actor 在每一帧、对每个连接的客户端单独做相关性检查并复制。游戏里同步 Actor 和连接一多,这就成了服务器(DS / Host)的主要 CPU 瓶颈:
原生框架下,服务器的工作量 ≈ 客户端数 × 同步 Actor 数。每次同步,服务器都要为每个连接独立算一遍复制逻辑。
Replication Graph 的做法是把 Actor 组织进由节点(Node)管理的、跨连接共享且持久的复制列表,消除「每个 Actor 对每个连接」的重复相关性检查,从而显著降低服务器 CPU,同时不牺牲客户端更新频率。
高效 Actor 分组
它按相关性标准或游戏特定规则,把 Actor 归类到不同节点中,服务器就能高效地为每个连接拼出复制列表。
跨帧持久数据
与原生模型不同,Replication Graph 用跨帧持久的数据结构在连接间共享复制列表,省掉重复计算。
原生框架 vs. Replication Graph
| 特性 | UE4 传统同步框架 | Replication Graph |
|---|---|---|
| Actor 相关性检查 | 每个 Actor 为每个连接单独跑相关性检查 | Actor 路由到节点,由节点集体、持久地管理相关性和复制列表 |
| CPU 开销 | Actor/玩家多时因重复检查而高 | 在节点里批处理,避免每连接重复检查,开销低 |
| 数据持久性 | 跨帧无持久数据,复制决策即时进行 | 跨帧缓存持久复制列表与节点状态,并在连接间共享 |
| 可定制性 | 只能用有限的 Actor 虚函数/属性(如 IsNetRelevantFor()),Actor 多时难配 | 支持自定义节点类型和复杂分组逻辑 |
| 更新频率 | 默认所有 Actor 统一频率,难扩展 | 可扩展内置的 FrequencyBuckets、DynamicSpatialFrequency 节点,做降频或按优先级更新 |
| 适用场景 | 中小玩家数 / Actor 数 | 大量玩家与同步 Actor 的大型游戏 |
| 实现难度 | 简单,内置于 Actor,无需额外设置 | 需启用并配置,且要用 C++ 写/定制节点 |
| 内置节点 | 无,依赖 Actor 内置逻辑 | 提供 GridSpatialization2D、AlwaysRelevant、FrequencyBuckets 等 |
| 蓝图支持 | 完全兼容 | 框架与同步节点主要面向 C++,不支持蓝图建自定义节点;上层 gameplay 里同步变量的声明与用法和传统方式一致,可平滑切换 |
| 不支持 | 全场景支持 | 不支持分屏 |
一条同步链路示例
以 Epic 官方示例工程 Lyra 为例,下面的时序图展示 ALyraPlayerState::PawnData 被修改、收集、同步到客户端的全过程。