概念
进程内多 Lua VM 之间的数据共享机制
解决问题
skynet 每个服务是独立 Lua VM,如果 100 个服务各 load 一份 500KB 的配置表,就是 50MB 浪费。
演进过程
sharedata(老方案,云风早期设计)
实现思路
-
由一个 sharedatad服务把 table 序列化成 C 层的 lightuserdata 存起来
-
其他 VM 通过 sharedata.query(name)拿到这个指针
-
每个 VM 用 metatable 代理 从 lightuserdata 里查字段,并建 proxy 缓存已查过的 key
配置表 → C 层 lightuserdata ←→ 各 VM 通过 metatable+proxy 访问
优点:惰性展开,初次 query 快,热更后旧数据易回收
缺点:每次访问要走 metatable → C → 回 Lua,proxy 随服务数膨胀,访问慢、内存占用随服务数涨
sharetable(2019 年后新方案)
直接改了 Lua VM 的实现,允许多个 VM 共享只读的原生 Lua table,且不参与 GC
优点:等价于访问本地 Lua table,无 metatable、无 proxy、不进 GC,实测比 sharedata 快 5~25 倍
缺点:热更麻烦------旧 table 要等所有引用服务退出才能释放;C 层内存占用更大
选型口诀
💡 不常更新的大配置用 sharetable,常更新的小配置用 sharedata
-
数值表、道具表、技能表 → sharetable(一次加载反复读)
-
运营活动配置、开关类 → sharedata(热更友好)