V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gantleman
V2EX  ›  推广

使用 redis 实现 5 万人同服的“相位技术”

  •  
  •   gantleman · 2020-08-03 16:29:03 +08:00 · 4862 次点击
    这是一个创建于 1565 天前的主题,其中的信息可能已经有所发展或是发生改变。

    完整文章链接 zhuanlan.zhihu.com/p/166347236

    魔兽世界和 EVE 服务器能够同时支持 5 万人在线的技术肯定让很多人流口水吧。今天我用 redis 来模拟实现“相位技术”。所谓“相位技术”就是将服务器分为多个并行的空间。是对传统分割成多个地图场景技术的升级。这个技术通过创建多个并行时空的概念。将多个时空分配到不同的服务器。在客户端请求数据时再将多个时空的数据整合在一起。这样理论上就可以将地图场景再次无限分割。所以理论上使用“相位技术”的服务器承载人数可以达到非常恐怖的 5 万人。

    传统的一个地图一个服务器的做法。如果玩家过多就会大量消耗服务器 CPU 资源。直到 CPU 资源耗尽达到服务器人数上限。因为所有逻辑运算都拥挤在一个线程。这种多个功能间资源抢夺的现象会非常明显。而其中玩家移动是最消耗资源的功能。在每一帧中移动的数据都需要同时广播给其他的玩家。这样其他的玩家才能看到这个玩家在移动。

    如果屏幕内有1千个玩家,哪么就需要广播1千次。相当于每次移动的数据都放大了1千倍。而移动同步的频率通常在每秒1次到60次。同步频率越高在客户端表现越细腻。如果每秒同步频率是1次,哪么每个用户每秒钟就要发送一次千人的广播。1千个用户在服务器一共要发送1百万次的同步信息。也就是说移动同步信息如果不加限制,哪么将会成指数级别的增加。

    关注 surparallel.org 获得更多有趣的并行知识。

    20 条回复    2020-08-04 20:38:53 +08:00
    smallpython
        1
    smallpython  
       2020-08-03 18:12:28 +08:00
    虽然说得很厉害, 但是我玩魔兽有时候捡个任务物品 10 秒钟
    gantleman
        2
    gantleman  
    OP
       2020-08-03 18:23:44 +08:00
    @smallpython 魔兽的服务器是商业秘密,不清楚具体实现方式。如果请我帮忙诊断,报销来回车费,我可以考虑帮他们看看。嘿嘿
    huntcool001
        3
    huntcool001  
       2020-08-04 00:12:53 +08:00
    "1 万人以每秒 60 帧的速度向 redis 提交数据。每秒钟将会达到 60 万次提交"

    一个玩家的位置,真的有必要一秒更新 60 次? 移动的时候客户端再更新不行吗
    gantleman
        4
    gantleman  
    OP
       2020-08-04 05:37:58 +08:00
    @huntcool001 也可以每秒提交一次,但这样角色的动作就会看起来不自然。
    opengps
        5
    opengps  
       2020-08-04 05:49:42 +08:00
    这个模拟有个非常大的差异:单机应用跟集群应用的区别
    opengps
        6
    opengps  
       2020-08-04 05:52:09 +08:00   ❤️ 1
    服务器一旦集群应用后,本身也会损失一定的性能,所以文中那种总数除以单机的承载总量的做法有点理想化。实际引用中需要额外追加一定量的机器
    ArchiTech
        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/

    这篇文章也讲了延时如何补偿。
    gantleman
        8
    gantleman  
    OP
       2020-08-04 09:52:00 +08:00   ❤️ 1
    @ArchiTech 有路径的情况下会好些,因为路径算法本身也是吃 cpu 。相位技术的本质就是对 cpu 的分配。是用 io 换效率的方法。空间定位是所有模拟环境的的基础,包括现实中车船飞机的调度,人员定位协作等。并不局限于游戏。
    mattx
        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 之类的。
    des
        10
    des  
       2020-08-04 10:06:12 +08:00
    并不能“无限分割”,分割太细就会有很多进出边界的事件发生
    gantleman
        11
    gantleman  
    OP
       2020-08-04 10:23:23 +08:00
    @mattx 没做过太多游戏,只完整上线过四个游戏。
    1,估值当然要按最高标准来做的。毕竟游戏质量的选择不是技术决定的。60 也好 30 也好是老板决定的。
    2,游戏信息放在哪里要根据性能做选择。因为没有 redis 之前我们也自己开发缓存服务器。如果能保证自己的开发的缓存服务器好于 redis 也可以不用 redis 。在这里 redis 作为通用工具也是事实的标准,作为技术贴容易交流。并且这个技术并不局限于游戏,车辆,船舶,飞机的调度都可能使用。
    3,redis 在这里作为关键节点承担了计算和存储的压力,理论上一个用户可以一个服务,压力比关键节点小很多。
    4,wow 的相位技术公布很久了,可能你对这方面关注不多吧。
    5,这篇文章讨论的是同服也是同场景的问题,因为同服就意味着玩家可能会集中到 1 个地图场景。所以并没有在文章强调同服,同地图还是同场景。也没有限定只能同服不能同地图和同场景。

    以前玩过魔兽模拟器,因为当时模拟器是单线程的性能非常差。自己改写过一个多线程版本可以跑 2 千人同场景。官方后来改名大芒果,再后来的 trinitycore 就没接触了。
    gantleman
        12
    gantleman  
    OP
       2020-08-04 10:27:11 +08:00
    @des 是的,因为相当于用 io 换 cpu 的并行,这里没有计算网络带宽和硬盘极限,每个服务器的封包大小不太好估算。最后的瓶颈可能会出现在内网或外网带宽上。
    Acoolda
        13
    Acoolda  
       2020-08-04 14:06:14 +08:00 via Android
    有必要广播给一千个人吗?只需要广播给在同一个地方的用户就行了吧,其他用户根本不关心
    gantleman
        14
    gantleman  
    OP
       2020-08-04 14:14:11 +08:00
    @Acoolda 是的所以要加限制,使用九宫格,81 宫格,六变格的技术进行过滤。
    gantleman
        15
    gantleman  
    OP
       2020-08-04 18:38:08 +08:00
    @livid 真的要好好夸夸你,谷歌的中文优化做的真棒。第二天就排到了云风 blog 的后面。相位技术 14 年出来的,是魔兽游戏服务器的核心技术。到今天国内都不能出仿制品。无数的大牛在这个技术上折戟沉沙。我就这么免费给大家拿出来了,给各位也卖个热闹好看。各位看过的爷,有钱的捧个钱场,没钱的捧个人场。谢谢您了。
    tcfenix
        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 上面有很多视频,非常建议学习
    sunny352787
        17
    sunny352787  
       2020-08-04 19:22:49 +08:00
    看你的做法我倒是想到了另一种方式,既然已经分了多个游戏服,那么游戏服按类似帧同步的方式每个时间片统一向 redis 提交一次全服的位置同步信息呢?这样对 redis 的压力就没那么大了,只是一次同步的数据会多一点,这个应该也可以优化,毕竟不可能服务器上所有单位都在移动
    sunny352787
        18
    sunny352787  
       2020-08-04 19:25:26 +08:00
    @sunny352787 当然,这只是针对使用 redis 进行位置同步的方式的优化想法,实际上我这边在做玩家同步的时候是有一个单独的位置服务器的,这部分是参照了云风之前的一篇文章
    mattx
        19
    mattx  
       2020-08-04 19:38:07 +08:00
    @gantleman 先说魔兽世界相位技术吧,是巫妖王以后拿来加强融入感的,实际上就是开了一个新的场景,只是因为客户端资源不需要加载(已经在内存)不需要 loading,不是什么高深的技术。
    魔兽世界后期比较关注的技术应该是出现很多地图的跨服玩家,而且主城可以出现很多不同服务器的玩家,应该是把主城也当做位面世界来做了
    你是来蹭流量的吧?“redis 在这里作为关键节点承担了计算和存储的压力,理论上一个用户可以一个服务,压力比关键节点小很多” 这是什么鬼?
    gantleman
        20
    gantleman  
    OP
       2020-08-04 20:38:53 +08:00
    @tcfenix
    @sunny352787
    谢谢,谢谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2647 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 82ms · UTC 15:34 · PVG 23:34 · LAX 07:34 · JFK 10:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.