首先,我们要知道什么是序列化和反序列化?
- **序列化(Serialization)**是指将内存中的数据结构(如 C++/Java 对象、结构体)转换为字节序列,以便传输或存储(如发给 Redis)。
- **反序列化(Deserialization)**则是将这些字节序列重新转换成可用的内存对象。
- 常见的序列化格式包括:
- JSON:可读性强,体积大,性能最差,解析慢。
- Protobuf:Google 推出的二进制协议,压缩率高,性能较好。
- MsgPack、FlatBuffers、Cap'n Proto:新兴的更快、更紧凑的二进制协议。
其次,我们需要了解为什么序列化在游戏场景中代价高昂?
- 高频写入导致 CPU 和内存占用激增。
在实时游戏中,玩家状态变化非常频繁,常见更新项包括:
- 位置坐标:每 50~100 毫秒更新一次。
- 技能 CD、状态变化:战斗中可能毫秒级更新。
- 生命值、Buff、装备状态:持续变动。
这些状态如果每次都需要打包成 JSON 或 protobuf, 哪怕是毫秒级变化都会造成大量 CPU 时间用于字符串构造、对象转换、内存复制等工作。

我们可以看一下这个例子:
{
"playerId": 1234,
"hp": 57,
"position": [12.3, 45.6, 78.9],
"status": "fighting"
}
用 JSON 表达虽然直观,但是还是会出现以下问题:
- 需要构造字符串。
- 需要进行类型编码、转义。
- Redis 存储的是字符串,还要走 UTF-8 编码。
- 消耗 CPU 和内存带宽。
游戏场景中序列化代价高昂的原因就在此。
- 内存结构转换带来延迟问题。
每次访问 Redis 的数据时,还要把字符串(或字节流)反序列化成对象:
- JSON → 解析为字符串、数字、数组 → 映射到对象字段。
- Protobuf → 根据 Schema 反解析为结构体。
- 需要额外的内存分配、对象构造、字段校验等操作。
这一过程带来的延迟、GC 压力(特别是 Java)和内存碎片在高频场景下更为突出。
实际上,在大并发下,这种重复操作对性能影响非常大。