完整文章链接 zhuanlan.zhihu.com/p/166347236
魔兽世界和 EVE 服务器能够同时支持 5 万人在线的技术肯定让很多人流口水吧。今天我用 redis 来模拟实现“相位技术”。所谓“相位技术”就是将服务器分为多个并行的空间。是对传统分割成多个地图场景技术的升级。这个技术通过创建多个并行时空的概念。将多个时空分配到不同的服务器。在客户端请求数据时再将多个时空的数据整合在一起。这样理论上就可以将地图场景再次无限分割。所以理论上使用“相位技术”的服务器承载人数可以达到非常恐怖的 5 万人。
传统的一个地图一个服务器的做法。如果玩家过多就会大量消耗服务器 CPU 资源。直到 CPU 资源耗尽达到服务器人数上限。因为所有逻辑运算都拥挤在一个线程。这种多个功能间资源抢夺的现象会非常明显。而其中玩家移动是最消耗资源的功能。在每一帧中移动的数据都需要同时广播给其他的玩家。这样其他的玩家才能看到这个玩家在移动。
如果屏幕内有1千个玩家,哪么就需要广播1千次。相当于每次移动的数据都放大了1千倍。而移动同步的频率通常在每秒1次到60次。同步频率越高在客户端表现越细腻。如果每秒同步频率是1次,哪么每个用户每秒钟就要发送一次千人的广播。1千个用户在服务器一共要发送1百万次的同步信息。也就是说移动同步信息如果不加限制,哪么将会成指数级别的增加。
关注 surparallel.org 获得更多有趣的并行知识。
1
smallpython 2020-08-03 18:12:28 +08:00
虽然说得很厉害, 但是我玩魔兽有时候捡个任务物品 10 秒钟
|
2
gantleman OP @smallpython 魔兽的服务器是商业秘密,不清楚具体实现方式。如果请我帮忙诊断,报销来回车费,我可以考虑帮他们看看。嘿嘿
|
3
huntcool001 2020-08-04 00:12:53 +08:00
"1 万人以每秒 60 帧的速度向 redis 提交数据。每秒钟将会达到 60 万次提交"
一个玩家的位置,真的有必要一秒更新 60 次? 移动的时候客户端再更新不行吗 |
4
gantleman OP @huntcool001 也可以每秒提交一次,但这样角色的动作就会看起来不自然。
|
5
opengps 2020-08-04 05:49:42 +08:00
这个模拟有个非常大的差异:单机应用跟集群应用的区别
|
6
opengps 2020-08-04 05:52:09 +08:00 1
服务器一旦集群应用后,本身也会损失一定的性能,所以文中那种总数除以单机的承载总量的做法有点理想化。实际引用中需要额外追加一定量的机器
|
7
ArchiTech 2020-08-04 06:43:56 +08:00 2
很多游戏的移动不需要每帧或者每秒和服务器沟通,一个常见的做法是当客户端的用户点击一个新位置,比如要从( 0,0 )移动到( 20,30 )这个位置,客户端用 A*算法可以算出移动路径然后直接开始移动,服务器端也有相同的 A*算法会得出完全一致的结果,所以服务器端只要做两件事:一是确认一下这个路径是否可行(以免客户端被恶意篡改了,比如玩家作弊穿墙);二是把目的地的坐标广播一下就好了,中间的路径就不需要广播了。
https://www.dynetisgames.com/2017/03/19/client-updates-phaser-quest/ 这篇文章也讲了延时如何补偿。 |
8
gantleman OP @ArchiTech 有路径的情况下会好些,因为路径算法本身也是吃 cpu 。相位技术的本质就是对 cpu 的分配。是用 io 换效率的方法。空间定位是所有模拟环境的的基础,包括现实中车船飞机的调度,人员定位协作等。并不局限于游戏。
|
9
mattx 2020-08-04 09:57:04 +08:00 1
楼主是没做过游戏么,还是来钓鱼的,你最后那个估算简直搞笑?
1 一般游戏服务器不要 60 帧吧?普通 mmo 10 帧,fps 30 估计就可以了 2 这种位置信息为什么一定要放 redis 里面,应该是作为玩家信息一部分放内存就好了 3 为啥估算服务器只有 redis,不要考虑 cpu 等负载情况 4 魔兽世界以前版本主要是支持 几个无缝大世界,一个世界里面可以承载很多人,后面版本又做了 大世界的负载均衡吧 5 xx 同服 不是件很难的事情,因为可能包含很多场景,主要还是一个场景最多可以有多少人在一起,并且地图无缝 还是去看实际的工程吧,trinitycore 之类的。 |
10
des 2020-08-04 10:06:12 +08:00
并不能“无限分割”,分割太细就会有很多进出边界的事件发生
|
11
gantleman OP @mattx 没做过太多游戏,只完整上线过四个游戏。
1,估值当然要按最高标准来做的。毕竟游戏质量的选择不是技术决定的。60 也好 30 也好是老板决定的。 2,游戏信息放在哪里要根据性能做选择。因为没有 redis 之前我们也自己开发缓存服务器。如果能保证自己的开发的缓存服务器好于 redis 也可以不用 redis 。在这里 redis 作为通用工具也是事实的标准,作为技术贴容易交流。并且这个技术并不局限于游戏,车辆,船舶,飞机的调度都可能使用。 3,redis 在这里作为关键节点承担了计算和存储的压力,理论上一个用户可以一个服务,压力比关键节点小很多。 4,wow 的相位技术公布很久了,可能你对这方面关注不多吧。 5,这篇文章讨论的是同服也是同场景的问题,因为同服就意味着玩家可能会集中到 1 个地图场景。所以并没有在文章强调同服,同地图还是同场景。也没有限定只能同服不能同地图和同场景。 以前玩过魔兽模拟器,因为当时模拟器是单线程的性能非常差。自己改写过一个多线程版本可以跑 2 千人同场景。官方后来改名大芒果,再后来的 trinitycore 就没接触了。 |
12
gantleman OP @des 是的,因为相当于用 io 换 cpu 的并行,这里没有计算网络带宽和硬盘极限,每个服务器的封包大小不太好估算。最后的瓶颈可能会出现在内网或外网带宽上。
|
13
Acoolda 2020-08-04 14:06:14 +08:00 via Android
有必要广播给一千个人吗?只需要广播给在同一个地方的用户就行了吧,其他用户根本不关心
|
15
gantleman OP @livid 真的要好好夸夸你,谷歌的中文优化做的真棒。第二天就排到了云风 blog 的后面。相位技术 14 年出来的,是魔兽游戏服务器的核心技术。到今天国内都不能出仿制品。无数的大牛在这个技术上折戟沉沙。我就这么免费给大家拿出来了,给各位也卖个热闹好看。各位看过的爷,有钱的捧个钱场,没钱的捧个人场。谢谢您了。
|
16
tcfenix 2020-08-04 19:11:30 +08:00
老哥你这是真的没开发过游戏了, 我也有几年没摸游戏项目了,如果现在整体趋势有变化请见谅
1 游戏服务器有很多都是内存数据主要解释,性能又好,又没有网络开销,然后定时落库,所以你应该听说过回档这个事情吧 2 接触过的游戏项目,redis 主要还是用来放一下临时数据,比如登录态的维护,道理很简单, 游戏服务器就是会追求快,而且用户对游戏上操作响应的忍耐空间是非常小的 3 你可以参考一下游戏公司招服务端的标准,基本上还是 80% 90%的 c++吧?然后少量的 golang 以及微量的 java c++会被怎么用?尤其是祖传的 c++代码... 4 操作帧跟实际上用户画面帧是完全两回事,举个例子用户可以任何时候向服务器发送操作指令,但是服务器就是可以以每秒 15 帧 或者更少去响应,然后在客户端处理成 30 60 帧,这边 GDC 上面有很多视频,非常建议学习 |
17
sunny352787 2020-08-04 19:22:49 +08:00
看你的做法我倒是想到了另一种方式,既然已经分了多个游戏服,那么游戏服按类似帧同步的方式每个时间片统一向 redis 提交一次全服的位置同步信息呢?这样对 redis 的压力就没那么大了,只是一次同步的数据会多一点,这个应该也可以优化,毕竟不可能服务器上所有单位都在移动
|
18
sunny352787 2020-08-04 19:25:26 +08:00
@sunny352787 当然,这只是针对使用 redis 进行位置同步的方式的优化想法,实际上我这边在做玩家同步的时候是有一个单独的位置服务器的,这部分是参照了云风之前的一篇文章
|
19
mattx 2020-08-04 19:38:07 +08:00
@gantleman 先说魔兽世界相位技术吧,是巫妖王以后拿来加强融入感的,实际上就是开了一个新的场景,只是因为客户端资源不需要加载(已经在内存)不需要 loading,不是什么高深的技术。
魔兽世界后期比较关注的技术应该是出现很多地图的跨服玩家,而且主城可以出现很多不同服务器的玩家,应该是把主城也当做位面世界来做了 你是来蹭流量的吧?“redis 在这里作为关键节点承担了计算和存储的压力,理论上一个用户可以一个服务,压力比关键节点小很多” 这是什么鬼? |
20
gantleman OP |